如何在MyBatis中实现ManyToMany关系?

时间:2013-12-18 11:57:12

标签: java mysql web-applications many-to-many mybatis

我最近正在学习使用Java框架开发Web应用程序。

该应用程序只是一个基本的注册/登录/注销系统。客人可以注册一个帐户并以common user登录。除了common user之外,还有另外两个角色super adminadmin,以及各自的权限/优先级。

Account可以同时拥有多个Role,当然Role可以应用于多个Account。这在AccountRole之间形成了多对多(或从n到对)的关系。

我在我的数据库中维护了三个表:

  • 首先,ACCOUNT表,存储除帐户角色以外的帐户信息;
  • 其次,ROLE表,存储有关Role的数量的信息。目前,只有三个“超级用户”,“管理员”和“普通用户”;
  • 第三个,ACCOUNT_ROLE表,用于存储ACCOUNTROLE之间的映射。

我可以使用Hibernate的@ManyToMany@JoinTable注释来实现这一点,如果我这样做,第三个表可以由Hibernate自动管理。例如,当我创建Account Common User时,hibernate将帮助我将包含AccountIdRoleId的条目添加到第三个表中;当我删除这个Account时,hibernate将帮助我删除第三个表中的相应条目。

而且,问题是如何在MyBatis中实现这种多对多关系?

我已经阅读了一些介绍如何在MyBatis中设置one-to-oneone-to-many关系的资料。但似乎MyBatis没有Hibernate之类的many-to-many关系。那我该怎么办?

我的想法是手动管理第三张表,这意味着:

  • 当我创建新帐户时,我必须手动向第三个表添加条目
  • 删除/更新帐户时,我必须手动删除/更新相应的条目

由于我对MyBatis并不熟悉,所以这种方式是我现在唯一能想到的。

我希望有人可以给我一些关于解决这个问题的提示或想法或具体样本。

PLUS :我在github上有演示应用程序的代码,以防您需要了解此演示的内容。 非常感谢!

3 个答案:

答案 0 :(得分:1)

用户故事

首先,mybatis为您生成model,mapper和mapper.xml。

现在,如果您有两个型号 - 用户和角色 用户和角色之间的关系是什么?

用户拥有许多角色,并且可以向许多用户授权角色。 所以他们是多对多的关系。

如何实施?

  • 将列表角色添加到用户模型

    private List<Role> roles = new ArrayList<>();
    
  • 将列表用户添加到角色模型

    private List<User> users = new ArrayList<>();
    
  • 使UserRoleMapper接口添加一些方法

     package com.jim.mapper;
    
    import com.jim.model.Role;
    import com.jim.model.User;
    
    import java.util.List;
    
    public interface UserRoleMapper {
        int deleteRole(long userId, long roleId);
        int addRole(long userId, long roleId);
        List<Role> getRoles(long userId);
        List<User> getUsers(long roleId);
    }
    
  • 将xml添加到映射SQL&amp;结果

    <resultMap id="UserResultMap" type="com.jim.model.Role">
        <id column="id" jdbcType="INTEGER" property="id"/>
        <result column="name" jdbcType="VARCHAR" property="name"/>
        <collection javaType="ArrayList" property="users" resultMap="RoleResultMap" />
    </resultMap>
    
    <resultMap id="RoleResultMap" type="com.jim.model.User">
        <id column="id" jdbcType="BIGINT" property="id"/>
        <result column="username" jdbcType="VARCHAR" property="username"/>
        <collection javaType="ArrayList" property="roles" resultMap="UserResultMap" />
    </resultMap>
    
    <insert id="addRole">
        INSERT INTO user_role (userId, roleId)
        VALUES (#{userId, jdbcType=BIGINT}, #{roleId, jdbcType=BIGINT});
    </insert>
    <delete id="deleteRole" >
        DELETE FROM user_role
        WHERE 1=1
        AND userId=#{userId}
        AND roleId=#{roleId}
    </delete>
    
    <select id="getRoles" resultMap="UserResultMap">
        SELECT
        r.id AS id, r.name AS name
        FROM users AS  u
        LEFT JOIN user_role AS ur ON u.id = ur.userId
        LEFT JOIN roles AS r ON r.id = ur.roleId
        WHERE 1=1
          AND u.id = #{id,jdbcType=BIGINT}
          AND r.isActive = 1
          AND u.isActive = 1
    </select>
    
    <select id="getUsers" resultMap="RoleResultMap">
        SELECT
        u.id AS id, u.username AS username
        FROM roles AS  r
        LEFT JOIN user_role AS ur ON r.id = ur.roleId
        LEFT JOIN users AS u ON u.id = ur.userId
        WHERE 1=1
        AND r.id = #{id,jdbcType=BIGINT}
        AND r.isActive = 1
        AND u.isActive = 1
    </select>
    

答案 1 :(得分:-1)

查看文档中的嵌套Resultmaps部分。

应该使用像

这样的结果图来实现
<resultMap id="xx" type="map"> 
    <association id="key1" javaType="bean1" /> 
    <collection id="key2" ofType="bean2" /> 
</resultMap> 

答案 2 :(得分:-1)

你可以查看我的repository有一个例子。