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查询用户的 ...
随机推荐
- 高德地图 地铁图adcode 城市代码
北京 1100天津 1200石家庄 1301沈阳 2101大连 2102长春 2201哈尔滨 2301上海 3100南京 3201无锡 3202苏州 3205杭州 3301宁波 3302合肥 3401 ...
- rabbitmq 脑裂(网络分区)
1.产生的原因 https://blog.csdn.net/zyz511919766/article/details/45198055 2.相关配置.如何规避 https://blog.csdn.ne ...
- 【最小生成树+子集枚举】Uva1151 Buy or Build
Description 平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方. 另外还有q(0<=q< ...
- BZOJ_3675_[Apio2014]序列分割_斜率优化
BZOJ_3675_[Apio2014]序列分割_斜率优化 Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了 ...
- 【源码安装】Heartbeat3.0.9
1.概述1.1 关于Heartbeat1.2 本篇博客实践环境2. 部署基础环境2.1 通过YUM安装依赖环境2.2 创建Heartbeat用户和组3. 编译安装3.1下载源码包3.2 编译安装3.2 ...
- python+appium 查找某个元素find_element()并click()点击,正向判断与反判断的方法封装
使用场景: 在自动化测试过程中,难免会用到反判断,包括异常情况的处理,比如:find_element_by_name('测试') 判断"测试"是否存在,存在则点击,不存在则执行其他 ...
- 什么是语义化的HTML?为什么要做到语义化?
一.什么是语义化的HTML? 语义化的HTML就是写出的HTML代码,符合内容的结构化(内容语义化),选择合适的标签(代码语义化),能够便于开发者阅读和写出更优雅的代码的同时让浏览器的爬虫和机器很好地 ...
- RabbitMQ windows本地安装
1: 安装RabbitMQ需要先安装Erlang语言开发包.下载地址 http://www.erlang.org/download.html 配置环境变量 ERLANG_HOME C:\Program ...
- Java Native Interface调用C++代码
概述 Java Native Interface译为Java原生接口,简称JNI.Java并不是完美的,它的不足体现在运行速度要比传统的C++慢上许多,并且无法直接访问到操作系统底层,为此Java提供 ...
- .Net开发者必知的技术类RSS订阅指南
目录 RSS订阅资源 .Net基金会 MSDN中文版 杂志 微软 Github 系列 微软DevBlog系列 InfoQ中文版系列 如何找到大佬的 Twitter/Youtube/Stackoverf ...