【java-mybaits-00402-Mapper-动态sql】知识为进步之母,而进步又为富强之源泉。这篇文章主要讲述java-mybaits-00402-Mapper-动态sql相关的知识,希望能为你提供帮助。
java-mybaits-00402-Mapper-动态sql-if、where、foreach、sql片段1、动态sql(重点)
通过mybatis提供的各种标签方法实现动态拼接sql。
什么是动态sql
mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。
需求
用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。
对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。1.1、If
< !-- 传递pojo综合查询用户信息 --> < select id="findUserList" parameterType="user" resultType="user"> select * from user where 1=1 < if test="id!=null and id!=\'\'"> and id=#{id} < /if> < if test="username!=null and username!=\'\'"> and username like \'%${username}%\' < /if> < /select>
注意要做不等于空字符串校验。 注意直接是属性,不用类名.属性1.2、Where
上边的sql也可以改为:
< select id="findUserList" parameterType="user" resultType="user"> select * from user < where> < if test="id!=null and id!=\'\'"> and id=#{id} < /if> < if test="username!=null and username!=\'\'"> and username like \'%${username}%\' < /if> < /where> < /select>
< where /> 可以自动处理第一个and。1.3、foreach
向sql传递数组或List,mybatis使用foreach解析,collection:表示传入过来的参数的数据类型。该参数为必选。要做 foreach 的对象,作为入参时,List 对象默认用 list 代替作为键,数组对象有 array 代替作为键,Map 对象没有默认的键。当然在作为入参时可以使用 @Param(“keyName”) 来设置键,设置 keyName 后,list,array 将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:
如果 User 有属性 List ids。入参是 User 对象,那么这个 collection = “ids” 如果 User 有属性 Ids ids; 其中 Ids 是个对象,Ids 有个属性 List id; 入参是 User 对象,那么 collection = “ids.id”
如果传入的是单参数且参数类型是一个 List 的时候,collection 属性值为 list
如果传入的是单参数且参数类型是一个 array 数组的时候,collection 的属性值为 array
如果传入的参数是多个的时候,我们就需要把它们封装成一个 Map 了,当然单参数也可以封装成 map。
item: 循环体中的具体对象。支持属性的点路径访问,如 item.age,item.info.details。具体说明:在 list 和数组中是其中的对象,在 map 中是 value,该参数为必选。(它是每一个元素进行迭代时的别名)
index:在 list 和数组中,index 是元素的序号;在 map 中,index 是元素的 key。
open:表示该语句以什么开始
close:表示该语句以什么结束
separator:表示在每次进行迭代之间以什么符号作为分隔符
如下: 1.3.1、通过pojo传递list
- 需求
- 在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法
文章图片
mapper.xml
< if test="ids!=null and ids.size> 0"> < foreach collection="ids" open=" and id in(" close=")" item="id" separator="," > #{id} < /foreach> < /if>
测试代码:
List< Integer> ids = new ArrayList< Integer> (); ids.add(1); //查询id为1的用户 ids.add(10); //查询id为10的用户 queryVo.setIds(ids); List< User> list = userMapper.findUserList(queryVo);
1.3.2、传递单个List 传递List类型在编写mapper.xml没有区别,唯一不同的是只有一个List参数时它的参数名为list。 如下:mapper.xml
< select id="selectUserByList" parameterType="java.util.List" resultType="com.lhx.mybatis.po.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>
mapper接口
public List< User> selectUserByList(List< User> userlist) throws Exception;
测试类
public void testselectUserByList() throws Exception { // 获取session SqlSession session = sqlSessionFactory.openSession(); // 获限mapper接口实例 UserMapper userMapper = session.getMapper(UserMapper.class); // 构造查询条件List List< 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); System.out.println(list.size()+""); // 关闭session session.close(); }
1.3.3、传递单个数组(数组中是pojo):mapper.xml
< !-- 传递数组综合查询用户信息 --> < select id="selectUserByArrayPojo" parameterType="Object[]" resultType="com.lhx.mybatis.po.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>
mapper接口
public List< User> selectUserByArrayPojo(Object[] userlist) throws Exception;
测试代码
public void testselectUserByArray() throws Exception { // 获取session SqlSession session = sqlSessionFactory.openSession(); // 获限mapper接口实例 UserMapper userMapper = session.getMapper(UserMapper.class); // 构造查询条件List Object[] 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.selectUserByArrayPojo(userlist); // 关闭session session.close(); }
1.3.4、传递单个数组(数组中是字符串类型):mapper.xml
< !-- 传递数组综合查询用户信息 --> < select id="selectUserByArray" parameterType="Object[]" resultType="com.lhx.mybatis.po.User"> select * from user < where> < !-- 传递数组 --> < if test="array!=null"> < foreach collection="array" index="index" item="item" open="and id in(" separator="," close=")"> #{item} < /foreach> < /if> < /where> < /select>
mapper接口
public List< User> selectUserByArray(Object[] userlist) throws Exception;
测试代码
public void testselectUserByArray() throws Exception { // 获取session SqlSession session = sqlSessionFactory.openSession(); // 获限mapper接口实例 UserMapper userMapper = session.getMapper(UserMapper.class); // 构造查询条件List Object[] userlist = new Object[2]; userlist[0] = "1"; userlist[1] = "2"; // 传递user对象查询用户列表 List< User> list = userMapper.selectUserByArray(userlist); // 关闭session session.close(); }
1.4、Sql片段
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,方便程序员进行开发如下:
< !-- 传递pojo综合查询用户信息 --> < select id="findUserList" parameterType="user" resultType="user"> select * from user < where> < if test="id!=null and id!=\'\'"> and id=#{id} < /if> < if test="username!=null and username!=\'\'"> and username like \'%${username}%\' < /if> < /where> < /select>
将where条件抽取出来
< sql id="query_user_where"> < if test="id!=null and id!=\'\'"> and id=#{id} < /if> < if test="username!=null and username!=\'\'"> and username like \'%${username}%\' < /if> < /sql>
使用include引用
< select id="findUserList" parameterType="user" resultType="user"> select * from user < where> < include refid="query_user_where"/> < /where> < /select>
注意: 1.如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下: < include refid="namespace.sql片段”/> 2.经验,是基于单表定有的sql片段,这样sql可重用性高 3.一般不添加where,方便引用多个片段
推荐阅读
- Ghostwindows10纯净版下载
- 二维码识别之Android完整编译Zbar
- 解决Android Studio卡在Gradle:Resolve dependecies 'app:_debugCompile'问题
- IDA远程调试Android
- unity 与android交互
- 在manifest中添加权限和在untiy中android的sd卡的根目录
- [转]Entity Framework Fluent API - Configuring and Mapping Properties and Types
- Android handler 报错处理Can't create handler inside thread that has not called Looper.prepare()(示例代码
- Android SQLit数据库学习