Mybatis输入映射和输出映射

Posted 暴走小骚年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis输入映射和输出映射相关的知识,希望对你有一定的参考价值。

本节内容:

  • 输入参数映射
  • 输出映射 
  • resultMap

 

Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。

 

一、环境准备

复制昨天的模块,然后粘贴,把名字改掉。具体操作如下:

然后把原来模块下的lib和src目录复制到新的模块下。

将src目录标记为源代码目录。

 

二、输入参数映射(parameterType)

1. 传递简单类型

参考上一篇文章。

使用#{}占位符,或者${}进行sql拼接。

 

2. 传递pojo对象

参考上一篇文章。

Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。

 

3. 传递pojo包装对象

开发中通过可以使用pojo传递查询条件。

查询条件可能是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如查询用户信息的时候,将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

包装对象:Pojo类中的一个属性是另外一个pojo。

需求:根据用户名模糊查询用户信息,查询条件放到QueryVo的user属性中。

(1)编写QueryVo

 QueryVo.java

package com.wisedu.mybatis.pojo;

import java.io.Serializable;

public class QueryVo implements Serializable { //序列化,对象转成二进制进行传输。

	private static final long serialVersionUID = 1L;
	//
	private User user;
	
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}

}

 

(2)sql语句

在UserMapper.xml中配置sql,如下:

    <select id="queryUserByQueryVo" parameterType="QueryVo"
            resultType="com.wisedu.mybatis.pojo.User">
        SELECT * FROM `user` WHERE username LIKE "%"#{user.username}"%" <!-- user对象被封装在QueryVo中 -->
    </select>

 

(3)Mapper接口

在UserMapper接口中添加方法,如下:

public List<User> queryUserByQueryVo(QueryVo vo);

  

(4)测试方法

在MybatisMapperTest.ajva增加测试方法,如下:

        @Test
	public void testMapperQueryVo() throws Exception {
		//加载核心配置文件
		String resource = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

		// 获取sqlSession,和spring整合后由spring管理
		SqlSession sqlSession = sqlSessionFactory.openSession();

		//SqlSEssion会帮我生成一个实现类  (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口)
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

		User user = new User();
		user.setUsername("五");

		QueryVo vo = new QueryVo();
		vo.setUser(user);
		List<User> users = userMapper.queryUserByQueryVo(vo);

		for (User u : users) {
			System.out.println(u);
		}

		// 和spring整合后由spring管理
		sqlSession.close();

	}

 

(5)执行测试方法

DEBUG [main] - ==>  Preparing: SELECT * FROM `user` WHERE username LIKE "%"?"%" 
DEBUG [main] - ==> Parameters: 五(String)
DEBUG [main] - <==      Total: 2
User [id=1, username=王五, sex=2, birthday=null, address=null]
User [id=26, username=王五, sex=null, birthday=null, address=null]

 

三、输出类型(resultType)

1. 输出简单类型

需求:查询用户表数据条数,sql:SELECT count(*) FROM `user`

(1)Mapper.xml文件

在UserMapper.xml中配置sql,如下图:

<!--输出简单类型-->
    <select id="queryUserCount" resultType="int">
        SELECT count(*) FROM `user`
    </select>

 

(2)Mapper接口

在UserMapper添加方法,如下图:

        //查询数据条数
	public Integer queryUserCount();

 

(3)测试方法

在MybatisMapperTest.ajva增加测试方法,如下:

    @Test
    public void testCount() throws Exception {
        //加载核心配置文件
        String resource = "sqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        //创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

        // 获取sqlSession,和spring整合后由spring管理
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //SqlSEssion会帮我生成一个实现类  (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口)
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        Integer count = userMapper.queryUserCount();
        System.out.println(count);

        // 和spring整合后由spring管理
        sqlSession.close();

    }

 

(4)执行测试方法

DEBUG [main] - ==>  Preparing: SELECT count(*) FROM `user` 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 1
9

 

2. 输出pojo对象

 

参见上一篇博客。

 

3. 输出pojo列表

参见上一篇博客。

 

四、resultMap

resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。

如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。

resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

