前面的例子中,数据库中字段或者字段别名与持久化类中成员变量名保持一致,如果二者并不对应,可以通过映射,将不一致的对应起来。
在之前的 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 必须为大写形式,常见的类型对应关系:
- javaTypejdbcType
- intINTEGER
- String VARCHAR
- ......
- java.util.DateTIMESTAMP
如果一个表通过外键与另一个表相关联,在查询一个表信息要求关联另一个表的信息,映射文件中的结果集该如何映射?
新建一个 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 语句需要执行两条,现精简为一条。
来源: http://www.bubuko.com/infodetail-1958455.html