MyBatis 3(4)关联映射:一对一,一对多

MyBatis 关联映射


MyBatis 中对一对一,一对多的关联映射关系的配置方式是比较简单的,只需要在 XML 实体映射文件中进行相应的简单配置即可;

以下为示例代码中数据库的结构:
 
# 用户表
table user(
    user_id primary key,
    user_name,
    user_eamil,
    role_id refrences role(role_id)
)
# 角色表
table role(
    role_id primary key,
    role_name,
    role_group
    )
# 用户评论表
table comments(
    comment_id primary key,
    comment_content,
    user_id references user(user_id)
    )
其中 user 和 role 为一对一的关联关系;user 和 comments 为一对多的关联关系;




一对一映射


user 和 role 为一对一的关联关系,在 POJO User 的数据域中含有一个 Role,如下:
site.assad.domain.User
 
public class User implements Serializable{
    private int id;
    private String name;
    private String email;
    private Role role;                     //一对一关系关联映射对象属性
    // getter,setter
}
site.assad.domain.Role
 
public class Role implements Serializable {
    private int id;
    private String name;
    private String group;
    // getter,setter
}

可以使用 <association> 标签来配置一对一的关联映射,该标签含有的属性如下:
  • property:必填,对应 POJO 中的属性名称;
  • javaType:属性对应的 Java 类型;
  • resultMap:可以通过该属性直接使用现有的 resultMap;
  • columnPrefix:查询列的前缀,配置该属性后,在子标签配置 result 的 column 时可以设置该前缀值;
  • fetchType:抓取策略,可选值由 lazy(延迟抓取),eager(立即抓取);

以下是映射文件的一个示例的配置, mapper/UserMapper.xml
 
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.assad.dao.UserDao">
    
    <!--User 的基本实体映射-->
    <resultMap id="userMap" type="site.assad.domain.User">
        <id property="id" column="user_id" />
        <result property="name" column="user_name" />
        <result property="email" column="user_email" />
    </resultMap>
    
    <!--User 一对一关联属性 role 的属性映射 -->
    <resultMap id="userRoleMap" extends="userMap" type="site.assad.domain.User">
        <!--Role 相关属性映射-->
        <association property="role" javaType="site.assad.domain.Role" >
            <id property="id" column="role_id" />
            <result property="name" column="role_name" />
            <result property="group" column="role_group" />
        </association>
    </resultMap>
    
     <!--示例一对一关联映射查询接口方法-->
    <select id="getUserByIdWithRole" resultMap="userRoleMap">
        select u.user_id, u.user_name, u.user_email,
                r.role_id, r.role_name, r.role_group
        from user u
        inner join role r on u.role_id = r.role_id
        where u.user_id = #{id}
    </select>
</mapper>

在Dao接口 site.assad.dao.UserDao 中定义接口方法:
 
public interface UserDao {
    User getUserByIdWithRole(int id);
}

以下是dao接口方法的测试代码:
 
public class UnitTest {
    private UserDao userDao;
    @Before
    public void init() throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        userDao = sqlSession.getMapper(UserDao.class);
        reader.close();
    }
    @Test
    public void testGetUserByIdWithRole(){
        User user  = userDao.getUserByIdWithRole(1);
        System.out.println(user);
    }
}




一对多映射


user 和 comment 为一对多的关联关系,在 POJO User 数据域含有一个 Comment 类型的列表属性,如下:
site.assad.domain.User
 
public class User implements Serializable{
    private int id;
    private String name;
    private String email;
    private List<Comment> comments;    //一对多的关联映射对象属性
    // getter,setter
}
site.assad.domain.Comment
 
public class Comment implements Serializable{
    private int id;
    private String content;
   // getter,setter
}

可以使用  <collection>  标签来配置一对一的关联映射,该标签含有的属性类似于 <association>:
  • property:必填,对应 POJO 中的属性名称;
  • ofType:集合元素的类型;
  • resultMap:可以通过该属性为集合元素直接使用现有的 resultMap;
  • columnPrefix:集合元素查询列的前缀,配置该属性后,在子标签配置 result 的 column 时可以设置该前缀值;
  • fetchType:抓取策略,可选值有 lazy(延迟抓取),eager(立即抓取);

以下是映射文件的一个示例的配置, mapper/UserMapper.xml
 
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.assad.dao.UserDao">
    
    <!--User 的基本实体映射-->
    <resultMap id="userMap" type="site.assad.domain.User">
        <id property="id" column="user_id" />
        <result property="name" column="user_name" />
        <result property="email" column="user_email" />
    </resultMap>
    
    <!--User 一对多关联属性 commentList 的属性映射 -->
    <resultMap id="userCommentsMap" extends="userMap" type="site.assad.domain.User">
        <!--Comment 相关属性映射-->
        <collection property="comments" ofType="site.assad.domain.Comment" fetchType="lazy">
            <id property="id" column="comment_id" />
            <result property="content" column="comment_content"/>
        </collection>
    </resultMap>
    
    <!--示例一对多关联映射查询接口方法-->
    <select id="getUserByIdWithComments" resultMap="userCommentsMap">
        select u.user_id, u.user_name, u.user_email,
                c.comment_id, c.comment_content
        from user u
        inner join comments c on u.user_id = c.user_id
        where u.user_id = #{id}
    </select>
</mapper>

在Dao接口 site.assad.dao.UserDao 中定义接口方法:
 
public interface UserDao {
    User getUserByIdWithComments(int id);
}

以下是dao接口方法的测试代码:
 
