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]