在开发中,我遇到这样一种情况:每个种类(Categoy)中有多个属性(Property),每个Category和Property都拥有自己的id属性。这种时候,我就需要使用到多对一的方式:多个属性对应一个种类(种类 为 属性对象 的属性)。
以下为开发中的相关记录(注解方式实现)
一、相关注解
1. @Results
- 代替映射文件中的<resultMap>
- 当做select语句时,返回一个多对一的JavaBean时,需要用到Results来将数据库的相关id映射成对象保存在Bean中(后面有实例)
- 该注解中可以使用单个 @Result 注解,也可以使用一个 @Result注解集合
- 用法:@Results( {@Result( ), @Result( ) } )
2. @Result
-
代替了映射文件中中的<id> 和 <result>
-
属性介绍:
- property:字符串,JavaBean中需要映射的属性,这里是 "Category"
- column:字符串,数据库的列名,可以看做 @One 中sql语句的参数,这里是 "cid"
- one:需要使用 @One ,one = @One( )
- many: 需要使用 @Many ,many=@Many( )
-
用于实现Results中的具体映射:什么映射成什么,使用了什么Sql语句
3. @One (一对一)
-
代替了<assocation>, 多表查询的关键,在注解中用来指定子查询返回舱单一对象给@Result前面的 property
-
属性介绍
- select:指定用来多表查询的 SqlMapper,mapper包路径+方法名
-
使用:@Result(column=" ",property="",one=@One(select="") )
4. @Many (多对一)
- 代替了<colletion>
- 和@One用法类似,例如:一个Categorry 中包含很多个Property
- 使用:@Result(property="",column="",many=@Many(select=""))
二、运行原理
从SQL查询结果集到JavaBean或POJO实体的过程:
- 通过JDBC查询得到一个ResultSet对象,里面包含了数据库表的item
- 遍历ResultSet对象,并将每行item保存到HashMap实例中,以数据库中的字段名或设置的字段别名为键,以字段值为值
- 根据ResultMap(在注解中就是这里的Results)中的类型,这里是应用注解时下方的函数返回类型,通过反射实例化数据模型,即实例化一个Property对象
- Property对象中的Category对象,通过@Result中的属性实例化。这里是将参数column="cid"传递到@One中的sql语句中,返回的对象实例赋给category ( 通过 property="category" 设置 )
三、具体实现
@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查找对应的Property
-
java类结构为:Property中有一个Category属性
表结构为:Property中有一个cid属性
-
特别注意:当向函数传递对象参数时,需要使用@Param( " 别名")注解,同时使用 category.id 调用
-
原理讲解:
-
通过JDBC查询得到一个ResultSet对象,里面包含了数据库表的property{id, cid, name },cid为Category的id
@Select("select * from property where cid=#{category.id}")
-
通过遍历ResultSet对象,并将每行property保存到HashMap实例中,以数据库中的字段名或设置的字段别名为键,以字段值为值
-
根据下方的函数返回类型 List<Property>,通过反射实例化Property模型
-
Property对象中的category属性,通过@Result中的属性实例化。这里是将参数column="cid"传递到@One中的sql语句中,返回的对象实例赋给category ( 通过 property="category" 设置 )
@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; } }
网友评论