动态sql语句

1.1 动态sql语句概述

Mybatis 的映射文件中,业务逻辑复杂时, SQL是动态变化的,此时在前面的学习中 SQL 就不能满足要求了。

参考的官方文档:
在这里插入图片描述

1.2 动态 SQL 之<if>

根据实体类的不同取值,使用不同的 SQL语句来进行查询
比如在 id 如果不为空时可以根据id查询,如果username 不为空时还要加入用户名作为条件。
这种情况在多条件组合查询中经常会碰到

  <select id="findColl" parameterType="user" resultType="user">
        select * from T_user
        <where> <!--表示where-->
            <if test="id!=0">
                 id=#{id}
            </if>
            <if test="username!=null and username!=''">
                and username=#{username}
            </if>
        </where>

编写dao接口:

//多条件查询
public List<User> findColl(User user);

当查询条件id和username都存在时,控制台打印的sql语句如下:

     @Test
    public void findCollT(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user=new User();
        user.setId(1);
        user.setUsername("张三");
        List<User> coll = mapper.findColl(user);
        System.out.println(coll.toString());
        
        MybatisUtils.closeSqlSession(sqlSession);
    }

在这里插入图片描述

当查询条件只有id存在时,控制台打印的sql语句如下:

 //获得MyBatis框架生成的UserDao接口的实现类
@Test
    public void findCollT(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user=new User();
        user.setId(1);
        List<User> coll = mapper.findColl(user);
        System.out.println(coll.toString());MybatisUtils.closeSqlSession(sqlSession);
    }

在这里插入图片描述

总结语法:

<where>:条件标签。如果有动态条件,则使用该标签代替 where 关键字。
<if>:条件判断标签。
<if test=“条件判断”>
    查询条件拼接
</if>

1.3 动态sql之set (update insert)

  <!-- 动态语句 set 更新语句 update 表名 set name=#{name} -->
 <update id="updateMap" parameterType="map">
        update T_user 
        <set>
            <if test="username!=null">username=#{username},</if>
            <if test="sex!=null">sex=#{sex}</if>
        </set>
        <where>
            <if test="id!=null">id=#{id}</if>
        </where>
    </update>
    <!-- 动态语句 set 插入语句 insert into 表名 set name=#{name},age=#{age} -->
 
    <insert id="saveMap" parameterType="map">
        insert into T_user
        <set>
            <if test="id!=null">id=#{id},</if>
            <if test="username!=null">username=#{username},</if>
            <if test="sex!=null">sex=#{sex},</if>
            <if test="address!=null">address=#{address},</if>
            <if test="birthday!=null">birthday=#{birthday}</if>
        </set>
    </insert>

编写dao接口添加方法:

public int updateMap(Map<String ,Object> map);public int saveMap(Map<String ,Object> map);

测试类编写:

修改的测试方法
@Test
    public void updatemap(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);Map<String,Object> map=new HashMap<>();
        map.put("id",1);
        map.put("username","老六");
        map.put("sex","女");
        int i = mapper.updateMap(map);
        System.out.println(i);
    }
添加的测试方法
    @Test
    public void savemapT(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);Map<String,Object> map=new HashMap<>();
        map.put("username","老六");
        map.put("sex","女");
        map.put("address","郑州");
        map.put("birthday",Date.valueOf("2010-03-09"));
        int i = mapper.saveMap(map);
        System.out.println(i);
    }

总结语法:

<set>:条件标签。set 元素可以用于动态包含需要更新的列
<if>:条件判断标签。
<if test="条件判断">
    查询条件拼接
</if>

1.4 动态sql之choose (when, otherwise)

相当于Java中的switch语句

当when有条件满足的时候,就跳出choose

 <choose>
        <when test="条件1">...</when>
        <when test="条件2">...</when>
        <when test="条件3">...</when>
        <otherwise>其他条件</otherwise>
</choose>

代码演示步骤:

1、编写Dao接口代码

2、编写mapper文件

3、测试运行

代码实现:

编写Dao接口代码

