MyBatis-映射文件

参数传递方式

单个参数

可以接受基本类型,对象类型,集合类型的值。

public Employee getEmpById(Integer id);

多个参数

会被MyBatis重新包装成一个Map传入。Map的key是param1,param2,0,1…,值就是参数的值。

public Employee getEmpByIdAndLastName(Integer id,String lastName);

命名参数

参数使用@Param起一个名字,MyBatis就会将这些参数封装进map中,key指定的名字。

public Employee getEmpByIdAndLastName(@Param("id")Integer id,@Param("lastName")String lastName);

POJO

public boolean updateEmp(Employee employee);

Map

public Employee getEmpByMap(Map<String, Object> map);

映射文件中参数设置

#{id,javaType=int,jdbcType=INTEGER}

javaType指定java类型 jdbcType指定数据库类型 numericScale小数点后保留位数。

mode 属性允许指定IN,OUT 或INOUT 参数。如果参数为OUT 或INOUT,参数对象属性的真实值将会被改变,就像在获取输出参数时所期望的那样。

 

参数位置支持的属性

javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、expression

Mybatis 中$与#的区别

https://www.cnblogs.com/hellokitty1/p/6007801.html

Insert、update、delete属性

id:命名空间唯一标志符,作为Mybatis查找sql

parameterType:可选,限定传入参数的类名或者别名。未指定情况下,Mybatis可以通过TypeHandler推断具体传入语句的参数类型,默认值unset。

flushCache:是否清空本地缓存和二级缓存,默认值true。

timeout:等待数据库返回请求结果的秒数。默认unset

statementType:STATEMENT、PREPARED或CALLABLE的一个,分别对应Statement、PreparedStatement或CallableStatement,默认PREPARED

useGeneratedKeys:令Mybatis使用JDBC的getGeneratedKeys方法来获取由数据库内部生成的主键,默认false。

keyProperty:Mybatis会通过getGeneratedKeys的返回值或者通过insert语句的selectKey子元素设置他的键值,默认unset

