1.背景介绍
映射器是mybatis最复杂且最重要的组件。它由一个接口加上xml文件(或注解)组成。在映射器中可以配置参数、各类SQL语句、存储过程、缓存、级联等复杂的内容,并且通过简易的映射规则映射到指定的POJO或者其他对象上,映射器能够有效消除JDBC底层的代码。注解方式在实际开发中很少应用,因为其可读性比较差,不能很好的表达对应关系。
2.映射器配置元素
元素 | 说明 |
---|---|
1.select | 查询语句,可以自定义参数、返回结果 |
2.insert | 插入语句,返回入条数 |
3.update | 更新语句,返回影响行数 |
4.delete | 删除语句,返回删除的行数 |
5.sql | 定义部分固定的sql,方便其他地方使用 |
6.resultMap | 声明结果集映射规则 |
7.cache | 缓存配置 |
3.select元素-查询语句
在映射器中select元素代表SQL的select语句,用于查询。使开发过程中用的最多的语句,多则意味着强大和复杂,select的配置元素一共有14种,这里我们介绍几种常用的元素。
元素 | 说明 | 备注 |
id | 他和Mapper的命名空间组合起来是唯一的,供mybatis调用 | 如果命名空间和id结合起来不 唯一,mybatis将抛出异常 |
resultType | 定义类的全路径,在允许自动匹配的情况下,结果集将通过javaBean的规范映射;或定义为int、double、float、map等参数; 也可以使用别名,但要符合别名规范,切不能和resultMap同时使用 | 常用参数,比如统计总条数,设为int,注意全路径引用 |
resultMap | t它是映射集的引用,将执行强大的映射功能。resultMap能提供自定义映射规则的机会 | mybatis最复杂的元素,可以配置映射规则、级联和typeHandler |
parameterType | 将会传入这条语句的参数类的完全限定名或别名。 | |
flushCache | 无论语句什么时候被调用,都会导致缓存被清空。 | Boolean类型默认值:false。 |
useCache | 启动二级缓存开关,是否要求mybatis将此次结果缓存 | Boolean类型默认值:true。 |
timeout | 这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理) | |
fetchSize | 这是暗示驱动程序每次批量返回的结果行数。默认不设置(驱动自行处理) | |
statementType | STATEMENT,PREPARED或CALLABLE的一种。这会让MyBatis使用选择使用Statement,PreparedStatement或CallableStatement。默认值:PREPARED。 |
为了解决数据库表格字段和POJO类的属性名称不一致(mysql:create_time;student:createTime),可以在mybatis的配置文件的settings选项的mapUnderscoreToCamelCase,是控制驼峰映射的开关。
驼峰映射
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
驼峰映射对于命名规则有着严格的要求,有时不能满足项目中灵活应用,通常采用resultMap建立映射
<resultMap id="StudentDO" type="com.ptteng.classwork.pojo.StudentDO">
<id column="add_id" property="addId"/>
<result column="name" property="name"/>
<result column="qq" property="qq"/>
<result column="type" property="type"/>
<result column="entor_time" property="entorTime"/>
<result column="graduate_school" property="graduateSchool"/>
<result column="net_id" property="netId"/>
<result column="daily_link" property="dailyLink"/>
<result column="wish" property="wish"/>
<result column="senior" property="senior"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
</resultMap>
id colum对应数据库表格中的主键
别名设置:
为了简化resultType和parameterType的全路径引入,在
typeAliases
配置别名
<typeAliases>
<typeAlias type="java.lang.Integer" alias="int"/>
<typeAlias type="java.util.List" alias="list"/>
<!--对pojo对象较多的情况下,扫描包文件,自动默认小写命名,形成映射-->
<package name="com.ptteng.classwork.pojo"/>
</typeAliases>
@param注解传递参数,注意由于注解的指定,在mapper文件中不用再设置parameterType
boolean updateType(@Param("type")String name,
@Param("updateTime")Long updateTime,
@Param("addId")int addId );
<update id="updateType">
UPDATE student_registrantion SET type=type=#{type},update_time=#{updateTime} WHERE add_id=#{addId}
</update>
采用注解方式传递参数,代码简洁,可阅读性强,在参数少于5个情况下,优先选择。参数过多则采用bean类传递参数。
4.insert元素-插入语句
主键回填,元素属性
元素 | 描述 | 备注 |
useGeneratedKeys | 是否启用JDBC的getGeneratedKeys方法来取出有数据库内部生成的主键。(数据库表格中的自增主键) | 默认为false |
keyPropery | w唯一标记一个属性,Mybatis会通过gettGeneratedKeys的返回值,或则insert语句的selectKey子元素设置它的键值 | 默认值unset,不能和keyColum连用 |
keyColumn | t通过生成键值设置表格中的列名,这个设置仅在数据中是必须的,当主键列不是表格中的第一列时需要设置 |
从数据库中获取主键
<insert id="saveStudent" parameterType="studentDO"
useGeneratedKeys="true" keyProperty="addId">
INSERT INTO student_registrantion (name,qq,type,entor_time,graduate_school,net_id,daily_link,wish,senior,create_time,update_time)
VALUES(#{name},#{qq},#{type},#{entorTime},#{graduateSchool},#{netId},#{dailyLink},#{wish},#{senior},#{createTime},#{updateTime})
</insert>
自定义主键
有的时候主键可能依赖于某些规则,比如取消表格中add_id的自增规则,而是将其规则修改为:
- 当记录为空时,add_id=1
- 当记录不为空时,add_id为当前id加3
当然也可以设定规则为最后一个插入的数据的值,来获取自增主键
<insert id="saveStudent" parameterType="studentDO">
<selectKey keyProperty="addId" order="AFTER" resultType="int">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO student_registrantion (add_id,name,qq,type,entor_time,graduate_school,net_id,daily_link,wish,senior,create_time,update_time)
VALUES(#{addId},#{name},#{qq},#{type},#{entorTime},#{graduateSchool},#{netId},#{dailyLink},#{wish},#{senior},#{createTime},#{updateTime})
</insert>
4.动态SQL
动态sql语句在场景中的应用
模糊查询
<select id="selectLikeNameNetId" parameterType="studentDO"
resultType="studentDO">
SELECT * FROM student_registrantion WHERE 1=1
<choose>
<when test="name !=null and name !=''" >
and name like CONCAT(CONCAT('%',#{name},'%'))
</when>
<when test="netId !=null and netId !='' ">
<bind name="pattern1" value="'%'+_parameter.netId+'%'"></bind>
AND net_id LIKE #{pattern1}
</when>
</choose>
</select>
choose when标签,相当于java中的switch case,匹配条件执行,条件符合则跳出判断
<select id="selectLikeNameNetId" parameterType="studentDO"
resultType="studentDO">
SELECT * FROM student_registrantion
<where>
<if test="name !=null and name !=''" >
NAME like CONCAT(CONCAT('%',#{name},'%'))
</if>
<if test="netId !=null and netId !='' ">
<bind name="pattern1" value="'%'+_parameter.netId+'%'"></bind>
AND net_id LIKE #{pattern1}
</if>
</where>
</select>
where 标签默认匹配上下文的and or,两个属性共同参与判断,实现模糊查询
<insert id="studentBatchInsert" parameterType="List" useGeneratedKeys="true" keyProperty="addId">
INSERT INTO student_registrantion (add_id,name,qq,type,entor_time,graduate_school,net_id,daily_link,wish,senior,create_time,update_time)
VALUES
<foreach collection= "list" item= "studentDO" separator = ",">
(#{studentDO.addId},#{studentDO.name},#{studentDO.qq},#{studentDO.type},#{studentDO.entorTime},#{studentDO.graduateSchool},
#{studentDO.netId},#{studentDO.dailyLink},#{studentDO.wish},#{studentDO.senior},#{studentDO.createTime},#{studentDO.updateTime})
</foreach>
</insert>
全字段更新插入,判断属性为空则不更新,简化DAO
<!--根据主键全字段更新,if字段为空/为0,字段不更新-->
<update id="updateStudent" parameterType="studentDO">
UPDATE student_registrantion
<!--trim标签替代关键字set-->
<trim prefix="set" suffixOverrides=",">
<if test="name !=null and name != ''">
name=#{name},
</if>
<if test="qq !=null and qq != ''">
qq=#{qq},
</if>
<if test="type !=null and type != ''">
type=#{type},
</if>
<if test="entorTime !=null and entorTime != ''">
entor_time=#{entorTime},
</if>
<if test="graduateSchool !=null and graduateSchool != ''">
graduate_school=#{graduateSchool},
</if>
<if test="netId !=null and netId != ''">
net_id=#{netId},
</if>
<if test="dailyLink !=null and dailyLink != ''">
daily_link=#{dailyLink},
</if>
<if test="wish !=null and wish != ''">
wish=#{wish},
</if>
<if test="senior !=null and senior != ''">
senior=#{senior},
</if>
<if test="updateTime !=null and updateTime != ''">
update_time=#{updateTime},
</if>
</trim>
WHERE add_id=#{addId}
</update>
批量插入
<insert id="studentBatchInsert" parameterType="List" useGeneratedKeys="true" keyProperty="addId">
INSERT INTO student_registrantion (add_id,name,qq,type,entor_time,graduate_school,net_id,daily_link,wish,senior,create_time,update_time)
VALUES
<foreach collection= "list" item= "studentDO" separator = ",">
(#{studentDO.addId},#{studentDO.name},#{studentDO.qq},#{studentDO.type},#{studentDO.entorTime},#{studentDO.graduateSchool},
#{studentDO.netId},#{studentDO.dailyLink},#{studentDO.wish},#{studentDO.senior},#{studentDO.createTime},#{studentDO.updateTime})
</foreach>
</insert>
foreach标签遍历集合,批量插入