public List<User> showUserfindAll(
       @Param("username") String username,
        @Param("sex") String sex,
        @Param("address") String address,
        @Param("birthday") Date birthday;

编写mapper文件

<!-- 动态语句choose when when otherwise -->
<!-- if elseif elseif else
    <choose>
        <when test=""></when>
        <when test=""></when>
        <when test=""></when>
        <otherwise>...</otherwise>
    </choose>-->
<select id="showUserfindAll" resultType="cn.zxy.pojo.User">
    select * from user where 
    <choose>
        <when test="username!=null and username!=''">
             username like concat("%",#{username},"%")
        </when>
        <when test="sex!=null and sex!=''">
             sex =#{sex}
        </when>
        <when test="address!=null and address!=''">
            address like concat("%",#{address},"%")
        </when>
        <otherwise>
             year(birthday)=year(#{birthday})
        </otherwise></choose>

另一种写法


 <select id="showUserfindAll" resultType="cn.zxy.pojo.User">
        select * from user 
	<where>
        <choose>
            <when test="username!=null">
              <choose>
                 <when test="username.indexOf('%')!=-1"> username like #{username}</when>
                 <when test="username.indexOf('_')!=-1">username like #{username}</when>
                 <otherwise>username = #{username}</otherwise>
              </choose>
            </when>
            <when test="sex!=null and sex!=''">
               sex =#{sex}
            </when>
            <when test="address!=null and address!=''">
                address like concat("%",#{address},"%")
            </when>
            <otherwise>
                birthday=#{birthday}
            </otherwise>
        </choose>
	</where>

    </select>

实体和数据库名字不匹配

<!-- 查询中如果表字段名和实体类名不一致,不想定义ResultMap,可以使用查询的列名 -->
<sql id="s1p">id,user_name username,birthday birth,address addr,sex sex</sql><select id="showUserfindAll" resultType="cn.zxy.pojo.User">
    select <include refid="s1p"/> from user where 1=1
    <choose>
        <when test="username!=null">
            <choose>
                <when test="username.indexOf('%')!=-1">user_name like #{username}</when>
                <when test="username.indexOf('_')!=-1">user_name like #{username}</when>
                <otherwise>user_name = #{username}</otherwise>
            </choose>
        </when>
        <when test="sex!=null and sex!=''">
            and sex =#{sex}
        </when>
        <when test="address!=null and address!=''">
            and address like concat("%",#{addr},"%")
        </when>
        <otherwise>
            and year(birthday)=year(#{birth})
        </otherwise>
    </choose>
</select>

测试运行

 @Test
    public void test() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
        SqlSession session = factory.openSession();
        UserDao userDao = session.getMapper(UserDao.class);
        List<User> users = userDao.showUserfindAll("小_", "男", "河", null);
        System.out.println(users.toString());}

1.5 动态 SQL 之<foreach>

循环执行sql的拼接操作,例如:SELECT * FROM user WHERE id IN (1,2,5)。

foreach 迭代一个集合,通常用于in条件

属性:

  • item 查询条件

  • collection:必须指定

    • list

    • array

    • map—key

  • open : 括号 (

  • separator :分割符 ,

  • close :括号 )

例子如下

  <!--循环迭代-->
<select id="findByIds" parameterType="list" resultType="user">
    <!--
        collection: 表示集合存储类型 分别为 list array数组
           open : id in (  是指代  where id in(
           close: 闭合括号
           item : 查询条件
           separator: 分割符
    -->
    select * from T_user
    <where>
    <foreach collection="list" open="id in (" close=")" item="id" separator=",">
        #{id}
    </foreach>
    </where>
</select>

编写dao接口:

//根据多个id查询
public List<User> findByIds(List<Integer> ids);

测试代码片段如下:

 @Test
    public void findByidst() {
        //获取sqlssession给定的对象
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        //创建list集合 并赋值
        List<Integer> list=new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        //把集合里面的值赋给mapper
        List<User> byIds = mapper.findByIds(list);
        for (User byId : byIds) {
            System.out.println(byId);
        }
        MybatisUtils.closeSqlSession(sqlSession);
    }

批量插入:

Mapper接口编写

public  void insert(List<User> list);

映射文件编写:

 <insert id="insert" parameterType="user">
        insert into user values
        <foreach collection="list" separator="," item="user">
            (#{user.id},#{user.username},#{user.sex},#{user.address},#{user.birthday})
        </foreach>
    </insert>

测试类编写:

 @Test
    public void inTest(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession(true);
        DUserMapper mapper = sqlSession.getMapper(DUserMapper.class);
        long start=System.currentTimeMillis();
        log.info("开始的时间{}",start);
        List<User> userList=new ArrayList<>();
        User user;
        for (int i = 0; i < 5; i++) {
            user=new User();
            user.setUsername("唐"+i);
            user.setSex("男");
            user.setAddress("河南北京");
            user.setBirthday(new Date());
            userList.add(user);
        }
        mapper.insert(userList);
        long end = System.currentTimeMillis();
        log.info("结束的时间{}",(end-start));
    }

总结语法:

<foreach>:循环遍历标签。适用于多个参数或者的关系。
    <foreach collection="" open="" close="" item="" separator="">
        获取参数
    </foreach>

属性
collection:参数容器类型, (list-集合, array-数组)
open:开始的 SQL 语句 id in (
close:结束的 SQL 语句
item:参数变量名
separator:分隔符

1.6 SQL片段抽取

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

<!--抽取sql片段简化编写-->
<sql id="selectUser" select * from student</sql>
<!--根据id查询-->
<select id="findById" parameterType="int" resultType="user">
    <include refid="selectUser"></include> where id=#{id}
</select>
<!--根据ids遍历-->
<select id="findByIds" parameterType="list" resultType="student">
    <include refid="selectUser"></include>
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

总结语法:

我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果。

-  <sql>:抽取 SQL 语句标签。 
-  <include>:引入 SQL 片段标签。 
   <sql id=“片段唯一标识”>抽取的 SQL 语句</sql> 
<include refid=“片段唯一标识”/>
 

1.7 知识小结

MyBatis映射文件配置:

<select>:查询
​
<insert>:插入
​
<update>:修改
​
<delete>:删除
​
<where>:where条件
​
<if>:if判断
​
<foreach>:循环
​
<sql>:sql片段抽取
​
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis是一个开源的持久层框架,它可以帮助开发者简化数据库操作的代码。MyBatis动态SQL语句是指在编写SQL语句时可以根据不同的条件动态生成不同的SQL语句MyBatis提供了以下几种方式来实现动态SQL语句: 1. if元素:通过if元素可以根据条件判断来生成不同的SQL语句片段。例如: ``` <select id="getUserList" parameterType="User" resultType="User"> SELECT * FROM user WHERE 1=1 <if test="name != null"> AND name = #{name} </if> <if test="age != null"> AND age = #{age} </if> </select> ``` 上述示例中,如果传入的User对象中name属性不为空,则会生成AND name = #{name}这段SQL语句。 2. choose、when、otherwise元素:通过choose、when、otherwise元素可以实现类似于switch语句的功能,根据不同的条件选择不同的SQL语句片段。例如: ``` <select id="getUserList" parameterType="User" resultType="User"> SELECT * FROM user WHERE 1=1 <choose> <when test="name != null"> AND name = #{name} </when> <when test="age != null"> AND age = #{age} </when> <otherwise> AND status = 'ACTIVE' </otherwise> </choose> </select> ``` 上述示例中,如果传入的User对象中name属性不为空,则会生成AND name = #{name}这段SQL语句;如果name为空而age不为空,则会生成AND age = #{age}这段SQL语句;如果name和age都为空,则会生成AND status = 'ACTIVE'这段SQL语句。 3. foreach元素:通过foreach元素可以实现对集合类型的参数进行遍历,并生成相应的SQL语句片段。例如: ``` <select id="getUserList" parameterType="List" resultType="User"> SELECT * FROM user WHERE id IN <foreach collection="list" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> ``` 上述示例中,如果传入的List参数中包含[1, 2, 3]三个元素,则会生成SELECT * FROM user WHERE id IN (1, 2, 3)这段SQL语句。 这些是MyBatis动态SQL语句的几种常用方式,通过它们可以根据不同的条件生成不同的SQL语句,提高了SQL语句的灵活性和可复用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值