mybatis之旅第四篇-初识mybatis
一、引言
在日常开发用到mybatis时,因为实际的开发业务场景很复杂,不论是输入的查询条件,还是返回的结果,经常是需要根据业务来定制,这个时候我们就需要自己来定义一些输入和输出映射
二、
输入映射是在映射文件中通过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(); }
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
得到测试结果:
输入映射比较简单,一般不会使用包装类,而是根据需要的条件去设置字段比较好
三、
输出类型有简单类型,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
四、
resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
先新增一张订单表,sql如下:
DROP TABLE IF EXISTS `order`; CREATE TABLE `orders` ( `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_orders_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 ('3', '1', '1000010', '2015-02-04 13:22:35', null); INSERT INTO `order` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null); INSERT INTO `order` VALUES ('5', '10', '1000012', '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解决,
<?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); } }
结果: