mybatis 动态sql

转载 2018年04月14日 23:08:03

1 动态sql

什么是动态sql

mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。

需求

用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。
对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。

mapper.xml

<!--用户信息综合查询
    #{userCustom.sex}:取出pojo包装对象中性别值
    ${userCustom.loginname}:取出pojo包装对象中用户名称
      -->
    <select id="findUserList2" parameterType="mybatis.po.UserQueryVo" resultType="mybatis.po.UserCustom">
        select * from user
        <!--where 可以自动去掉条件中的第一个and  -->
        <where>
            <if test="userCustom!=null">
                <if test="userCustom.sex!=null and userCustom.sex!=''">
                    and user.sex=#{userCustom.sex}
                </if>
                <if test="userCustom.loginname!=null and userCustom.loginname!=''">
                    and user.loginname like '%${userCustom.loginname}%'
                </if>
            </if>
        </where>
    </select>

    <select id="findUserCount2" parameterType="mybatis.po.UserQueryVo" resultType="int">
        select count(*) from user
        <!--where 可以自动去掉条件中的第一个and  -->
        <where>
            <if test="userCustom!=null">
                <if test="userCustom.sex!=null and userCustom.sex!=''">
                    and user.sex=#{userCustom.sex}
                </if>
                <if test="userCustom.loginname!=null and userCustom.loginname!=''">
                    and user.loginname like '%${userCustom.loginname}%'
                </if>
            </if>
        </where>
    </select>

测试代码

@Test
    public void testFindUserList2() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo=new UserQueryVo();
        UserCustom userCustom=new UserCustom();
        //由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中
        //userCustom.setSex("男");
        userCustom.setLoginname("小明");
        userQueryVo.setUserCustom(userCustom);
        //调用userMapper方法
        List<UserCustom> list=userMapper.findUserList2(userQueryVo);
        System.out.println(list);
    }

    @Test
    public void testFindUserCount() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo=new UserQueryVo();
        UserCustom userCustom=new UserCustom();
        //userCustom.setSex("男");
        userCustom.setLoginname("小明");
        userQueryVo.setUserCustom(userCustom);
        //调用userMapper方法
        int count=userMapper.findUserCount2(userQueryVo);
        System.out.println(count);
    }

2 sql片段

1 需求

将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。
方便程序员进行开发。

2 定义sql片段

<!--定义sql片段
    id:sql片段的唯一标识  
    经验:是基于表单来定义sql片段,这样 sql 片段可重用型才高
    在sql片段中不要包括where
    -->
    <sql id="query_user_where" >
        <if test="userCustom!=null">
            <if test="userCustom.sex!=null and userCustom.sex!=''">
                and user.sex=#{userCustom.sex}
            </if>
            <if test="userCustom.loginname!=null and userCustom.loginname!=''">
                and user.loginname like '%${userCustom.loginname}%'
            </if>
        </if>
    </sql>
    <!--在mapper.xml中定义的statement中引用sql片段:  -->
    <select id="findUserList3" parameterType="mybatis.po.UserQueryVo" resultType="mybatis.po.UserCustom">
        select * from user
        <where>
            <!--引用sql片段的id,如果refid指定的id不在本mapper文件中,需要前边加载namespace  -->
            <include refid="query_user_where"></include>
        </where>
    </select>

foreach

向sql传递数组或List,mybatis使用foreach解析

1 需求

在用户查询列表和查询总数的statement中增加多个id输入查询。
sql语句如下:
两种方法:
SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
SELECT * FROM USER WHERE id IN(1,10,16)

.2 在输入参数类型中添加List ids传入多个id