public class UnitTest {
    private UserDao userDao;
    .....
    @Test
    public void testGetUserByIdWithComments(){
        User user  = userDao.getUserByIdWithComments(1);
        List<Comment> comments = user.getComments();
        comments.forEach(System.out::println);
    }
}




集成配置示例


以上的 POJO User 中同时含有一对一关联属性,一对多关联属性,如下:
site.assad.domain.User
 
public class User implements Serializable{
    private int id;
    private String name;
    private String email;
    private Role role;                     //一对一关系关联映射对象属性
    private List<Comment> comments;    //一对多的关联映射对象属性
    // getter,setter
}

可以使用以下比较简洁的 XML 配置方式, mapper/UserMapper.xml:
 
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.assad.dao.UserDao">
    
    <!--User 的基本实体映射-->
    <resultMap id="userMap" type="site.assad.domain.User">
        <id property="id" column="user_id" />
        <result property="name" column="user_name" />
        <result property="email" column="user_email" />
    </resultMap>
    
     <!--Role 的实体映射-->
    <resultMap id="roleMap" type="site.assad.domain.Role">
        <id property="id" column="role_id" />
        <result property="name" column="role_name" />
        <result property="group" column="role_group" />
    </resultMap>
    <!--Comment 的实体映射-->
    <resultMap id="commentMap" type="site.assad.domain.Comment">
        <id property="id" column="comment_id" />
        <result property="content" column="comment_content"/>
    </resultMap>
    <!--User 完整实体映射,包含两个关联属性的映射-->
    <resultMap id="userFullMap" type="site.assad.domain.User" extends="userMap">
        <association property="role" resultMap="roleMap" />
        <collection property="comments" resultMap="commentMap" fetchType="lazy"/>
    </resultMap>
    
    <!--查询接口方法配置-->
    <select id="getUserById" resultMap="userFullMap">
        select u.user_id, u.user_name, u.user_email,
        r.role_id, r.role_name, r.role_group,
        c.comment_id, c.comment_content
        from user u
        inner join role r on u.user_id = r.role_id
        inner join comments c on u.user_id = c.user_id
        where u.user_id = #{id}
    </select>
</mapper>
之后再在 site.assad.dao.UserDao 接口中添加接口方法: User getUserById(int id)  即可;



可以看到,以上的配置方式将 User、Role、Comment 的实体映射配置进一步独立处理,之后通过一个 resultMap 集成 userMap,并引用 roleMap,commentMap 的 resultMap 配置,这样的配置方式进一步提供了代码复用性;

在实际开发过程中,关于 Role,Comment 实体的配置往往不会编写在 UserMapper.xml ,而是编写在各自的实体映射 XML 中,如下:
mapper/RoleMapper.xml
 
<mapper namespace="site.assad.dao.RoleDao">
...
   <resultMap id="roleMap" type="site.assad.domain.Role">
        <id property="id" column="role_id" />
        <result property="name" column="role_name" />
        <result property="group" column="role_group" />
    </resultMap>
....
mapper/CommentMapper.xml
 
<mapper namespace="site.assad.dao.CommentDao">
....
    <resultMap id="commentMap" type="site.assad.domain.Comment">
        <id property="id" column="comment_id" />
        <result property="content" column="comment_content"/>
    </resultMap>
....
此时在 mapper/UserMapper.xml  可以跨文件通过相应的接口类引用这些 resultMap,而不用为一个 POJO 维护多个基本 resultMap,如下:
 
....
    <resultMap id="userMap" type="site.assad.domain.User">
        <id property="id" column="user_id" />
        <result property="name" column="user_name" />
        <result property="email" column="user_email" />
    </resultMap>
    <resultMap id="getUserFull" type="site.assad.domain.User" extends="userMap">
        <association property="role" resultMap="site.assad.dao.RoleDao.roleMap" />
        <collection property="comments" resultMap="site.assad.dao.CommentDao.commentMap"/>
    </resultMap>
....



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis是一款优秀的ORM框架,支持一对一一对多、多对一、多对多等关联映射。其中,一对多关联映射是指一个实体类中包含多个另一个实体类的对象。下面是一对多关联映射的实现方法: 1.在主实体类中定义一个包含从实体类对象的List集合属性。 2.在主实体类对应的Mapper.xml文件中,使用<collection>标签来映射从实体类对象的List集合属性。 3.在从实体类对应的Mapper.xml文件中,使用<association>标签来映射主实体类对象。 具体实现可以参考以下代码: 主实体类User: ``` public class User { private Integer id; private String username; private List<Order> orders; //getter和setter方法 } ``` 从实体类Order: ``` public class Order { private Integer id; private String orderNo; private User user; //getter和setter方法 } ``` 主实体类User对应的Mapper.xml文件: ``` <mapper namespace="com.biem.mapper.UsersMapper"> <resultMap id="userMap" type="User"> <id property="id" column="id"/> <result property="username" column="username"/> <collection property="orders" ofType="Order"> <id property="id" column="order_id"/> <result property="orderNo" column="order_no"/> </collection> </resultMap> <select id="getUserById" resultMap="userMap"> select * from user where id=#{id} </select> </mapper> ``` 从实体类Order对应的Mapper.xml文件: ``` <mapper namespace="com.biem.mapper.OrdersMapper"> <resultMap id="orderMap" type="Order"> <id property="id" column="id"/> <result property="orderNo" column="order_no"/> <association property="user" javaType="User"> <id property="id" column="user_id"/> <result property="username" column="username"/> </association> </resultMap> <select id="getOrderById" resultMap="orderMap"> select * from order where id=#{id} </select> </mapper> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值