MyBatis-【第三天学习】
文章目录
1.复杂的联表查询
一对多处理:
即对实体类中属性类型为泛型集合的查询,即查询role实体类中的allUser属性
@Data
public class Role {
private Integer id; //id
private String roleName; //角色名称
private List<User> allUser;
@Override
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName + '\'' +
", allUser=" + allUser +
'}';
}
}
@Data
public class User {
private String userName; //用户名称
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
'}';
}
}
<select id="searchRoleOfAllUser" resultMap="cMap">
select r.id,r.roleName,u.userName from smbms_role r,smbms_user u where r.id=u.userRole and r.id=1
</select>
<resultMap id="cMap" type="role">
<result property="id" column="id"></result>
<result property="roleName" column="roleName"></result>
<!--此处的property对应role实体类中的allUser属性,泛型信息为user-->
<collection property="allUser" ofType="user">
<!--此处的property对应user实体类中想要查询的属性,column对应sql语句查询的内容 -->
<result property="userName" column="userName"></result>
</collection>
</resultMap>
2.动态SQL
是什么:根据不同的条件生成不同的sql语句
2.1 IF查询
<select id="searchRoleOfAllUser" resultMap="cMap" parameterType="_int">
select r.id,r.roleName,u.userName from smbms_role r,smbms_user u where r.id=u.userRole
--rID对应传入的参数名称
<if test="rID > 0">
and r.id=#{rID}
</if>
</select>
2.2 choose,when,otherwise
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<choose>
<when test="title != null">
title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</where>
</select>
注意:只会选择其中一个实现,相当于switch中的break效果
2.3 where
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
<select id="getUserList" resultMap="map">
select * from smbms.smbms_user u
<where>
<if test="uID > 0">
and u.id=#{uID}
</if>
</where>
</select>
执行的sql语句会自动把无用的and舍去
2.4 set
这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
<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>
首行需要加逗号,若后序判断均不成立,会自动把逗号舍去
2.5 trim
-- prefix:前缀 prefixOverrides:前缀覆盖 suffix:后缀 suffixOverrides:后缀覆盖
<trim prefix="" suffix="" prefixOverrides="" suffixOverrides="" ></trim>
2.6 SQL片段
1.使用sql标签抽取公共部分
<sql id="select_user">
select * from smbms.smbms_user u
</sql>
2.在需要的地方include标签引用
<select id="getUserList" resultMap="map">
<include refid="select_user"></include>
<where>
<if test="uID > 0">
and u.id=#{uID}
</if>
</where>
</select>
注意事项:
- 最好基于单表定义sql片段
- 最好不要存在where标签
2.7 forEach
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)
<!--parameterType:传递参数为map类型 collection:map中存放的关键字为ids的集合-->
<select id="getUserList" resultMap="map" parameterType="map">
<include refid="select_user"></include>
<where>
<foreach collection="ids" item="id" open="(" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
==
select * from smbms_user where (id=1 or id=2)
测试:
@Test
public void getUserList(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<>();
ArrayList<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
map.put("ids",ids);
List<User> userList = mapper.getUserList(map);
for (User user:userList){
System.out.println(user);
}
sqlSession.close();
}
可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。