MyBatis结果集映射

前面的例子中,数据库中字段或者字段别名与持久化类中成员变量名保持一致,如果二者并不对应,可以通过映射,将不一致的对应起来。

简单的结果集映射

在之前的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语句需要执行两条,现精简为一条。

posted on 2017-02-25 00:27  乄清雅轩灬  阅读(2816)  评论(0编辑  收藏  举报

导航