Mybatis-关联关系映射

1.一对多

 1.1.导入数据表

复制代码
-- 一对多
-- 客户表(主表)
create table t_customer
(
  customer_id int primary key not null auto_increment,
  customer_name varchar(50) not null
);

-- 多对一
-- 订单表(从表)
create table t_order
(
  order_id int primary key not null auto_increment,
  order_no varchar(50) not null unique,
  cid int not null,
  foreign key(cid) references t_customer(customer_id)
);
复制代码

关系:

 

 

 

1.2.mybatis-generator插件生成代码

1)配置mybatis-generator插件生成文件位置2)修改generatorConfig.xml配置文件的生成目录(mapper和model)及对应生成关系

1.3.案例

1.3.1.一对多

一对多:一个客户对应多个订单。建立实体层面的一对多关联关系:

 

 

 

 在CustomerMapper层中定义接口:

List<Customer> queryCustomerAll();

在CustomerMapper.xml中配置SQL语句:

注意事项,使用左外连接而非内连接!!!

 

 

 

1.3.2.多对一

多对一:多个订单对应一个客户(一个订单指向唯一一个客户)。建立实体层面的一对多关联关系:

 

 

 

 

 

 在OrderMapper层中定义接口:

Order queryOrderByOid(Integer orderId);

在OrderMapper.xml中配置SQL语句:

 

 

 

2.多对多

多对多映射其实就是一个双向的一对多映射,因为两边都是一对多。多对多主要是关联关系要找好,然后根据关联去查询。

   一个用户可以拥有多个角色,User—>Role(一对多)。
  一个角色可以赋予多个用户,Role—>User(一对多)。

 

 

 2.1.导入数据表

复制代码
-- 多对多
CREATE TABLE `t_role`  (
  `roleId` int(11) NOT NULL AUTO_INCREMENT,      --角色编号
  `roleName` varchar(255)  NULL DEFAULT NULL,    --角色名称
  `remake` varchar(255)  NULL DEFAULT NULL,      --角色描述
  PRIMARY KEY (`roleId`) USING BTREE
);

