Mybatis之旅第四篇-输入输出映射
一、引言
在日常开发用到mybatis时,因为实际的开发业务场景很复杂,不论是输入的查询条件,还是返回的结果,经常是需要根据业务来定制,这个时候我们就需要自己来定义一些输入和输出映射
二、parameterType(输入映射)
输入映射是在映射文件中通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型,当我们去查询用户时,有些字段基本不会用作查询条件,还有一些时候我们需要连表查询,那么这个时候我们可以用到包装类。
新建pojo包,定义包装类:
public class QueryVo {
//pojo
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
将UserMapper.xml文件移至com.yuanqinnan.mapper包中,并增加一个查询方法
<select id="queryByQo" parameterType="com.yuanqinnan.pojo.QueryVo" resultType="com.yuanqinnan.model.User">
SELECT * from user where username like '%${user.username}%'
</select>
UserMapper中增加接口:
List<User> queryByQo(QueryVo queryVo);
结构如图:

将SqlMapConfig.xml 中其他的配置恢复原先配置,引入mapper方式进行修改
<mappers>
<package name="com.yuanqinnan.mapper"/>
</mappers>
测试方法:
@Test
public void testQueryUserByUsername2() {
// 获取sqlSession,和spring整合后由spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 从sqlSession中获取Mapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行查询方法
QueryVo queryVo=new QueryVo();
User user=new User();
user.setUsername("张");
queryVo.setUser(user);
List<User> list = userMapper.queryByQo(queryVo);
for (User user2 : list) {
System.out.println(user2);
} // 和spring整合后由spring管理
sqlSession.close();
}
原以为会很顺利的出现结果,结果一直报错:invalid bound statement (not found),这个错误是找不到相应sql,可是明明路径和sql都是对的,最后竟然发现是需要在pom.xml文件中配置resource,不然mapper.xml文件就会被漏掉,这种错误真是太恼火了,pom加上配置:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
得到测试结果:

输入映射比较简单,一般不会使用包装类,而是根据需要的条件去设置字段比较好
三、resultType(输出类型)
输出类型有简单类型,pojo类,pojo列表,pojol类和列表在前面的例子中都有演示,下面看一个简单类型的
新增方法:
<select id="queryUserCount" resultType="int">
select count(*) from user
</select>
接口:
int queryUserCount();
测试:
@Test
public void testQueryUserCount() {
// 获取sqlSession,和spring整合后由spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 从sqlSession中获取Mapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行查询方法
int count= userMapper.queryUserCount() ;
System.out.println(count); // 和spring整合后由spring管理
sqlSession.close();
}
结果:10
四、resultMap
resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
下面通过例子来说明:
先新增一张订单表,sql如下:
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '下单用户id',
`number` varchar(32) NOT NULL COMMENT '订单号',
`createtime` datetime NOT NULL COMMENT '创建订单时间',
`note` varchar(100) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
KEY `FK_order_1` (`user_id`),
CONSTRAINT `FK_order_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of order
-- ----------------------------
INSERT INTO `order` VALUES ('', '', '', '2015-02-04 13:22:35', null);
INSERT INTO `order` VALUES ('', '', '', '2015-02-03 13:22:41', null);
INSERT INTO `order` VALUES ('', '', '', '2015-02-12 16:13:23', null);
实体:
public class Order {
// 订单id
private int id;
// 用户id
private Integer userId;
// 订单号
private String number;
// 订单创建时间
private Date createtime;
// 备注
private String note;
public int getId() {
return id;
}
public Integer getUserId() {
return userId;
}
public String getNumber() {
return number;
}
public Date getCreatetime() {
return createtime;
}
public String getNote() {
return note;
}
public void setId(int id) {
this.id = id;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public void setNumber(String number) {
this.number = number;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public void setNote(String note) {
this.note = note;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", userId=" + userId +
", number='" + number + '\'' +
", createtime=" + createtime +
", note='" + note + '\'' +
'}';
}
}
新增OrderMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuanqinnan.mapper.OrderMapper">
<!-- 查询所有的订单数据 -->
<select id="queryOrderAll" resultType="com.yuanqinnan.model.Order">
SELECT id, user_id,
number,
createtime, note FROM `order`
</select>
</mapper>
新增OrderMapper接口
public interface OrderMapper {
List<Order> queryOrderAll();
}
测试:
@Test
public void testQueryAll() {
// 获取sqlSession
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 获取OrderMapper
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); // 执行查询
List<Order> list = orderMapper.queryOrderAll();
for (Order order : list) {
System.out.println(order);
}
}
结构如图:

结果:

发现userId为null,用resultMap解决,修改OrderMapper.xml,定义resultMap
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuanqinnan.mapper.OrderMapper">
<!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo -->
<!-- id:设置ResultMap的id -->
<resultMap type="com.yuanqinnan.model.Order" id="orderResultMap">
<!-- 定义主键 ,非常重要。如果是多个字段,则定义多个id -->
<!-- property:主键在pojo中的属性名 -->
<!-- column:主键在数据库中的列名 -->
<id property="id" column="id" />
<!-- 定义普通属性 -->
<result property="userId" column="user_id" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
</resultMap> <!-- 查询所有的订单数据 -->
<select id="queryOrderAll" resultType="com.yuanqinnan.model.Order">
SELECT id, user_id,
number,
createtime, note FROM `order`
</select> <select id="queryOrderAll2" resultMap="orderResultMap">
SELECT id, user_id,
number,
createtime, note FROM `order`
</select>
</mapper>
增加接口:
List<Order> queryOrderAll2();
测试方法:
@Test
public void testQueryAll2() {
// 获取sqlSession
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 获取OrderMapper
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); // 执行查询
List<Order> list = orderMapper.queryOrderAll2();
for (Order order : list) {
System.out.println(order);
}
}
结果:

Mybatis之旅第四篇-输入输出映射的更多相关文章
- Mybatis之旅第三篇-SqlMapConfig.xml全局配置文件解析
一.前言 刚换工作,为了更快的学习框架和了解业务,基本每天都会加班,导致隔了几天没有进行总结,心里总觉得不安,工作年限越长越感到学习的重要性,坚持下去!!! 经过前两篇的总结,已经基本掌握了mybat ...
- SpringBoot之旅第四篇-web开发
一.引言 有了自动配置,springboot使web开发变得简单,这个在springboot之旅中的第一篇中就有体现,实际的开发中当然不会这么简单,很多时候我们都需要自己去定制一些东西.web开发的东 ...
- 深入理解MyBatis的原理(四):映射器的用法
前言:继续深入学习 mybatis 的用法及原理,还是先会用再学习原理. 映射器的主要元素有:select.insert.update.delete.parameterMap(即将被删除,不建议使用) ...
- Mybatis之旅第六篇-关联查询
一.引言 通过动态SQL我们可以进行复杂SQL的编写,但之前的例子都是单表查询,在实际开发中,当然不可能都是单表,很多时候我们需要进行关联多表查询(有些公司为了性能还是尽量的使用单表查询),表与表之间 ...
- Mybatis学习总结(四)——输入映射和输出映射
在前面几篇文章的例子中也可以看到mybatis中输入映射和输出映射的身影,但是没有系统的总结一下,这篇博客主要对这两个东东做一个总结.我们知道mybatis中输入映射和输出映射可以是基本数据类型.ha ...
- Mybatis之旅第五篇-动态SQL
一.引言 在之前的CRUD例子中,都是一些很简单的SQL,然而实际的业务开发中会有一些复杂的SQL,我们经常需要拼接SQL,拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号.Myba ...
- Spring之旅第四篇-注解配置详解
一.引言 最近因为找工作,导致很长时间没有更新,找工作的时候你会明白浪费的时间后面都是要还的,现在的每一点努力,将来也会给你回报的,但行好事,莫问前程!努力总不会有错的. 上一篇Spring的配置博客 ...
- MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射
在上一章中我们学习了<MyBatis学习总结(一)——ORM概要与MyBatis快速起步>,这一章主要是介绍MyBatis核心配置文件.使用接口+XML实现完整数据访问.输入参数映射与输出 ...
- Mybatis输入输出映射_动态sql_关联关系(一对一、一对多、多对多)
Mybatis输入输出映射_动态sql_关联关系(一对一.一对多.多对多)输入输出映射parameterType完成输入映射parameterType可以传入的参数有,基本数据类型(根据id查询用户的 ...
随机推荐
- sed、awk——运维必须掌握的两个工具
今天主要跟大家介绍2个非常霸道的工具,sed和awk,本篇文章将介绍这两个工具在日常运维中的常用用法,工作中这两个工具要掌握好了在结合一些管道命令.正则表达式,日常处理事务简直666啦! l Sed ...
- github 用git bash上传项目 最后提示 Everything up-to-date 但没传上去
今天为了把本地的项目远程到githup远程仓库,把好久不用的githup命令重新用了起来,不用怀疑,很正常的出错了. 为了长点记性,总结错误与解决办法如下: 1.我犯得第一个简单错误,是忘了git c ...
- 关于Random(47)与randon.nextInt(100)的区别
参考https://blog.csdn.net/md_shmily92/article/details/44059313 相关文章random.nextInt()与Math.random()基础用法 ...
- BZOJ_1085_[SCOI2005]骑士精神_IDDFS
BZOJ_1085_[SCOI2005]骑士精神_DFS Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可 ...
- Angular2+ 使用 Protractor 与 Modify Header Value (HTTP Headers) 插件 完成 Windows Authorization 验证
入职新公司第二周,接到了一个E2E测试的任务,两天的时间把所有的测试条件都写完了,结果剩下三天都卡在了Windows Authorization验证这里. 先说一下公司项目Authorize的逻辑 第 ...
- mysql 使用Navicat Lite如何打开‘查询编辑器’,使用sql语句对表进行操作!
今天第一次使用mysql,尽然连查询编辑器都找不到,研究了半天,询问了下大牛,才搞出来,准备写下来,后面方面忘记了有查找的地方,哈哈哈~~ 如何打开"查询编辑器",使用sql语句进 ...
- 腾讯面试:一条SQL语句执行得很慢的原因有哪些?---不看后悔系列
说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...
- 【推荐】 HyperLedger Fabric环境搭建、测试及注意事项 [详尽指导] [亲测有效]
系统:Ubuntu16.04 LTS 一.环境准备 1.1 Ubuntu下安装 crul sudo apt install curl curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被 ...
- Asp.Net Core&Docker部署到树莓派3B中
花了一点时间将吃灰数月的树莓派装上了Docker,并在容器中部署了一个Asp.Net Core应用程序,通过花生壳映射树莓派中的程序,可以使用外网访问树莓派,玩起来很有意思(外网访问地址:http:/ ...
- 《k8s-1.13版本源码分析》-抢占调度
源码分析系列文章已经开源到github,地址如下: github:https://github.com/farmer-hutao/k8s-source-code-analysis gitbook:ht ...