在開發(fā)中箱锐,我遇到這樣一種情況:每個種類(Categoy)中有多個屬性(Property),每個Category和Property都擁有自己的id屬性嘉汰。這種時候皿曲,我就需要使用到多對一的方式:多個屬性對應(yīng)一個種類(種類 為 屬性對象 的屬性)。
以下為開發(fā)中的相關(guān)記錄(注解方式實現(xiàn))
一粤铭、相關(guān)注解
1. @Results
- 代替映射文件中的<resultMap>
- 當(dāng)做select語句時挖胃,返回一個多對一的JavaBean時,需要用到Results來將數(shù)據(jù)庫的相關(guān)id映射成對象保存在Bean中(后面有實例)
- 該注解中可以使用單個 @Result 注解梆惯,也可以使用一個 @Result注解集合
- 用法:@Results( {@Result( ), @Result( ) } )
2. @Result
代替了映射文件中中的<id> 和 <result>
-
屬性介紹:
- property:字符串酱鸭,JavaBean中需要映射的屬性,這里是 "Category"
- column:字符串垛吗,數(shù)據(jù)庫的列名凛辣,可以看做 @One 中sql語句的參數(shù),這里是 "cid"
- one:需要使用 @One 职烧,one = @One( )
- many: 需要使用 @Many 扁誓,many=@Many( )
用于實現(xiàn)Results中的具體映射:什么映射成什么,使用了什么Sql語句
3. @One (一對一)
代替了<assocation>, 多表查詢的關(guān)鍵蚀之,在注解中用來指定子查詢返回艙單一對象給@Result前面的 property
-
屬性介紹
- select:指定用來多表查詢的 SqlMapper蝗敢,mapper包路徑+方法名
使用:@Result(column=" ",property="",one=@One(select="") )
4. @Many (多對一)
- 代替了<colletion>
- 和@One用法類似,例如:一個Categorry 中包含很多個Property
- 使用:@Result(property="",column="",many=@Many(select=""))
二足删、運行原理
從SQL查詢結(jié)果集到JavaBean或POJO實體的過程:
- 通過JDBC查詢得到一個ResultSet對象寿谴,里面包含了數(shù)據(jù)庫表的item
- 遍歷ResultSet對象,并將每行item保存到HashMap實例中失受,以數(shù)據(jù)庫中的字段名或設(shè)置的字段別名為鍵讶泰,以字段值為值
- 根據(jù)ResultMap(在注解中就是這里的Results)中的類型,這里是應(yīng)用注解時下方的函數(shù)返回類型拂到,通過反射實例化數(shù)據(jù)模型痪署,即實例化一個Property對象
- Property對象中的Category對象,通過@Result中的屬性實例化兄旬。這里是將參數(shù)column="cid"傳遞到@One中的sql語句中狼犯,返回的對象實例賦給category ( 通過 property="category" 設(shè)置 )
三、具體實現(xiàn)
@Select("select * from property where cid=#{category.id}")
@Results({
@Result(property = "category", column = "cid",
one = @One(select = "com.shan.tianmao.mapper.CategoryMapper.get"))
})
List<Property> findByCategory(@Param("category") Category category);
此為PropertyMapper中的findByCategory方法领铐,用于利用Category查找對應(yīng)的Property
-
java類結(jié)構(gòu)為:Property中有一個Category屬性
表結(jié)構(gòu)為:Property中有一個cid屬性
特別注意:當(dāng)向函數(shù)傳遞對象參數(shù)時悯森,需要使用@Param( " 別名")注解,同時使用 category.id 調(diào)用
-
原理講解:
-
通過JDBC查詢得到一個ResultSet對象绪撵,里面包含了數(shù)據(jù)庫表的property{id, cid, name }瓢姻,cid為Category的id
@Select("select * from property where cid=#{category.id}")
通過遍歷ResultSet對象,并將每行property保存到HashMap實例中音诈,以數(shù)據(jù)庫中的字段名或設(shè)置的字段別名為鍵幻碱,以字段值為值
根據(jù)下方的函數(shù)返回類型 List<Property>续膳,通過反射實例化Property模型
-
Property對象中的category屬性,通過@Result中的屬性實例化收班。這里是將參數(shù)column="cid"傳遞到@One中的sql語句中坟岔,返回的對象實例賦給category ( 通過 property="category" 設(shè)置 )
@Result(property = "category", column = "cid", one = @One(select = "com.shan.tianmao.mapper.CategoryMapper.get"))
-
附兩個實體類代碼:
-
Category
package com.shan.tianmao.pojo; public class Category { private int id; private String name; public Category() { } public Category(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
-
Property
package com.shan.tianmao.pojo; public class Property { private int id; private String name; private Category category; public Property() { } public Property(int id, String name, Category category) { this.id = id; this.name = name; this.category = category; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Category getCategory() { return category; } public void setCategory(Category category) { this.category = category; } }