1.问题引出:

  在做映射时候,之前,按照表DDL的字段名,设置java对象的属性。但是,在实际应用无法完全保证表字段名与java类属性完全一致,而且java类应该保持驼峰格式的规范风格。对于类似字段user_id等的情况,不能较好的处理。这时,需要使用resultMap标签来将,DDL的字段名和java类属性名一一对应起来。

  下面实现一个使用resultMap做映射的实例,来阐述其使用方法:


2.resultMap使用,resultMap和resultType的不同使用场景:

 在表的Mapper文件中可以使用<resultMap>来定义这种对应关系,并将信息注入给java对象。组装从数据表中查询出的实体。为了开发的规范,不管数据库表的字段名和java类属性是否能够对上,都要使用resultMap。

1. 表定义test_order_mm.sql:

CREATE TABLE `test_order_mm` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` varchar(20) DEFAULT NULL,
  `order_address` varchar(10) DEFAULT NULL,
  `price` decimal(19,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

随便加2条数据,如下:

10001beijing8.90

20002chengdu100.87


实体类TestOrderMm.java:

public class TestOrderMm {
	private int id;
	private String orderNo;
	private String orderAddress;
	private double price;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getOrderAddress() {
		return orderAddress;
	}
	public void setOrderAddress(String orderAddress) {
		this.orderAddress = orderAddress;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public String getOrderNo() {
		return orderNo;
	}
	public void setOrderNo(String orderNo) {
		this.orderNo = orderNo;
	}
	@Override
	public String toString() {
		return "TestOrderMm [id=" + id + ", orderNo=" + orderNo + ", orderAddress=" + orderAddress + ", price=" + price
				+ "]";
	}

}


2.表mapper配置文件TestOrderMm.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.vip.mapping.TestOrderMm">
	<resultMap id="orderResultMap" type="com.vip.model.TestOrderMm">
		<id property="id" column="id" />
		<result property="orderNo" column="order_no"/>
		<result property="orderAddress" column="order_address"/>
		<result property="price" column="price"/>
	</resultMap>

	<select id="selectOrder" parameterType="java.lang.Integer" resultMap="orderResultMap">
		select * from test_order_mm where id = #{id}
	</select>
	<select id="selectCountOrder" resultType="java.lang.Integer">
		select count(*) from test_order_mm 
	</select>
</mapper>

说明:

(1)resultMap标签:

       resultMap标签定义resultMap;

       id:是这个resultMap的唯一标识符,用来后边的select来通过resultMap标签引用;

       type:指定这个resultMap对应的java类。

       id、result:id和result都用来指定表列和java类属性的映射,但是只有第一个使用id,后边的字段都使用result。

       property:要映射的java类的属性。

       column:要映射的表的字段名。

(2)在select标签中,注意这里指定的是resultMap属性,而不是resultType属性了。

<select id="selectOrder" parameterType="java.lang.Integer" resultMap="orderResultMap">

select * from test_order_mm where id = #{id}

</select>

(3)既然,上边的规范要求:尽量为所有的表都指定resultMap,是不是resultType属性就无用武之地了呢?答案是否定的。我们可以看select id "selectCountOrder",对于这个select,我们清楚得看到返回的是一个数字"订单数"。很明显,一个数字并不需要我们将其映射到java对象中。所以,这个时候就可以使用resultType,并且,这里一定要注意resultType="java.lang.Integer",因为返回值是一个数字。


3. 注册表的配置文件,sqlMapConfig.xml:

<mapper resource="com/vip/mapping/TestOrderMm.xml"/>

4. 测试类:

	/**
	 * 测试resultmap,映射表字段名和java类属性名关系。
	 */
	@Test
	public void testResultMap() {
		SqlSession sqlsession = sqlSessionFactory.openSession();
		//第一个参数找到执行的SQL,命名空间.sqlid   第二个参数:是输入的参数。
		TestOrderMm tom = sqlsession.selectOne("com.vip.mapping.TestOrderMm.selectOrder", 2);
		System.out.println(tom);
		//查询订单总数:
		Integer orderCount = sqlsession.selectOne("com.vip.mapping.TestOrderMm.selectCountOrder");
		System.out.println("共有"+orderCount.toString()+"个订单!!");
		sqlsession.close();
	}

5. 执行结果:

DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: select * from test_order_mm where id = ? 
DEBUG - ==> Parameters: 2(Integer)
TestOrderMm [id=2, orderId=0002, orderAddress=chengdu, price=100.87]
DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: select count(*) from test_order_mm 
DEBUG - ==> Parameters: 
共有2个订单!!


3.返回多条记录:

对于返回多条记录的需求,表mapper定义还是跟返回一条记录之前的一致的,只是在最后返回时,使用List保存,下面是一个返回多条记录的实例:

TestOrderMm.xml:

	<select id="selectCountOrders" resultMap="orderResultMap">
		select * from test_order_mm 
	</select>

测试类AppTest.java

List<TestOrderMm> toms = sqlsession.selectList("com.vip.mapping.TestOrderMm.selectCountOrders");
		for(TestOrderMm tom_si: toms)
		{
			System.out.println(tom_si);
		}
		sqlsession.close();

使用selectList方法,替代selectOne方法来获得多行记录。

运行结果:

DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: select * from test_order_mm 
DEBUG - ==> Parameters: 
TestOrderMm [id=1, orderId=0001, orderAddress=beijing, price=8.9]
TestOrderMm [id=2, orderId=0002, orderAddress=chengdu, price=100.87]