MyBatis 进阶
- 复杂CURD
- 返回设置
- 返回类型:resultType
- 返回字典映射:resultMap
- 多表查询
- 动态SQL使⽤
- <<if>if>标签
- <trim\>标签
- <where\>标签
- <set\>标签
- <foreach\>标签
- 其他
- 打开日志
- 单元测试不污染数据库
复杂CURD
返回设置
返回类型:resultType
-
绝⼤数查询场景可以使⽤ resultType 进⾏返回,如下代码所示:
-
它的优点是使⽤⽅便,直接定义到某个实体类即可
-
<select id="getbyUserid" resultType="com.example.mybatis3.entity.Userinfo">select * from userinfo where id =${id} </select>
-
-
返回字典映射:resultMap
-
resultMap 使⽤场景:
- 字段名称和程序中的属性名不同的情况,可使⽤ resultMap 配置映射;
- ⼀对⼀和⼀对多关系可以使⽤resultMap映射并查询数据。
- 字段名称和程序中的属性名不同的情况,可使⽤ resultMap 配置映射;
-
字段名和属性名不同的情况
-
使用场景:
-
实现实体类中的属性 和 字段映射的功能
-
<resultMap id="userMap" type="com.example.mybatis3.entity.Userinfo"><id column="id" property="id"/><result column="username" property="username"/><result column="password" property="password"/><result column="photo" property="photo"/> </resultMap>
-
<select id="getbyUserid" resultMap="userMap">select * from userinfo where id =${id} </select>
-
-
-
当实体类属性名与数据库中名字不一致时:
- 使用 resultMap 进行映射
- 使用 数据库别名 as 重命名 (推荐)
多表查询
- 在多表查询时,如果使⽤ resultType 标签
- 在⼀个类中包含了另⼀个对象是查询不出来被包含的对象的
- ⽐如以下实体类:
- 最终实现:
- 链表查询(left join inner join) + xxxVO
- VO
- view object
- 专门给前端使用的对象
- VO
- 链表查询(left join inner join) + xxxVO
动态SQL使⽤
- 动态 sql 是Mybatis的强⼤特性之⼀,能够完成不同条件下不同的 sql 拼接
- mybatis – MyBatis 3 | 动态 SQL
<if>标签
-
例子:
-
<insert id="add" useGeneratedKeys="true" keyProperty="id">insert into userinfo(username,password<if test="updateTime != null">,updatetime</if>)values(#{username},#{password}<if test="updateTime != null">,#{updatetime}</if>) </insert>
-
-
效果:
<trim>标签
-
trim 通常配合 if 来用
-
如果所有字段都是⾮必填项
- 就考虑使⽤标签结合标签,对多个字段都采取动态⽣成的⽅式
-
标签中有如下属性:
- prefix:表示整个语句块,以prefix的值作为前缀
- suffix:表示整个语句块,以suffix的值作为后缀
- prefixOverrides:表示整个语句块要去除掉的前缀
- suffixOverrides:表示整个语句块要去除掉的后缀
- 有则去除,没有则啥事不干
-
例子:
-
<insert id="add" useGeneratedKeys="true" keyProperty="id">insert into userinfo<trim prefix="(" suffix=")" suffixOverrides=","><if test="username != null">username,</if><if test="password != null">password,</if><if test="photo != null">photo,</if></trim>values<trim prefix="(" suffix=")" suffixOverrides=","><if test="username != null">#{username},</if><if test="password != null">#{password},</if><if test="photo != null">#{photo},</if></trim></insert>
-
-
效果:
<where>标签
-
传⼊的⽤户对象,根据属性做 where 条件查询,⽤户对象中属性不为 null 的,都为查询条件。
-
where 可以去除 最前面的 and
- 不会删除最后面的
-
标签也可以使⽤ 替换
-
例:
-
<select id="getListByParm" resultType="com.example.mybatis3.entity.Userinfo">select * from userinfo<where><if test="username != null">username = #{username}</if><if test="password != null">and password = #{password}</if></where> </select>
-
-
效果:
<set>标签
-
根据传⼊的⽤户对象属性来更新⽤户数据,可以使⽤标签来指定动态内容
-
<update id="upUser">update userinfo<set><if test="username != null">username = #{username},</if><if test="password != null">password = #{password},</if></set>where id=#{id}</update>
-
-
以上标签也可以使⽤ 替换
<foreach>标签
-
对集合进⾏遍历时可以使⽤该标签。标签有如下属性:
- collection:
- 绑定⽅法参数中的集合,如 List,Set,Map或数组对象
- item:遍历时的每⼀个对象
- open:语句块开头的字符串
- close:语句块结束的字符串
- separator:每次遍历之间间隔的字符串
- collection:
-
例:
-
int deleteUsers(List<Integer> ids);
-
<delete id="deleteUsers">delete from userinfo where id in<foreach collection="ids" item="id" open="(" close=")" separator=",">#{id}</foreach> </delete>
-
-
效果:
其他
打开日志
mybatis:mapper-locations: classpath:mapper/**Mapper.xmlconfiguration: # 配置打印 MyBatis 执行的 SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 配置打印 MyBatis 执行的 SQL
logging:level:com:example:mybatis3: debug
- 日志内容:
- mybatis底层 就是 JDBC
- mybatis底层 就是 JDBC
单元测试不污染数据库
-
加上@Transactional注解:
-
可以加到类或者方法上
-
@SpringBootTest @Transactional class UserinfoMapperTest {@Autowiredprivate UserinfoMapper userinfoMapper;@Testvoid deleteUser() {int i = userinfoMapper.deleteUser(2);System.out.println(i);Assertions.assertEquals(1,i);} }
-
-
效果:
- 执行成功
- 并且数据库中数据未删除
- 并且数据库中数据未删除
- 执行成功