MyBatis【多表查询与动态SQL使用】
- 🍎一.MyBatis多表查询
- 🍒1.1 一对一查询
- 🍒1.2 一对多查询
- 🍎二.动态SQL使用
- 🍒2.1 if 标签使用
- 🍒2.2 trim 标签使用
- 🍒2.3 where 标签使用
- 🍒2.4 set 标签使用(增添)
- 🍒2.5 foreach 标签使用(集合进行遍历)
🍎一.MyBatis多表查询
我们在进行多表查询的时候,我们需要在数据库创建两个表(作者表,文章表)
<作者表 userinfo>:
<文章表 articleinfo>:
在项目中创建的对象:
在userinfo配置文件mybatis.xml配置信息
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namepace 要设置是实现接口所在的具体包加类名 -->
<mapper namespace="com.example.demo.mapper.UserMapper">
<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
<!-- 主键映射 -->
<id column="id" property="id"></id>
<!-- 普通属性映射映射 -->
<result column="username" property="username"></result>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="photo" property="photo"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
<result column="state" property="state"></result>
<!-- collection 关联映射 适用于一对多 -->
<collection
property="artlist"
resultMap="com.example.demo.mapper.ArticleMapper.BaseMap"
columnPrefix="a_">
</collection>
</resultMap>
</mapper>
在aricleinfo配置文件mybatis.xml配置信息
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namepace 要设置是实现接口所在的具体包加类名 -->
<mapper namespace="com.example.demo.mapper.ArticleMapper">
<resultMap id="BaseMap" type="com.example.demo.model.ArticleInfo">
<!-- 主键映射 -->
<id column="id" property="id"></id>
<!-- 普通属性映射映射 -->
<result column="title" property="title"></result>
<result column="content" property="content"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
<result column="uid" property="uid"></result>
<result column="rcount" property="rcount"></result>
<result column="state" property="state"></result>
<!-- association 关联映射 适用于一对一 -->
<association property="userInfo"
resultMap="com.example.demo.mapper.UserMapper.BaseMap"
columnPrefix="u_">
</association>
</resultMap>
</mapper>
🍒1.1 一对一查询
创建一个ArticleMapper接口方法:
创建一个ArticleMapper接口对应 aricleinfo 和 userinfo 在maybatis.xml配置文件
ArticleMapper.xml 配置信息:
UserMapper.xml 配置信息:
配置文件多表查询语句
这是我们在MySQL进行多表一对一查询执行语句
我们发现这两个表都有一个相同的id名称属性,这会使在查询时前面id的值会将后面id的值进行覆盖,
所有我们需要将对被联合查询表进行重命名
<select id="getArticleById" resultMap="BaseMap">
select a.*,
u.id u_id,
u.username u_username,
u.password u_password
from articleinfo a left join userinfo u on a.uid=u.id
where a.id=#{id}
</select>
在进行单元测试代码:
测试结果:
🍒1.2 一对多查询
UserMapper接口代码:
//查询用户及用户发表的所有文章,根据用户uid
public UserInfo getUserAndArticleByUid(@Param("uid") Integer uid);
UserMapper.xml代码:
<!-- 根据用户输入uid查询用户及用户发表的所有文章,根据用户uid-->
<select id="getUserAndArticleByUid" resultMap="BaseMap">
select u.*,
a.id a_id,
a.title a_title,
a.content a_content,
a.createtime a_createtime,
a.updatetime a_updatetime
from userinfo u left join articleinfo a on u.id=a.uid
where u.id=#{uid}
</select>
单元测试代码:
@Test
void getUserAndArticleByUid() {
UserInfo userInfo = userMapper.getUserAndArticleByUid(1);
log.info("用户文章详细"+userInfo);
}
单元测试结果:
🍎二.动态SQL使用
动态 sql 是Mybatis的强⼤特性之⼀,能够完成不同条件下不同的 sql 拼接
可以参考官⽅⽂档:官⽅⽂档
🍒2.1 if 标签使用
在注册⽤户的时候,可能会有这样⼀个问题,就是有必选和非必选是,当我们使用传统的SQL语句就会很繁琐,需要大量代码来实现,这时我们就可以使用动态SQL来进行筛选用户所填的非必选信息
<!-- 添加用户时 photo时非必传参数 -->
<insert id="add2">
insert into userinfo(username,password
<if test="photo != null">
,photo
</if>
) values(#{username},#{password}
<if test="photo !=null">
,#{photo}
</if>
)
</insert>
我们在单元测试中假设我们没有填写photo属性信息:
结果:
我们看到并没有实现photo属性信息填写,解决了非必要填写信息的选择语句繁琐的难题
当我们填写photo信息时:
🍒2.2 trim 标签使用
<trim>
标签结合<if>
标签,对多个字段都采取动态⽣成的⽅式
<trim>
标签中有如下属性:
● prefix:表示整个语句块,以prefix的值作为前缀
● suffix:表示整个语句块,以suffix的值作为后缀
● prefixOverrides:表示整个语句块要去除掉的前缀
● suffixOverrides:表示整个语句块要去除掉的后缀
<!-- 添加用户时 photo时非必传参数 -->
<insert id="add3">
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>
🍒2.3 where 标签使用
where属性没有输入就默认时全局查找了
传⼊的⽤户对象,根据属性做 where 条件查询,⽤户对象中属性不为 null 的,都为查询条件
如user.username 为 “a”,则查询条件为 where username=“a”:
<!-- <where> 标签可以去除前面and标签 -->
<select id="getUserById" resultMap="BaseMap">
select * from userinfo
<where>
<if test="id != null">
and id=#{id}
</if>
</where>
</select>
以上<where>
标签也可以使⽤ <trim prefix="where" prefixOverrides="and">
替换
🍒2.4 set 标签使用(增添)
根据传⼊的⽤户对象属性来更新⽤户数据,可以使⽤<set>
标签来指定动态内容
<!-- <set>可以去除 后面的 ,标签 -->
<update id="update2">
update userinfo
<set>
<if test="username != null">
username=#{username},
</if>
<if test="password != null">
password=#{password},
</if>
<if test="photo != null">
photo=#{photo},
</if>
</set>
where id=#{id}
</update>
以上<set>
标签也可以使⽤ <trim prefix="set" suffixOverrides=",">
替换
🍒2.5 foreach 标签使用(集合进行遍历)
// 删除方法{根据id删除这一条数据
public int del2(@Param("ids") List<Integer> ids);
<!-- collection 是数组对象名
item 是 数组对象的子对象
separator是每次遍历之间间隔的字符串-->
<delete id="del2">
delete from userinfo where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</delete>
测试单元代码:
测试单元结果: