Mybatis学习(4)输入映射、输出映射、动态sql
一、输入映射:
通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型
1) 传递pojo的包装对象
需求是:完成用户信息的综合查询,传入的查询条件复杂;(包括用户信息、其他信息等);
定义包装类型:
用户扩展类:
package com.cy.po; /**
*用户的扩展类
* @author chengyu
*
*/
public class UserCustom extends User{ }
视图层面的用户包装类型:
package com.cy.po; /**
* 用户的包装类型
* @author chengyu
*
*/
public class UserQueryVo {
//在这里包装所需要的查询条件 //用户查询条件
private UserCustom userCustom; //可以包装其它的查询条件,订单、商品
//.... public UserCustom getUserCustom() {
return userCustom;
} public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
}
}
mapper.xml:
<!-- 用户信息综合查询
#{userCustom.sex}:取出pojo包装对象中性别值
${userCustom.username}:取出pojo包装对象中用户名称
-->
<select id="findUserList" parameterType="com.cy.po.UserQueryVo" resultType="com.cy.po.UserCustom">
SELECT * FROM USER where sex = #{userCustom.sex} and username like '%${userCustom.username}%'
</select>
mapper.接口:
public interface UserMapper {
//用户信息综合查询
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
测试代码:
@Test
public void testFindUserList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setSex("1");
userCustom.setUsername("张三丰");
userQueryVo.setUserCustom(userCustom);
//调用userMapper的方法 List<UserCustom> list = userMapper.findUserList(userQueryVo); System.out.println(list);
}
二、输出映射、
1、resultType:
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
1) 输出简单类型: ----》》查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。
需求是,用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。
mapper.xml:
<!-- 用户信息综合查询总数
parameterType:指定输入类型和findUserList一样
resultType:输出结果类型
-->
<select id="findUserCount" parameterType="com.cy.po.UserQueryVo" resultType="int">
SELECT count(*) FROM USER where sex = #{userCustom.sex} and username like '%${userCustom.username}%'
</select>
mapper.java接口:
//用户信息综合查询总数
public int findUserCount(UserQueryVo userQueryVo) throws Exception;
juit测试代码:
//测试查询用户数
@Test
public void testFindUserCount() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setSex("1");
userCustom.setUsername("张三丰");
userQueryVo.setUserCustom(userCustom);
int count = userMapper.findUserCount(userQueryVo);
System.out.println(count);
}
2)输出pojo对象,和pojo对象列表:
不管是输出的pojo单个对象还是一个列表,在mapper.xml中resultType指定的类型是一样的。在mapper.java指定的方法返回值类型不一样;
输出单个pojo,返回值是这个pojo对象类型
输出pojo列表,返回值是List<pojo>
2.resultMap
mybatis中使用resultMap完成高级输出结果映射。如果查询出来的列名和pojo的属性名不一致,可以通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
使用方法啊:
1)定义resultMap
2)使用resultMap作为statement的输出映射类型
mapper.xml:
<!--使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址-->
<mapper namespace="com.cy.mapper.UserMapper"> <!-- 定义resultMap 将SELECT id id_,username username_ FROM USER 和User类中的属性作一个映射关系
type:resultMap最终映射的java对象类型,可以使用别名
id:对resultMap的唯一标识
-->
<resultMap type="com.cy.po.User" id="userResultMap">
<!-- id表示查询结果集中唯一标识 column:查询出来的列名 property:type指定的pojo类型中的属性名-->
<id column="id_" property="id"/> <!-- result:对普通名映射定义 column:查询出来的列名 property:type指定的pojo类型中的属性名 -->
<result column="username_" property="username"/>
</resultMap> <!-- 使用resultMap进行输出映射
resultMap:指定定义的resultMap的id,如果这个resultMap在其它的mapper文件,前边需要加namespace
-->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
SELECT id id_,username username_ FROM USER WHERE id=#{value}
</select>
</mapper>
mapper接口:
//根据id查询用户信息,使用resultMap输出
public User findUserByIdResultMap(int id) throws Exception;
juittest代码:
@Test
public void testFindUserByIdResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findUserByIdResultMap(1);
System.out.println(user);
}
3.自己做的实验,输入类型和传出类型都为java.util.Map:
<!-- 查看resultMap的使用 java.util.Map
传入参数为hashmap id和username都为map的key
-->
<select id="findUserByIdDefaultMap" parameterType="java.util.Map" resultType="java.util.Map">
SELECT * FROM USER where id=#{id} and username like '%${username}%'
</select>
并且java.util.Map在mybatis中的别名是hashmap,写成这样,效果一样的:
<select id="findUserByIdDefaultMap" parameterType="hashmap" resultType="hashmap">
SELECT * FROM USER where id=#{id} and username like '%${username}%'
</select>
mapper接口:
//find user parameterMap and resultMap both are java.uti.Map
public Map<String, String> findUserByIdDefaultMap(Map<String, String> parmas) throws Exception;
测试代码:
@Test
public void testfindUserByIdDefaultMap() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); Map<String ,String> params = new HashMap<String, String>();
params.put("id", "25");
params.put("username", "小明");
Map<String, String> user = userMapper.findUserByIdDefaultMap(params);
System.out.println(user);
}
打印结果:
DEBUG [main] - ==> Preparing: SELECT * FROM USER where id=? and username like '%小明%'
DEBUG [main] - ==> Parameters: 25(String)
DEBUG [main] - <== Total: 1
{id=25, sex=1, username=陈小明, address=河南郑州}
三、动态sql
mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。
例子1:
需求: 对上面程序中的 用户信息综合查询列表这个statement使用动态sql,对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。
mapper.xml:
<!-- 用户信息综合查询
#{userCustom.sex}:取出pojo包装对象中性别值
${userCustom.username}:取出pojo包装对象中用户名称
-->
<select id="findUserList" parameterType="com.cy.po.UserQueryVo" resultType="com.cy.po.UserCustom">
SELECT * FROM USER <!-- where可以自动去掉条件中的第一个and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and sex = #{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
</if>
</where>
</select>
测试代码:
@Test
public void testFindUserList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom(); //动态sql的存在,不设置某个值,条件不会拼接在sql中
//userCustom.setSex("1");
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom); List<UserCustom> list = userMapper.findUserList(userQueryVo);
System.out.println(list);
}
打印:
DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE username like '%小明%'
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
[------->> User [id=16, username=张小明, sex=1, birthday=null, address=河南郑州], ------->> User [id=22, username=陈小明, sex=1, birthday=null, address=河南郑州], ------->> User [id=25, username=陈小明, sex=1, birthday=null, address=河南郑州]]
2)sql片段:
将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。
mapper.xml:----定义sql片段、引用sql片段:
<mapper namespace="com.cy.mapper.UserMapper">
<!-- 定义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 sex = #{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
</if>
</sql>
<!-- 用户信息综合查询
#{userCustom.sex}:取出pojo包装对象中性别值
${userCustom.username}:取出pojo包装对象中用户名称
-->
<select id="findUserList" parameterType="com.cy.po.UserQueryVo" resultType="com.cy.po.UserCustom">
SELECT * FROM USER
<where>
<!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
<include refid="query_user_where"></include>
</where>
</select>
</mapper>
3)使用foreach标签:
向sql传递数组或List,mybatis使用foreach解析;
需求:在用户查询列表的statement中增加多个id输入查询。
输入参数类型UserQueryVo中添加ids List,根据这个list查:
package com.cy.po; import java.util.List; /**
* 用户的包装类型
* @author chengyu
*
*/
public class UserQueryVo {
//在这里包装所需要的查询条件 private List<Integer> ids; //用户查询条件
private UserCustom userCustom; //可以包装其它的查询条件,订单、商品
//.... public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public UserCustom getUserCustom() {
return userCustom;
}
public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
}
}
mapper.xml:
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and sex = #{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
<if test="ids!=null">
<!-- 使用 foreach遍历传入ids
collection:指定输入 对象中集合属性
item:每个遍历生成对象中
open:开始遍历时拼接的串
close:结束遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
--> <!-- AND (id=1 OR id=10 OR id=16)-->
<foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
id=#{user_id}
</foreach> <!-- and id IN(1,10,16) -->
<!-- <foreach collection="ids" item="user_id" open="and id in(" close=")" separator=",">
#{user_id}
</foreach> -->
</if>
</if>
</sql> <!-- 用户信息综合查询
#{userCustom.sex}:取出pojo包装对象中性别值
${userCustom.username}:取出pojo包装对象中用户名称
-->
<select id="findUserList" parameterType="com.cy.po.UserQueryVo" resultType="com.cy.po.UserCustom">
SELECT * FROM USER
<where>
<!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
<include refid="query_user_where"></include>
</where>
</select>
测试代码:
@Test
public void testFindUserList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom(); //动态sql的存在,不设置某个值,条件不会拼接在sql中
//userCustom.setSex("1");
userCustom.setUsername("小明"); //传入多个id
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(10);
ids.add(16);
userQueryVo.setIds(ids);
userQueryVo.setUserCustom(userCustom); List<UserCustom> list = userMapper.findUserList(userQueryVo);
System.out.println(list);
}
可以看打印结果拼接的sql:
DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE username like '%小明%' and ( id=? or id=? or id=? )
DEBUG [main] - ==> Parameters: 1(Integer), 10(Integer), 16(Integer)
DEBUG [main] - <== Total: 1
[------->> User [id=16, username=张小明, sex=1, birthday=null, address=河南郑州]]
Mybatis学习(4)输入映射、输出映射、动态sql的更多相关文章
- 【Mybatis架构】输入、输出映射
前言综述: 其实在我们分析Mybatis的查询缓存或者是一些简介的时候,我们就不难看到有关于Mybatis输入输出映射的东西,比如说: 但是一直没有想起来系统的来总结一下这方面的相关知识,偶然看到 ...
- Mybatis学习笔记(四) 之动态SQL语句
动态SQL mybatis 的动态sql语句是基于OGNL表达式的.可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类: 1. if 语句 (简单的条件 ...
- (转)MyBatis框架的学习(四)——Mapper.xml文件中的输入和输出映射以及动态sql
http://blog.csdn.net/yerenyuan_pku/article/details/71893689 前面对MyBatis框架的学习中,我们对Mapper.xml映射文件多少有些了解 ...
- JAVAEE——Mybatis第二天:输入和输出映射、动态sql、关联查询、Mybatis整合spring、Mybatis逆向工程
1. 学习计划 1.输入映射和输出映射 a) 输入参数映射 b) 返回值映射 2.动态sql a) If标签 b) Where标签 c) Sql片段 d) Foreach标签 3.关联查询 a) 一对 ...
- MyBatis基础入门《二十》动态SQL(foreach)
MyBatis基础入门<二十>动态SQL(foreach) 1. 迭代一个集合,通常用于in条件 2. 属性 > item > index > collection : ...
- MyBatis基础入门《十九》动态SQL(set,trim)
MyBatis基础入门<十九>动态SQL(set,trim) 描述: 1. 问题 : 更新用户表数据时,若某个参数为null时,会导致更新错误 2. 分析: 正确结果: 若某个参数为nul ...
- MyBatis基础入门《十八》动态SQL(if-where)
MyBatis基础入门<十八>动态SQL(if-where) 描述: 代码是在<MyBatis基础入门<十七>动态SQL>基础上进行改造的,不再贴所有代码,仅贴改动 ...
- mybatis学习记录四——输入、输出映射
6 输入映射 通过parameterType指定输入参数的类型,类型可以是简单类型.hashmap.pojo的包装类型. 6.1.1 需求 完成用户信息的综合查询,需要传入查询条件很 ...
- Mybatis学习第三天——输入输出映射以及动态SQL
注意:以下传入数据与输出数据类型部分使用别名的方式,别名在SqlMapConfig.xml核心文件中配置 1.输入映射 1.1 传递简单数据类型 1.2 传递pojo中的类类型 1.3 传递Query ...
- mybatis 输入、输出映射
一.输入映射 mapper.xml的参数只有一个.可以传参数,基本简单类型,hashmap和javabean (一).Javabean的方法. 需求:通过小说名和作者模糊找书. 1.定义Javabea ...
随机推荐
- 源代码管理:SVN源代码管理器在ASP.NET VS中的使用注意事项
一共有三个软件 1.ASP.NET下SVN有三个是不受管理的,bin文件夹,obj文件夹,.user类型文件,位置在TortoiseSVN的Settings下面的Subversion下的[Global ...
- 触电(by quqi99)
高压电线杆相关的触电方式主要是两种: 一是跨步电压,高压电线落在地面时,如果人恰好在这个范围内步行时,就会从一只脚到跨下再到另一只脚到地形成回路,这叫跨步电压.步子越大,电压越大(以落地点为圆心向外电 ...
- JavaWeb中监听器+过滤器+拦截器区别、配置和实际应用
JavaWeb中监听器+过滤器+拦截器区别.配置和实际应用 1.前沿上一篇文章提到在web.xml中各个元素的执行顺序是这样的,context-param-->listener-->fil ...
- CentOS7.5最小化安装与初始化配置(做标准化)
本文分享CentOS的标准化安装配置方法,方便集群批量装机配置 ------------------------- 完美的分割线 ---------------------------- 1.安装标准 ...
- UnicodeDammit
UnicodeDammit 是BS内置库, 主要用来猜测文档编码. 编码自动检测 功能可以在Beautiful Soup以外使用,检测某段未知编码时,可以使用这个方法: from bs4 import ...
- Tomcat下JSP、Servlet和JavaBean环境的配置
经常看到jsp的初学者问tomcat下如何配置jsp.servlet和bean的问题,于是总结了一下如何tomcat下配置jsp.servlet和ben,希望对那些初学者有所帮助. 第一步:下载j2s ...
- test20190408(十二省联考)
做了十二省联考的题.暂时只更几个比较可做的题目. 异或粽子 考试的时候乱搞了个做法.结果以每个大数据点 \(1900+\ ms\) 的优秀效率通过了此题... 乱搞 建一颗 \(Trie\) 树,显然 ...
- POJ 2312:Battle City(BFS)
Battle City Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9885 Accepted: 3285 Descr ...
- Django Rest FrameWork 全部API
Django Rest FrameWork .Requests 请求 客服端发送给服务器的请求 .Responses 响应 rest框架支持响应不同格式的内容 .Views 视图 base基础类视图 ...
- matplotlib 双y轴绘制及合并图例
关键函数:twinx() refer to: https://www.cnblogs.com/Atanisi/p/8530693.html