【需求】:查询订单表order的所有数据,sql:SELECT id, user_id, number, createtime, note FROM `order`

1. 编写pojo对象

数据库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_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

Order.java

package com.wisedu.mybatis.pojo;

import java.io.Serializable;
import java.util.Date;

public class Orders implements Serializable{
	private static final long serialVersionUID = 1L;

	private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number == null ? null : number.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note == null ? null : note.trim();
    }

    @Override
    public String toString() {
        return "Orders{" +
                "id=" + id +
                ", userId=" + userId +
                ", number=\'" + number + \'\\\'\' +
                ", createtime=" + createtime +
                ", note=\'" + note + \'\\\'\' +
                \'}\';
    }
}

  

2. Mapper.xml文件

创建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.wisedu.mybatis.mapper.OrderMapper">

    <!-- 查询所有的订单数据 -->
    <select id="queryOrdersAll" resultType="Orders">
        SELECT id, user_id,
        number,
        createtime, note FROM `orders`
    </select>

</mapper>

 

3. Mapper接口

编写接口如下:

package com.wisedu.mybatis.mapper;

import com.wisedu.mybatis.pojo.Orders;

import java.util.List;

public interface OrderMapper {
	//查询所有订单
	List<Orders> queryOrdersAll();

}

 

4. 测试方法

编写测试方法如下:

    //查询订单表orders的所有数据
    @Test
    public void testResultMap() throws Exception {
        //加载核心配置文件
        String resource = "sqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        //创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

        // 获取sqlSession,和spring整合后由spring管理
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //SqlSEssion会帮我生成一个实现类  (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口)
        OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);

        List<Orders> orderses = orderMapper.queryOrdersAll();
        for (Orders order: orderses) {
            System.out.println(order);
        }

        // 和spring整合后由spring管理
        sqlSession.close();

    }

执行测试方法,查看控制台日志:

DEBUG [main] - ==>  Preparing: SELECT id, user_id, number, createtime, note FROM `orders` 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 3
Orders{id=3, userId=null, number=\'1000010\', createtime=Wed Feb 04 13:22:35 CST 2015, note=\'null\'}
Orders{id=4, userId=null, number=\'1000011\', createtime=Tue Feb 03 13:22:41 CST 2015, note=\'null\'}
Orders{id=5, userId=null, number=\'1000012\', createtime=Thu Feb 12 16:13:23 CST 2015, note=\'null\'}

发现userId为null。

解决方案:使用resultMap

 

5. 使用resultMap

由于上边的mapper.xml中sql查询列(user_id)和Order类属性(userId)不一致,所以查询结果不能映射到pojo中。
需要定义resultMap,把orderResultMap将sql查询列(user_id)和Order类属性(userId)对应起来。

修改OrderMapper.xml,如下:

    <!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo -->
    <!-- id:设置ResultMap的id -->
    <resultMap type="Orders" 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" />
        <!--当然可以只写属性名和列名不一样的,一样的可以省略。id一样也可以省略-->
    </resultMap>

    <!-- 查询所有的订单数据 -->
    <select id="queryOrdersAll" resultMap="orderResultMap">
        SELECT id, user_id,
        number,
        createtime, note FROM `orders`
    </select>

再次执行测试方法,查看控制台日志:

DEBUG [main] - ==>  Preparing: SELECT id, user_id, number, createtime, note FROM `orders` 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 3
Orders{id=3, userId=1, number=\'1000010\', createtime=Wed Feb 04 13:22:35 CST 2015, note=\'null\'}
Orders{id=4, userId=1, number=\'1000011\', createtime=Tue Feb 03 13:22:41 CST 2015, note=\'null\'}
Orders{id=5, userId=10, number=\'1000012\', createtime=Thu Feb 12 16:13:23 CST 2015, note=\'null\'}

 

以上是关于Mybatis输入映射和输出映射的主要内容,如果未能解决你的问题,请参考以下文章

mybatis第二天

Mybatis

MyBatis:MyBatis的输入映射和输出映射

mybatis第二天——大纲待更新

mybatis入门基础----输入映射和输出映射

MyBatis总结之输入和输出映射