一 动态sql
1.1 什么是动态sql?
mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。
需求:用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。
对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。
这是我们上面输入映射进行综合查询用的一个sql的statement
<!-- 用户信息综合查询 -->
<select id="findUserList" parameterType="cn.eugene.po.UserQueryVo" resultType="cn.eugene.po.UserCustom">
select * from user where userName like '%${userCustom.userName}%'
</select>
其中UserQueryVo代码如下
package cn.eugene.po;
import java.util.List;
public class UserQueryVo {
private UserCustom userCustom;
private List<Integer> ids;
public UserCustom getUserCustom() {
return userCustom;
}
public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
}
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
@Override
public String toString() {
return "UserQueryVo [userCustom=" + userCustom + "]";
}
}
将这个statement改写下,变成下面这样,可以看到我们加入了<where>和<if>来动态判断userCustom.userName这个属性,输入userCustom.userName或则不输入都不会有影响,这就是动态sql
<select id="findUserCount" parameterType="cn.eugene.po.UserQueryVo" resultType="int">
select count(*) from user
<where>
<if test="userCustom!=null">
<if test="userCustom.userName!=null and userCustom.userName!=''">
and userName like '%${userCustom.userName}%'
</if>
</if>
</where>
</select>
测试代码和输入映射中的相同就不在演示了
1.2 sql片段
当多个页面的查询都用到了用户综合信息查询的时候,我们需要考虑将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。
方便程序员进行开发。
如何使用sql片段?
1.sql片段定义
<!-- id sql片段的唯一标识 ,经验:一般是基于单表来定义sql片段,这样sql的重用性才高,sql片段中不包含where-->
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.userName!=null and userCustom.userName!=''">
and userName like '%${userCustom.userName}%'
</if>
</if>
</sql>
2.引用(使用include)
<!-- 符合条件的用户数查询 -->
<select id="findUserCount" parameterType="cn.eugene.po.UserQueryVo" resultType="int">
select count(*) from user
<!-- where可以自动去掉条件中的一个and -->
<where>
<!-- refid,sql片段的标识 -->
<include refid="query_user_where"></include>
</where>
</select>
1.3 foreach
向sql传递数组或List,mybatis使用foreach解析
需求:在用户查询列表和查询总数的statement中增加多个id输入查询。
sql语句如下:
两种方法:
SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
SELECT * FROM USER WHERE id IN(1,10,16)
具体实例
以综合查询用户数为例,查询用户名为运费id等于1的用户数有多少
在输入参数类型中添加List<Integer> ids传入多个id,以上面的用户综合查询为例
我们这里需要向自定义的对象中封装更多参数
package cn.eugene.po;
import java.util.List;
public class UserQueryVo {
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
....
}
修改mapper.xml,这里用到了sql片段
<!-- id sql片段的唯一标识 ,经验:一般是基于单表来定义sql片段,这样sql的重用性才高,sql片段中不包含where-->
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.userName!=null and userCustom.userName!=''">
and userName like '%${userCustom.userName}%'
</if>
</if>
</sql>
<sql id="query_user_id">
<if test="ids!=null">
<foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
<!-- 每个遍历需要拼接的串 -->
id=#{user_id}
</foreach>
</if>
</sql>
<!-- 符合条件的用户数查询 -->
<select id="findUserCount" parameterType="cn.eugene.po.UserQueryVo" resultType="int">
select count(*) from user
<!-- where可以自动去掉条件中的一个and -->
<where>
<!-- refid,sql片段的标识 -->
<include refid="query_user_where"></include>
<include refid="query_user_id2"></include>
</where>
</select>
测试代码
//满足条件的用户数查询
@Test
public void testFindUserCount() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//mybatis自动生成接口实现类代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setUserName("运费");
userQueryVo.setUserCustom(userCustom);
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
userQueryVo.setIds(ids);
int count = userMapper.findUserCount(userQueryVo);
System.out.println("count: "+count);
}
另外一个sql的实现,sql片段
<sql id="query_user_id2">
<if test="ids!=null">
<foreach collection="ids" item="user_id" open="and id in(" close=")" separator=",">
<!-- 每个遍历需要拼接的串 -->
#{user_id}
</foreach>
</if>
</sql>
如果对你有所帮助的话,点个赞吧
网友评论