Mybatis-动态sql
来源:互联网 发布:苏州2017打车软件 编辑:程序博客网 时间:2024/05/18 01:49
动态sql在Mybatis中是很重要的东西,通过动态sql,我们可以更直观的进行编程,同时,对于修改代码也要相对简捷
一些;动态sql主要包括:sql片段、IF、Where、foreach等内容,下面通过实例进行讲解。
Sql片段
在Mybatis中进行sql的编写时,我们习惯于将sql不加任何条件的写在一起,即完成一天单纯的Sql语句。如下所示:
<!-- 用户信息的综合查询#{userCustom.sex}:取出pojo包装对象中sex的数据${userCustom.username}:取出包装对象中用户的名称 --><select id="findUserList" parameterType="com.sw.po.UserQueryVo" resultType="com.sw.po.UserCustom">select *from user user.sex=#{userCustom.sex} and user.username like '%${userCustom.username}%'</select>
但是在实际开发中,这并不适用,因为在sql语句中存在的一些变量,我们并没有做任何规范以及判断就进行sql的执行,这是不正确的;所以我们
需要对sql语句中的一些变量以及字段做出一定的规范与判断,如下所示:
<!-- 用户信息的综合查询#{userCustom.sex}:取出pojo包装对象中sex的数据${userCustom.username}:取出包装对象中用户的名称 --><select id="findUserList" parameterType="com.sw.po.UserQueryVo" resultType="com.sw.po.UserCustom">select *from user<!-- where可以自动去掉条件中的第一个and --><where><!-- 使用动态sql,当输入参数不为空时才执行sql --><if test="userCustom!=null"><!-- 判断userCustom.sex --><if test="userCustom.sex!=null and userCustom.sex!=''">and user.sex=#{userCustom.sex}</if><!-- 判断userCustom.username --><if test="userCustom.username!=null and userCustom.username!=''">and user.username like '%${userCustom.username}%'</if></if></where></select>
经过改进,我们在sql语句中加入了IF与where判断,但是经过观察不难发现,这样的Sql未免太过于繁杂,同时,这些IF也会存在于其他Sql语句中,于是Mybatis为我们提供了Sql片段抽出与Sql引用;我们可以将相同的Sql代码抽取出来,进而在其他Sql语句中继续引用,如下所示:
抽取Sql:
<!-- 定义sql片段id:sql片段的唯一标识注意:一般定义sql片段是定义单表定义的,这样可增加sql片段的可重用性在sql片段中建议不包括where条件 --><sql id="query_user_where"><!-- 使用动态sql,当输入参数不为空时才执行sql --><if test="userCustom!=null"><!-- 判断userCustom.sex --><if test="userCustom.sex!=null and userCustom.sex!=''">and user.sex=#{userCustom.sex}</if><!-- 判断userCustom.username --><if test="userCustom.username!=null and userCustom.username!=''">and user.username like '%${userCustom.username}%'</if></if></sql>
引用Sql片段:
<!-- 用户信息的综合查询#{userCustom.sex}:取出pojo包装对象中sex的数据${userCustom.username}:取出包装对象中用户的名称 --><select id="findUserList" parameterType="com.sw.po.UserQueryVo" resultType="com.sw.po.UserCustom">select *from user<!-- where可以自动去掉条件中的第一个and --><where><!-- 使用动态sql,当输入参数不为空时才执行sql --><!-- 引用sql代码片段 --><include refid="query_user_where"/></where></select>
foreach标签
在Mybatis开发中,我们常常需要向Sql传入集合(List)或者是数组,那么这就需要用到foreach标签,如下Sql语句:
SELECT * FROM USERS WHERE username LIKE '%王%' AND (id =10 OR id =89 OR id=16)SELECT * FROM USERS WHERE username LIKE '%王%' id IN (10,89,16)
如上Sql所示,我们需要向Sql中传入一些列Id的值,集合或者是数组,接下来通过下面实例进一步了解:
在这里,我们可以将其分为:通过pojo传入list、传递单个list、传递单个数组(数组中包含pojo)、传递单个数组(数组中为字符串类型)
下面我们进行分别讲解:
通过pojo传递list
(1)定义pojo对象用于存放List(多个用户id)
package com.sw.po;import java.util.List;/* *@Author swxctx *@time 2016年12月2日 *@Explain:包装所需要的查询条件(亦可包装其他对象的查询信息)-包装类型 */public class UserQueryVo {//传入多个idprivate List<Integer> ids;//用户查询条件private UserCustom userCustom;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;}}
其他pojo:
package com.sw.po;/* *@Author swxctx *@time 2016年12月2日 *@Explain:User类的扩展类 */public class UserCustom extends User{//可以扩展用户的信息}
用户表的pojo对象这里不做介绍。
(2)配置mapper.xml文件
<!-- 用户信息的综合查询#{userCustom.sex}:取出pojo包装对象中sex的数据${userCustom.username}:取出包装对象中用户的名称 --><select id="findUserList" parameterType="com.sw.po.UserQueryVo" resultType="com.sw.po.UserCustom">select *from user<!-- where可以自动去掉条件中的第一个and --><where><!-- 使用动态sql,当输入参数不为空时才执行sql --><!-- 引用sql代码片段 --><include refid="query_user_where"/><if test="ids!=null"><!-- (id=27 OR id=32 OR id=34)使用foreah遍历传入的多个id(条件值)collection:指定输入对象中的集合属性item:每个遍历对象名open:开始遍历时需要拼接的字符串close:结束遍历时需要拼接的字符串separator:遍历的两个对象中间需要拼接的串 --><foreach collection="ids" item="user_id" open="and (" close=")" separator="or"><!-- 每个遍历需要拼接的串 -->id=#{user_id}</foreach></if></where></select>
(3)测试代码
package com.sw.mapper.test;import java.io.InputStream;import java.util.ArrayList;import java.util.Date;import java.util.List;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import com.sw.mapper.UserMapper;import com.sw.po.User;import com.sw.po.UserCustom;import com.sw.po.UserQueryVo;/* *@Author swxctx *@time 2016年12月1日 *@Explain: */public class UserMapperTest { private SqlSessionFactory sqlSessionFactory;@Beforepublic void setUpBefore() throws Exception {//执行其他方法前需要创建SqlSessionFactory// mybatis配置文件String resource = "SqlMapConfig.xml";// 得到配置文件流InputStream inputStream = Resources.getResourceAsStream(resource);// 创建会话工厂,传入mybatis的配置文件信息sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} //用户信息的综合查询 @Test public void testFindUserList() throws Exception{ SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //创建包装对象,设置查询条件 UserQueryVo userQueryVo = new UserQueryVo(); UserCustom userCustom = new UserCustom(); //传入多个id List<Integer> ids = new ArrayList<Integer>(); ids.add(30); ids.add(33); ids.add(34); userCustom.setSex("1"); userCustom.setUsername("王"); //将ids传入statement userQueryVo.setIds(ids); userQueryVo.setUserCustom(userCustom); //调用UserMapper方法 List<UserCustom> list = userMapper.findUserList(userQueryVo); sqlSession.close(); System.out.println(list); }}
传递单个List
在上面通过pojo传递list的讲解中,我们知道,我们需要在pojo中定义List用于存放需要传递的值;但是在这里,则仅仅只是有这一点差别,传递单个List并不需要我们在pojo对象中对齐进行定义,只需要在mapper.xml中将collection的值设置为list即可。回顾一下,在上面的例子中,我们传入的是ids(即pojo对象中定义的List)。那么很显然的,他们的区别也就展现出来了,这里自己观察进行理解,即可掌握两种传递方式。
那么下面我们通过具体的例子来看一下:
(1)Mapper.xml文件配置
<select id="selectUserByList" parameterType="java.util.List" resultType="user">select * from user <where><!-- 传递List,List中是pojo --><if test="list!=null"><foreach collection="list" item="item" open="and id in("separator=","close=")"> #{item.id} </foreach></if></where></select>
(2)测试代码
Public void testselectUserByList()throws Exception{//获取sessionSqlSession session = sqlSessionFactory.openSession();//获取mapper接口实例UserMapper userMapper = session.getMapper(UserMapper.class);//查询条件ListList<User> userlist = new ArrayList<User>();User user = new User();user.setId(1);userlist.add(user);user = new User();user.setId(2);userlist.add(user); //传递userlist列表查询用户列表List<User>list = userMapper.selectUserByList(userlist);//释放资源session.close();}
传递单个数组
其实善于观察的同学可以发现,数组(array)与集合(List)其实在开发方式使一样的,只是在这里我们将多个传入的值定义为一个数组。
下面通过例子进行理解:
(1)mapper.xml配置文件的配置
<!-- 传递数组综合查询用户信息 --><select id="selectUserByArray" parameterType="Object[]" resultType="user">select * from user <where><!-- 传递数组 --><if test="array!=null"><foreach collection="array" index="index" item="item" open="and id in("separator=","close=")"> #{item.id} </foreach></if></where></select>
针对上面的一些标签做出说明:
sql只接收一个数组参数,这时sql解析参数的名称mybatis固定为array,如果数组是通过一个pojo传递到sql则参数的名称为pojo中的属性名。index:为数组的下标。item:为数组每个元素的名称,名称随意定义open:循环开始close:循环结束separator:中间分隔输出
(2)测试类
Public void testselectUserByArray()throws Exception{//获取sessionSqlSession session = sqlSessionFactory.openSession();//获取mapper接口实例UserMapper userMapper = session.getMapper(UserMapper.class);//查询条件ListObject[] userlist = new Object[2];User user = new User();user.setId(1);userlist[0]=user;user = new User();user.setId(2);userlist[1]=user;//传递user对象查询用户列表List<User>list = userMapper.selectUserByArray(userlist);//释放资源session.close();}
同样的,数组与List有着相似之处,现在的数组是直接传入的,那么同样也可以将其定义在pojo对象中,这里不做讲解,克通过上述三个例子对数组进行进一步的学习。
同时,这里有很多细节没有注意,例如定义mapper接口等,这里忽略了这些细节,旨在讲解foreach的配置。
如有雷同,纯属巧合,请多多指教。
- mybatis动态SQL语句
- MyBatis动态SQL
- MyBatis 动态SQL
- Mybatis 动态SQL
- MyBatis动态SQL
- MyBatis动态SQL完整版
- mybatis动态sql
- mybatis动态SQL语句
- mybatis动态SQL语句
- MyBatis的动态SQL
- MyBatis动态SQL
- MyBatis动态SQL
- MyBatis 动态SQL语句
- MyBatis动态SQL
- Mybatis组建动态SQL
- MyBatis 动态sql
- mybatis 动态SQL语句
- MyBatis动态SQL详解
- android开发艺术探索第三章 移动到指定位置和内外两种情况拦截分析
- 支持向量机通俗导论(理解SVM的三层境界)
- Unity3D MineCraft 使用Unity3D制作MineCraft 我的世界 存盘和读取问题解决
- HTML 基本格式
- 数据特征选择
- Mybatis-动态sql
- 第三天
- Windows环境下QT学习笔记01:QT Creator下新建项目
- React Native学习笔记之--图片的加载
- kafka环境搭建1-单机版
- 一.简单批处理内部命令简介
- 数据特征选择
- Android开发 创建桌面图标和widget的示例
- 博客开篇啦