Mybatis多表查询案例之:多对多

Java 1345℃

1.准备工作

创建maven、添加jar包坐标、MyBatis主配置文件、log4j的配置文件等准备工作可以参考:IDEA中Maven工程的MyBatis快速入门

2.编写实体类

假如数据库有user表和role表,sql语句为:

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `sex` char(1) default NULL COMMENT '性别',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user`(`id`,`username`,`sex`) values (41,'老王','男'),(42,'小二王','女'),(43,'小三王','女');

DROP TABLE IF EXISTS `role`;

CREATE TABLE `role` (
  `id` int(11) NOT NULL COMMENT '编号',
  `role_name` varchar(30) default NULL COMMENT '角色名称',
  `role_desc` varchar(60) default NULL COMMENT '角色描述',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `role`(`id`,`role_name`,`role_desc`) values (1,'院长','管理学院'),(2,'总裁','管理公司'),(3,'校长','管理学校');

DROP TABLE IF EXISTS `user_role`;

CREATE TABLE `user_role` (
  `uid` int(11) NOT NULL COMMENT '用户编号',
  `rid` int(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY  (`uid`,`rid`),
  CONSTRAINT `FK_Reference_2` FOREIGN KEY (`rid`) REFERENCES `role` (`id`),
  CONSTRAINT `FK_Reference_3` FOREIGN KEY (`uid`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user_role`(`uid`,`rid`) values (41,1),(42,3),(41,3);

在src/main/java下创建User类和Role类,实现Serializable接口,且要求与数据表有对应的属性名,代码可参考:IDEA中Maven工程的MyBatis快速入门

通过面向对象的(has a)关系得知,可以在User类中加入一个Role类的属性来代表这个账户有哪些角色。即需要在User.class中添加如下代码:

private List<Role> roles;

public List<Role> getRoles() {
    return roles;
}

public void setRoles(List<Role> roles) {
    this.roles = roles;
}

3.编写实体类的持久层映射接口

这里对应的User类持久层映射接口取名UserMapper,放在src/main/java下,代码如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.QueryVo;
import com.gqzzw.domain.User;

import java.util.List;

public interface UserMapper {
    //多对多查询,查询所有用户同时查询对应的角色信息
    List<User> findAll();
}

4.编写映射接口的配置文件

放在src/main/resources下,必须与久层接口包路径和文件名相同,即:com.gqzzw.mapper.UserMapper.xml,此时需要使用resultMap标签来定义User属性和数据表列的对应关系

<?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="com.gqzzw.mapper.UserMapper">
    <!-- 多对多查询,查询所有用户同时查询对应的角色信息 -->
    <resultMap id="user_role" type="com.gqzzw.domain.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <collection property="roles" ofType="com.gqzzw.domain.Role">
            <result column="role_name" property="role_name"/>
            <result column="role_desc" property="role_desc"/>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="user_role">
        SELECT u.*,r.`role_name`,r.`role_desc` FROM USER u JOIN user_role ur ON u.`id` = ur.`uid` JOIN role r ON ur.`rid`=r.`id`
    </select>
</mapper>

5.编写测试类

放在src/test/java下,编写测试类,内容如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserMapperTset {
    private InputStream in;
    private SqlSession sqlSession;
    private UserMapper userMapper;

    @Before
    public void init() throws IOException {
        //读取配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //使用构建者创建工厂对象SqlSessionFactory
        SqlSessionFactory factory = builder.build(in);
        //使用SqlSessionFactory产SqlSession对象生
        sqlSession = factory.openSession();
        //产SqlSession对象时可以传true代表自动提交事务
        //sqlSession = factory.openSession(true);
        //使用SqlSession创建映射接口的代理对象
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @After
    public void destroy() throws IOException {
        //提交事务,释放资源
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }
    @Test
    //多对多查询,查询所有用户同时查询对应的角色信息
    public void findAll(){
        List<User> users = userMapper.findAll();
        for (User user : users) {
            System.out.println(user);
            System.out.println(user.getRoles());
        }
    }

}

转载请注明:零五宝典 » Mybatis多表查询案例之:多对多