手动拼接SQL太麻烦,看看MyBatis动态SQL

动态SQL

开发人员通常根据需求手动拼接SQL语句,这是一个极其麻烦的事情,而且很容易出错。MyBatis提供了动态组装的功能,允许在SQL语句中加入 <if>、<where>、<when>、<foreach>用于逻辑控制的元素,达到SQL语句根据需要动态变化的效果。

我们重新创建一个UserMapperDanmic接口和UserMapperDanmic.xml文件,专门讲解动态SQL语句

  • UserMapperDanmic接口
public interface UserMapperDanmic {
    /*此处添加和SQL语句对应的抽象方法*/
}
  • UserMapperDanmic.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">
<mapper namespace="com.itheima.mapper.UserMapperDanmic">
	<!--此处填写SQL语句-->
</mapper>

<if>语句

在UserMapperDanmic接口中添加下面的抽象方法

//根据条件动态查询用户信息
public List<User> selectUserByIf(User user);

在UserMapperDanmic.xml映射文件中,添加下面的代码,根据条件动态查询用户信息

<!--根据条件动态的查询用户信息-->
<!--where后面的1=1,是为了防止后面的if都不满足时,sql语句不成立而特加的-->
<!--*if test用于判断-->
<select id="selectUserByIf" resultType="com.itheima.domain.User" parameterType="user">
    select * from user where 1=1
    <if test="uname!=null and uname!=''">
        and uname like concat('%',#{uname},'%')
    </if>

    <if test="usex!=null and usex!=''">
        and usex=#{usex}
    </if>
</select>

创建UserMapperDanmicTest测试类,编写测试方法,代码如下

@Test
public void test(){
    InputStream in = null;
    try {
        //读取配置文件
        in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(in);
        SqlSession ss = ssf.openSession();

        //获取映射器接口
        UserMapperDanmic mapper = ss.getMapper(UserMapperDanmic.class);
        //创建参数对象,查询姓王的男性用户的信息
        User user=new User();
        user.setUname("王"); //注释掉试试
        user.setUsex("男");  //注释掉试试
        List<User> list = mapper.selectUserByIf(user);
        for (User u : list) {
            System.out.println(u);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

运行测试方法test会方法,查看日志信息,其查询语句是这样的

select * from user where 1=1 and uname like concat('%',?,'%') and usex=? 

user.setUname注释掉再运行,查看日志信息,其查询语句是这样的

select * from user where 1=1 and usex=? 

user.setUsex注释掉再运行,查看日志信息,其查询语句是这样的

select * from user where 1=1 and uname like concat('%',?,'%') 

user.setUname和user.setUsex都注释掉,查看日志信息,其查询语句是这样的

select * from user where 1=1 

<choose>语句

choose语句类似于Java的switch语句,用户从几个条件语句中进行选择执行

现在UserMapperDanmic接口中添加下面的抽象方法

//根据条件动态查询用户信息
public List<User> selectUserByChoose(User user);

再到UserMapperDanmic映射文件中添加下面的代码

<!--使用choose、when、otherwise元素动态的查询用户信息-->
<!--类似于switch、case、default-->
<select id="selectUserByChoose" parameterType="user" resultType="user">
    select * from user where 1=1
    <choose>
        <when test="uname!=null and uname!=''">
            and uname like concat('%',#{uname},'%')
        </when>

        <when test="usex!=null and usex!=''">
            and usex=#{usex}
        </when>

        <otherwise>
            and id>=10
        </otherwise>
    </choose>
</select>

在UserMapperDanmicTest测试类中编写测试方法,代码如下

@Test
public void test2(){
    InputStream in = null;
    try {
        //读取配置文件
        in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(in);
        SqlSession ss = ssf.openSession();

        //获取映射器接口
        UserMapperDanmic mapper = ss.getMapper(UserMapperDanmic.class);
        //创建参数对象
        User user=new User();
        user.setUname("王"); //注释掉试试
        user.setUsex("男");  //注释掉试试
        List<User> list = mapper.selectUserByChoose(user);
        for (User u : list) {
            System.out.println(u);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

<foreach>语句

<foreach>语句主要用于in条件下,在SQL语句中表示遍历一个集合

先在UserMapperDanmic接口中添加下面的方法

/*查询满足多个id的用户信息*/
public List<User> selectUserByForeach(List<Integer> list);

再到UserMapperDanmic.xml映射文件中添加如下的SQL映射语句

<!--使用foreach语句查询多个id的用户信息-->
<select id="selectUserByForeach" parameterType="List" resultType="user">
    select * from user where id in
    <foreach collection="list" item="item" index="index" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

collection: 表示要遍历的集合
item: 表示集合中的元素
index: 表示索引
open: 表示条件以"("开始
speartor: 表示用元素","隔开
close: 表示条件以")"结束

<where>语句

<where>语句用于,在条件查询where语句时替换where语句,如下面的代码

现在UserMapperDanmic接口中添加抽象方法

/*查询满足条件的用户信息*/
public List<User> selectUserByWhere(User user);

再到UserMapperDanmic.xml映射文件中添加SQL映射语句

<!--查询满足条件的用户信息-->
<select id="selectUserByWhere" resultType="com.itheima.domain.User" parameterType="user">
    select * from user
    <where>
        <if test="uname!=null and uname!=''">
            and uname like concat('%',#{uname},'%')
        </if>

        <if test="usex!=null and usex!=''">
            and usex=#{usex}
        </if>
    </where>
</select>

再到UserMapperDanmicTest测试类中添加测试方法,进行测试

/*使用where语句查询满足条件的用户信息*/
@Test
public void test4(){
    InputStream in = null;
    try {
        //读取配置文件
        in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(in);
        SqlSession ss = ssf.openSession();

        //获取映射器接口
        UserMapperDanmic mapper = ss.getMapper(UserMapperDanmic.class);
        //创建User对象
        User user=new User();
        user.setUname("王");
        user.setUsex("男");
        List<User> list = mapper.selectUserByWhere(user);
        for (User u : list) {
            System.out.println(u);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

<bind>语句

在进行模糊查询时,不同的数据库字符串拼接函数或者连接符不同,例如MySQL用concat函数、Oracle使用||连接符,这样MyBatis就需要对不同的数据库进行不同的实现,不利于代码移植。 <bind>语句就是用来解决这个问题

先在UserMapperDanmic接口中添加抽象方法

/*查询满足条件的用户信息*/
public List<User> selectUserByBind(User user);

再到UserMapperDanmic.xml映射文件中添加SQL映射语句

<!--使用bind语句实现模糊查询-->
<!--bind标签用来 定义模糊查询的条件-->
<select id="selectUserByBind" resultType="user" parameterType="user">
    <bind name="uname" value="'%'+uname+'%'"/>
    select * from user where uname like #{uname}
</select>

再到UserMapperDanmicTest类中编写测试代码,测试执行

/*使用bind语句模糊查询满足条件的用户信息*/
@Test
public void test5(){
    InputStream in = null;
    try {
        //读取配置文件
        in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(in);
        SqlSession ss = ssf.openSession();

        //获取映射器接口
        UserMapperDanmic mapper = ss.getMapper(UserMapperDanmic.class);
        //创建User对象
        User user=new User();
        user.setUname("王");
        List<User> list = mapper.selectUserByBind(user);
        for (User u : list) {
            System.out.println(u);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

<sql>语句

<sql>语句用于封装一部分sql语句,以方便在后面的sql语句中复用

抽取sql语句的片段代码如下,分配一个id值

<!--抽取sql语句的片段-->
<sql id="selectUser" select * from User</sql>

在其他的sql语句中根据id,引用前面的sql语句片段

<!--查询指定id指的用户信息-->
<select id="findById" parameterType="int" resultType="user">
    <include refid="selectUser"></include> where id=#{id}
</select>

<!--查询满足多个id值的多个用户信息-->
<select id="findByIds" parameterType="list" resultType="user">
    <include refid="selectUser"></include>
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值