<sql id="user_id">
        <if test="ids!=null">
        <!--使用foreach遍历传入ids
        collection:指定输入对象中集合属性
        item:每个遍历生成对象中
        open:结束遍历时拼接的串
        separator:遍历的两个对象中需要拼接的串
          -->
          <!--使用实现下边的sql拼接:and (id=1 or id=10 or id=16)  -->
            <foreach collection="ids" item="uid"  open="and (" close=")" separator="or">
                uid=#{uid}
            </foreach>
        </if>
    </sql>
    <sql id="user_id2">
        <if test="ids!=null">
        <!--使用foreach遍历传入ids
        collection:指定输入对象中集合属性
        item:每个遍历生成对象中
        open:结束遍历时拼接的串
        separator:遍历的两个对象中需要拼接的串
          -->
          <!--使用实现下边的sql拼接:and (id=1 or id=10 or id=16)  -->
            <foreach collection="ids" item="uid"  open="and uid in (" close=")" separator=",">
                #{uid}
            </foreach>
        </if>
    </sql>

    <!--在mapper.xml中定义的statement中引用sql片段:  -->
    <select id="findUserByIds" parameterType="mybatis.po.UserQueryVo" resultType="mybatis.po.UserCustom">
        select * from user
        <where>
            <!--引用sql片段的id,如果refid指定的id不在本mapper文件中,需要前边加载namespace  -->
            <include refid="user_id2"></include>
        </where>
    </select>

测试代码

@Test
    public void testFindUserByIds() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo=new UserQueryVo();
        List<Integer> ids=new ArrayList<Integer>();
        ids.add(1234276);
        ids.add(1234277);
        ids.add(1234279);
        userQueryVo.setIds(ids);
        //调用userMapper方法
        List<UserCustom> list=userMapper.findUserByIds(userQueryVo);
        System.out.println(list);
    }

mybatis中使用foreach构造多like查询及批量插入

使用foreach批量查询 SELECT * FROM goods_type WHERE 1>2 OR `NAME` LIKE CONCAT('%',#...
  • u012012240
  • u012012240
  • 2016-04-01 17:26:14
  • 4598

MyBatis实现模糊查询的几种方式

在学习MyBatis过程中想实现模糊查询,可惜失败了。后来上百度上查了一下,算是解决了。记录一下MyBatis实现模糊查询的几种方式。   数据库表名为test_student,初始化了几条记录,如图...
  • qq_40285302
  • qq_40285302
  • 2018-04-15 14:41:54
  • 13

Mybatis 示例之 foreach (上)

(由于csdn抽风,所以删除两篇重复内容重发) foreach一共有三种类型,分别为List,[](array),Map三种。 foreach的第一篇用来将List和数组(array)。 下面...
  • isea533
  • isea533
  • 2014-03-14 14:54:49
  • 75642

MyBatis的常用标签

1.where标签,重点!这里的if标签用来判断这些条件存不存在,存在就追加进sql语句进行查询,否则不追加 ...
  • jacksonary
  • jacksonary
  • 2017-05-22 13:26:47
  • 398

mybatis之动态sql总结

1.Mybatis的动态sql介绍 如果读者你之前玩过Jdbc相关的框架,你可能就会明白sql拼接的无奈,然后拼接成变量,作为参数传入再查询等等。动态sql的出现就是为了解决这个拼接的问题。动态sql...
  • ya_1249463314
  • ya_1249463314
  • 2016-12-18 11:32:49
  • 2810

MyBatis快速入门(三) 动态SQL

动态SQLMyBatis还有一个方便的功能就是动态SQL,可以根据条件智能生成SQL语句。这里的例子全部来自MyBatis文档。if标签下面这个例子使用了MyBatis的if元素,在标题不为空的情况下...
  • u011054333
  • u011054333
  • 2017-02-20 22:54:24
  • 925

Mybatis的动态SQL实现

一、动态SQL简介 MyBatis的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要...
  • xiaokang123456kao
  • xiaokang123456kao
  • 2017-03-27 17:08:29
  • 3881

Mybatis深入了解(五)----动态SQL

什么是动态SQL 实例 Mapperxml 测试代码 sql片段 定义sql片段 引用sql片段 foreach 应用场景 在输入参数类型中添加List ids传入多个id 修改Mapperxml ...
  • u010853701
  • u010853701
  • 2016-07-16 16:29:43
  • 1460

MyBatis——动态SQL讲解

MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。 MyBatis中用于实现动态SQL的元素主要有: if where set choose(when...
  • bear_wr
  • bear_wr
  • 2016-09-01 11:25:09
  • 11350

mybatis动态Sql(if-where)和sql片段

动态SQL可以极大地便利我们的综合查询: select * from user and username like '%${userCustom.use...
  • Dove_Knowledge
  • Dove_Knowledge
  • 2017-09-05 13:15:11
  • 416
收藏助手
不良信息举报
您举报文章:mybatis 动态sql
举报原因:
原因补充:

(最多只允许输入30个字)