前面的例子中,數據庫中字段或者字段別名與持久化類中成員變量名保持一致,如果二者並不對應,可以通過映射,將不一致的對應起來。
簡單的結果集映射
在之前的User類中新添加成員變量createDate(Date)和updateDate(Date),數據庫中添加字段create_date(timestamp)和update_date(timestamp),下面實現二者的映射。
在映射文件中使用resultMap標簽。
<sql id="common_field" > ${user}.id,${user}.account,${user}.password,${user}.user_name,${user}.create_time,${user}.update_time </sql> <resultMap type="self.exercise.bean.User" id="BaseResultMap"> <result column="create_time" jdbcType="TIMESTAMP" property="createDate"/> <result column="update_time" jdbcType="TIMESTAMP" property="updateDate"/> </resultMap> <select id="load" resultMap="BaseResultMap" parameterType="int"> select <include refid="common_field"> <property name="user" value="user"/> </include> from web_user user where id=${id} </select>
sql標簽中內容為提取出的公共字段。
resultMap標簽有一個屬性 autoMapping,默認值為true;當數據庫字段和類中成員名相同時,不必在result標簽中手動映射;
result標簽中有屬性javaType,用於指定類中成員的類型,可以省略;用於指定數據庫字段類型的jdbcType必須為大寫形式,常見的類型對應關系:
javaType jdbcType int INTEGER String VARCHAR
... ... java.util.Date TIMESTAMP
映射關聯屬性
如果一個表通過外鍵與另一個表相關聯,在查詢一個表信息要求關聯另一個表的信息,映射文件中的結果集該如何映射?
新建一個Role角色類,並生成get、set、toString方法。
public class Role { private int role_id; private String role_name; }
在數據庫中新建role表,字段與Role對應,user表中新添外鍵與role表關聯。
在User類中添加新的變量Role對象、以及fk_role_id外鍵,要求在查詢user信息時通過外鍵查詢出user對應的角色信息,存到變量Role對象中。
public class User { private String account; private int fk_role_id; private int id; private String password; private Role role; private String user_name; }
現欲查詢用戶信息,並且附帶用戶的角色,代碼如何實現呢?
<resultMap type="self.exercise.bean.User" id="UserWithRoleMapper"> <id property="id" column="id" jdbcType="INTEGER"/> <result property="account" column="account" jdbcType="VARCHAR"/> <result property="password" column="password" jdbcType="VARCHAR"/> <result property="user_name" column="user_name" jdbcType="VARCHAR"/> <result property="fk_role_id" column="fk_role_id" jdbcType="INTEGER"/> <association property="role" javaType="self.exercise.bean.Role" select="getRoleByfk" column="fk_role_id" > <id property="role_id" column="role_id" jdbcType="INTEGER"/> <result property="role_name" column="role_name" jdbcType="VARCHAR"/> </association> </resultMap> <select id="userWithRole" resultMap="UserWithRoleMapper" parameterType="int"> select * from web_user where id=#{id} </select> <select id="getRoleByfk" parameterType="int" resultType="self.exercise.bean.Role"> select role_id,role_name from role where role_id=#{id} </select>
上述代碼中,resultMap為User類的結果集映射;兩個查詢語句分別查詢user和user對應的角色信息。
在結果集映射中,Role對象用assocation標簽實現映射。property為User類中的屬性role,javaType指定role類型,select指定查詢角色信息的sql語句,column指定外鍵值,assocation子標簽可以實現role表和Role對象的映射;
接口中的方法聲明為User uerWithRole(@Param("id") int user_id);
這樣先查詢出user表中的信息,assocation獲取了外鍵和select語句的id,執行語句查詢出對應的角色信息,將結果映射到Role對象中。
改進
Role對象為一個自定義對象,可能其他查詢語句中也會有查詢role表的操作,如果role表中的字段很多,每次查詢role信息都要重新實現一次結果集映射(雖然字段名和類屬性名相同可以實現自動映射,但要考慮到不一致的情況),所以可以將role信息也用結果集映射,需要時直接引用結果集即可。
<mapper namespace="self.exercise.dao.RoleDao"> <resultMap type="self.exercise.bean.Role" id="baseRoleMapper"> <id property="role_id" column="role_id" jdbcType="INTEGER"/> <result property="role_name" column="role_name" jdbcType="VARCHAR"/> </resultMap> </mapper>
<resultMap type="self.exercise.bean.User" id="UserWithRoleMapper"> <id property="id" column="id" jdbcType="INTEGER"/> <result property="account" column="account" jdbcType="VARCHAR"/> <result property="password" column="password" jdbcType="VARCHAR"/> <result property="user_name" column="user_name" jdbcType="VARCHAR"/> <result property="fk_role_id" column="fk_role_id" jdbcType="INTEGER"/> <association property="role" javaType="self.exercise.bean.Role" resultMap="self.exercise.dao.RoleDao.baseRoleMapper" /> </resultMap> <select id="userWithRole" resultMap="UserWithRoleMapper" parameterType="int"> select u.*,r.* from web_user u left join role r on u.id = r.role_id where id=#{id} </select>
之前的sql語句需要執行兩條,現精簡為一條。