-- 主表
CREATE TABLE `t_user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,          --用户编号
  `username` varchar(255)  NULL DEFAULT NULL,    --用户名称
  `age` int(11) NULL DEFAULT NULL,               --年龄
  `birthday` date NULL DEFAULT NULL,             --生日
  `sex` varchar(255)  NULL DEFAULT NULL,         --性别
  `address` varchar(255)  NULL DEFAULT NULL,     --地址
  PRIMARY KEY (`id`) USING BTREE
);

-- 桥接表,在关系型数据库中:多对多关系是无法直接映射的,
-- 必须将一个多对多关系转换成二个一对多关系才能进行映射
CREATE TABLE `t_user_role`  (
  `ur_id` int(11) NOT NULL AUTO_INCREMENT,       
  `user_id` int(11) NULL DEFAULT NULL,
  `role_id` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`ur_id`) USING BTREE
);
复制代码

2.2.案例

2.2.1.用户到角色的多对多查询

  查询所有数据的sql语句

SELECT * FROM t_user u,t_user_role ur,t_role r
       WHERE u.id = ur.user_id AND ur.role_id = r.roleId ORDER BY id

  编写User实体类和UserMapper接口

User实体类:

复制代码
/**
 * 用户实体类
 */
public class User {
    private int userId;
    private String userName;
    private int userAge;
    private Date userBirthday;
    private int userSex;
    private String userAddress;

    //用户拥有的角色
    private List<Role> roles;

    //getter、setter、toString方法省略......
}
复制代码

UserMapper接口:

复制代码
/**
 * UserMapperJ接口
 */
public interface UserMapper {
    //查询所有用户信息
    List<User> selectAllUser();
    //根据用户id查询用户信息
    User selectUserByUserId(@Param("id") Integer userId);
}
复制代码

  配置映射文件UserMapper.xml

复制代码
<resultMap id="userMap" type="com.zking.ssm.model.User">
    <id property="id" column="id"/>
    <result property="username" column="username"/>
    <result property="age" column="age"/>
    <result property="birthday" column="birthday"/>
    <result property="sex" column="sex"/>
    <result property="address" column="address"/>
    <!--一对多映射-->
    <collection property="roles" ofType="com.zking.ssm.model.Role">
      <id property="roleid" column="roleId"/>
      <result property="rolename" column="roleName"/>
      <result property="remake" column="remake"/>
    </collection>
</resultMap>
...
<!-- 查询所有用户-->
<select id="selectAllUser" resultMap="userMap">
    SELECT * FROM
        t_user u,
        t_user_role ur,
        t_role r
    WHERE
        u.id = ur.user_id
    AND
           ur.role_id = r.roleId
    ORDER BY id
</select>
<!--根据用户id查询用户信息-->
<select id="selectUserByUserId" resultMap="userMap">
    SELECT * FROM
        t_user u,
        t_user_role ur,
        t_role r
    WHERE
        u.id = ur.user_id
    AND
        ur.role_id = r.roleId
    AND
        u.id = #{id}
</select>
复制代码

  编写测试类

复制代码
@Test
public void testSelectAllUser(){
    List<User> userList = userService.selectAllUser();
    userList.forEach(System.out::println);
}
//根据用户id查询用户信息
@Test
public void testSelectUserByUserId(){
    User user = userService.selectUserByUserId(2);
    System.out.println(user);
}
复制代码

2.2.2.角色到用户的多对多查询

  查询所有数据的sql语句

SELECT * FROM t_user u,t_user_role ur,t_role r
       WHERE u.id = ur.user_id AND ur.role_id = r.roleId ORDER BY id

  编写Role实体类和RoleMapper接口

Role实体类:

 

复制代码
/**
 * 角色实体类
 */
public class Role {
    private int roleId;
    private String roleName;
    private String remake;//备注

    //该角色包含的用户
    private List<User> users;

    //getter、setter、toString方法省略......
}
复制代码

RoleMapper接口:

复制代码
/**
 * 角色Mapper接口
 */
public interface RoleMapper {
    //查询所有角色信息
    List<Role> selectAllRole();
    //根据角色id查询角色信息
    Role selectRoleByRoleId(@Param("id") Integer roleId);
}
复制代码

  配置映射文件RoleMapper.xml

复制代码
<resultMap id="roleMap" type="com.zking.ssm.model.Role">
    <id property="roleid" column="roleId"/>
    <result property="rolename" column="roleName"/>
    <result property="remake" column="remake"/>
    <collection property="users" ofType="com.zking.ssm.model.User">
      <id property="id" column="id"/>
      <result property="username" column="username"/>
      <result property="age" column="age"/>
      <result property="birthday" column="birthday"/>
      <result property="sex" column="sex"/>
      <result property="address" column="address"/>
    </collection>
</resultMap>

 <!-- 查询所有角色-->
<select id="selectAllRole" resultMap="roleMap">
     SELECT * FROM
         t_user u,
         t_user_role ur,
         t_role r
     WHERE
         u.id = ur.user_id
     AND
         ur.role_id = r.roleId
     ORDER BY roleId
</select>

<!-- 根据角色id查询角色信息-->
<select id="selectRoleByRoleId" resultMap="roleMap">
    SELECT * FROM
        t_user u,
        t_user_role ur,
        t_role r
    WHERE
        u.id = ur.user_id
    AND
        ur.role_id = r.roleId
    AND
        r.roleId = #{id}
</select>
复制代码

  编写测试类

复制代码
//查询所有角色信息
@Test
public void testSelectAllRole(){
    List<Role> roleList = roleService.selectAllRole();
    roleList.forEach(System.out::println);
}
//根据角色id查询角色信息
@Test
public void testSelectRoleByRoleId(){
    Role role = roleService.selectRoleByRoleId(1);
    System.out.println(role);
}
复制代码

3.自关联

 3.1.导入数据表

复制代码
CREATE TABLE `t_module_vue`  (
  `id` int(11) NOT NULL COMMENT '唯一标识',
  `pid` int(11) NOT NULL COMMENT '父ID',
  `text` varchar(50) NOT NULL,
  `icon` varchar(30) NULL DEFAULT NULL,
  `url` varchar(50)  NULL DEFAULT NULL,
  `sort` int(11) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
)
复制代码

3.2.案例

  编写Module实体类和ModuleMapper接口

  Module实体类:

复制代码
@Data
public class Module implements Serializable {
    private Integer id;
    private Integer pid;
    private String text;
    private String icon;
    private String url;
    private Integer sort;
    private List<Module> modules;
}
复制代码

ModuleMapper接口:

@Repository
public interface ModuleMapper {
    List<Module> queryChildNodeByPid(Integer id);
}

  配置映射文件ModuleMapper.xml

 

 先根据id查询菜单根级目录,再利用上次查询结果collection中column的值id作为递归查询条件,查出所有子菜单,返回结果必须为resultMap,并且值为上面构建的resultMap的id值

  编写测试类

@Test
public void demo(){
    List<Module> modules = moduleService.queryRootNode(-1);
    modules.forEach(System.out::println);
}
posted @   孔武  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示