keyColumn:(仅对insert和update有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(如PostgreSQL)是必须的,当主键不是表中的第一列的时候需要设置。多个生成的列,可以用逗号分隔属性名层列表。

databaseId:如果配置databaseIdProvider,Mybatis会加载所有的不带databaseId或匹配当前databaseId的语句

Insert

Mysql:

mysql支持自增主键,自增主键值的获取,mybatis也是利用statement.getGenreatedKeys();

useGeneratedKeys="true";使用自增主键获取主键值策略,keyProperty;指定对应的主键属性。databaseId指定数据库是mysql。

<insert id="addEmp" parameterType="com.mybatis.bean.Employee"

useGeneratedKeys="true" keyProperty="id" databaseId="mysql">

insert into tbl_employee(last_name,email,gender)

values(#{lastName},#{email},#{gender})

</insert>

Oracle:

Oracle不支持自增,每次插入的数据的主键是从序列中拿到的值;

<insert id="addEmp" databaseId="oracle">

<selectKey keyProperty="id" order="BEFORE" resultType="Integer">

<!-- 编写查询主键的sql语句 -->

select EMPLOYEES_SEQ.nextval from dual

</selectKey>



<!-- 插入时的主键是从序列中拿到的 -->

<!-- BEFORE:-->

insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)

values(#{id},#{lastName},#{email<!-- ,jdbcType=NULL -->})

</insert>

语句步骤:

1 查询序列MPLOYEES_SEQ下一个序列值。

2 将序列值赋值给id属性。

3 进行插入操作。

 

selectKey

keyProperty:查出的主键值封装给javaBean的哪个属性

order:BEFORE当前sql在插入sql之前运行

  AFTER当前sql在插入sql之后运行

resultType:查出的数据的返回值类型

statementType:STATEMENT、PREPARED或CALLABLE

 

BEFORE运行顺序:

先运行selectKey查询id的sql;查出id值封装给javaBean的id属性

在运行插入的sql;就可以取出id属性对应的值

AFTER运行顺序:

先运行插入的sql(从序列中取出新值作为id);

再运行selectKey查询id的sql;

 

上面AFTER例子(不建议):

这种方式下,在高并发下,AFTER下获取的currval值不准确。

<insert id="addEmp" databaseId="oracle">

<selectKey keyProperty="id" order="AFTER" resultType="Integer">

<!-- 编写查询主键的sql语句 -->

select EMPLOYEES_SEQ.currval from dual

</selectKey>



<!-- 插入时的主键是从序列中拿到的 -->

<!-- BEFORE:-->

insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)

values(EMPLOYEES_SEQ.nextval,#{lastName},#{email<!-- ,jdbcType=NULL -->})

</insert>

 

select

常用参数

Id:唯一标识符。

parameterType:参数类型。MyBatis可以根据TypeHandler自动推断

resultType:返回值类型(别名或者全类名,如果返回的是集合,定义集合中元素的类型。不能和resultMap同时使用)

resultMap:外部resultMap命名引用,和resultType不能同时使用。

<select id="getDeptById" resultType="com.mybatis.bean.Department">

select id,dept_name departmentName from tbl_dept where id=#{id}

</select>

update

<update id="updateEmp">

update tbl_employee

set last_name=#{lastName},email=#{email},gender=#{gender}

where id=#{id}

</update>

delete

<delete id="deleteEmpById">

delete from tbl_employee where id=#{id}

</delete>

resultMap

constructor:类在实例化时, 用来注入结果到构造方法中.

idArg  ID参数

Arg   注入到构造方法的一个普通结果

id:id结果

result:普通结果

association:一个复杂的类型关联;

collection:复杂类型的集

discriminator:使用结果值来决定使用哪个结果映射

普通对象映射:

public class Employee {

private Integer id;

private String lastName;

private String email;

private String gender;

}
<resultMap type="bean.Employee" id="MySimpleEmp">

<!--指定主键列的封装规则: id定义主键会底层有优化;

column:指定哪一列 property:指定对应的javaBean属性   -->

<id column="id" property="id"/>

<!-- 定义普通列封装规则 -->

<result column="last_name" property="lastName"/>

<!-- 其他不指定的列会自动封装:我们只要写resultMap就把全部的映射规则都写上。 -->

<result column="email" property="email"/>

<result column="gender" property="gender"/>

</resultMap>

级联属性对象映射:

public class Employee {

private Integer id;

private String lastName;

private String email;

private String gender;

private Department dept;

}

普通方式定义:

<resultMap type="bean.Employee" id="MyDifEmp">

<id column="id" property="id"/>

<result column="last_name" property="lastName"/>

<result column="gender" property="gender"/>

<result column="did" property="dept.id"/>

<result column="dept_name" property="dept.departmentName"/>

</resultMap>

association定义关联的单个对象的封装规则:

<resultMap type="bean.Employee" id="MyDifEmp2">

<id column="id" property="id"/>

<result column="last_name" property="lastName"/>

<result column="gender" property="gender"/>

<!--  association可以指定联合的javaBean对象

property="dept":指定哪个属性是联合的对象

javaType:指定这个属性对象的类型-->

<association property="dept" javaType="com.mybatis.bean.Department">

<id column="did" property="id"/>

<result column="dept_name" property="departmentName"/>

</association>

</resultMap>

collection嵌套结果集查询:

public class Department {

private Integer id;

private String departmentName;

private List<Employee> emps;

}
<!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则  -->

<resultMap type="bean.Department" id="MyDept">

<id column="did" property="id"/>

<result column="dept_name" property="departmentName"/>

<!--collection定义关联集合类型的属性的封装规则

ofType:指定集合里面元素的类型-->

<collection property="emps" ofType="bean.Employee">

<!-- 定义这个集合中元素的封装规则 -->

<id column="eid" property="id"/>

<result column="last_name" property="lastName"/>

<result column="email" property="email"/>

<result column="gender" property="gender"/>

</collection>

</resultMap>

<select id="getDeptByIdPlus" resultMap="MyDept">

SELECT d.id did,d.dept_name dept_name,

e.id eid,e.last_name last_name,e.email email,e.gender gender

FROM tbl_dept d

LEFT JOIN tbl_employee e

ON d.id=e.d_id

WHERE d.id=#{id}

</select>

分段查询嵌套结果集

<resultMap type="bean.Department" id="MyDeptStep">

<id column="id" property="id"/>

<id column="dept_name" property="departmentName"/>

<collection property="emps" 

select="dao.EmployeeMapperPlus.getEmpsByDeptId"

column="{deptId=id}" fetchType="lazy"></collection>

</resultMap>

<select id="getDeptByIdStep" resultMap="MyDeptStep">

select id,dept_name from tbl_dept where id=#{id}

</select>

fetchType=eager/lazy 立即加载(eager)或者延迟加载(lazy) 可以覆盖全局setting设置

 

MyBatis-动态SQL

if:判断

<select id="findActiveBlogWithTitleLike"

     resultType="Blog">

  SELECT * FROM BLOG

  WHERE

<if test="title != null">

    title like #{title}

  </if>

<if test="state != null">

    AND state = #{state}

  </if>

</select>

where

在多个if语句的时候可能会出现:

SELECT * FROM BLOG WHERE AND title like ‘someTitle’

SELECT * FROM BLOG WHERE

 

严谨的方法:

<select id="findActiveBlogWithTitleLike"

     resultType="Blog">

  SELECT * FROM BLOG

  <where>

<if test="title != null">

    title like #{title}

  </if>

<if test="state != null">

    AND state = #{state}

  </if></where>

</select>

where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。

choose (when, otherwise)

<select id="findActiveBlogLike" resultType="Blog">

SELECT * FROM BLOG

<where>

<choose>

<when test="title != null">

title like #{title}

</when>

<when test="state != null">

state = #{state}

</when>

<otherwise>

featured = 1

</otherwise>

</choose>

</where>

</select>

trim

字符串的截取规则

prefix:前缀

prefixOverrides:前缀覆盖

suffix:后缀

suffixOverrides:后缀覆盖

<select id="getEmpsByConditionTrim" resultType="bean.Employee">

select * from tbl_employee

<trim prefix="where" suffixOverrides="and">

<if test="id!=null">

id=#{id} and

</if>

<if test="lastName!=null && lastName!=""">

last_name like #{lastName} and

</if>

<if test="email!=null and email.trim()!=""">

email=#{email} and

</if>

<!-- ognl会进行字符串与数字的转换判断 "0"==0 -->

<if test="gender==0 or gender==1">

gender=#{gender}

</if>

</trim>

</select>

set

set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。

<update id="updateAuthorIfNecessary">

  update Author

    <set>

      <if test="username != null">username=#{username},</if>

      <if test="password != null">password=#{password},</if>

      <if test="email != null">email=#{email},</if>

      <if test="bio != null">bio=#{bio}</if>

    </set>

  where id=#{id}

</update>

foreach

对一个collection集合进行遍历

<select id="selectPostIn" resultType="domain.blog.Post">

  SELECT *

  FROM POST P

  WHERE ID in

  <foreach item="item" index="index" collection="list"

      open="(" separator="," close=")">

        #{item}

  </foreach>

</select>

声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头open与结尾close的字符串以及在迭代结果之间放置分隔符。

bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。

<select id="selectBlogsLike" resultType="Blog">

  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />

  SELECT * FROM BLOG

  WHERE title LIKE #{pattern}

</select>

多数据库支持

一个配置了“_databaseId”变量的 databaseIdProvider 可用于动态代码中,这样就可以根据不同的数据库厂商构建特定的语句。

<insert id="insert">

  <selectKey keyProperty="id" resultType="int" order="BEFORE">

    <if test="_databaseId == 'oracle'">

      select seq_users.nextval from dual

    </if>

    <if test="_databaseId == 'db2'">

      select nextval for seq_users from sysibm.sysdummy1"

    </if>

  </selectKey>

  insert into users values (#{id}, #{name})

</insert>

OGNL(Object Graph Navigation Language )对象图导航语言

访问对象属性:person.name

调用方法:person.getName()

调用静态属性/方法:@java.lang.Math@PI

@java.util.UUID@randomUUID()

调用构造方法:new com.bean.Person(‘admin’).name

运算符:+,-*,/,%

逻辑运算符:in,not in,>,>=,<,<=,==,!=

提示:xml中特殊符号如”,>,<等这些都需要使用转义字符

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流光影下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值