mybatis 一对一 ,一对多,多对多

虽然mybatis的一对一 ,一对多,多对多有很多实现方法,但是我介绍一种通用的,任何表与表之间关联查询都可以用这种。

这是我使用的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ssmdemo1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.3.0</version>
        </dependency>
        <!-- mysql驱动包
        	这个驱动包要根据自己MySQL版本来配置不然就会出bug-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- junit测试包 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>

</project>

环境搭好了就可以开始弄了。

先来一对一的用法:

先看看数据库表:

用户表:
在这里插入图片描述

部门表:

在这里插入图片描述

有这两张表下面就可以开始一对一查询了

因为两张表有共同的外键dept_id就可以利用这个外键进行关联查询

创建两个类,供存储查询出来的结果用。

用户类:

//用户类
//使用lombok省略get set 方法
@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    private Dept dept;
    public User() {
    }
}

部门类:

//部门类
@Data
public class Dept {
    Integer dept_id;
    String dept_name;
    List<User> users;
}

建好两个类下面开始写dao层:

public interface UserDao {
    // 一对一查询
    public List<User> queryOneOnOne();

}

UserMapper.xml中代码如下:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.UserDao">
    <!--
        一对一
    -->
    <resultMap id="user" type="pojo.User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <!--
			association 这个标签对应user中的dept成员变量的属性。
		-->
        <association property="dept" javaType="pojo.Dept">
            <result property="dept_name" column="dept_name"></result>
        </association>
    </resultMap>
    <!--这个 id 要和dao层中的方法名对应-->
    <select id="queryOneOnOne" resultMap="user">
        select u.*,d.dept_name from t_user u , t_dept d where u.id = d.dept_id
    </select>
</mapper>

下面开始测试一下:

 //一对一,一对多
    @org.junit.Test
    public void _01_testFindUsername() throws IOException {
        //定义读取文件名
        String resources = "mybatis.xml";
        //创建流
        Reader reader = null;
        try {
            //读取mybatis-config.xml文件到reader对象中
            reader = Resources.getResourceAsReader(resources);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //初始化mybatis,创建SqlSessionFactory类的实例
        SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
        //创建session实例
        SqlSession session = sqlMapper.openSession(true);
        //传入Dao类
        UserDao dao = session.getMapper(UserDao.class);
		//调用一对一查询方法
        List<User> list2 = dao.queryOneOnOne();
        //打印信息
        for (User user0 : list2) {
            System.out.println(user0);
        }
        session.close();
    }

可以看到user中的dept已经有数据了

在这里插入图片描述

下面开始写多对多的例子:

一对多多对多差不多,我写一个多对多的例子,读者可以举一反三,想到一对多的写法。

首先建一个Role类:

@Data
public class Role {
    Integer role_id;
    String role_name;
}

在user类中加一个字段

@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    private Dept dept;
    private List<Role> roles;//增加一个集合,用于存储role对象
    public User() {
    }
}

数据库role表:
在这里插入图片描述
role和user的中间表:
在这里插入图片描述

下面开始写Dao层:

public interface UserDao {
//因为是多对多查询所以返回值为list
	public List<User> queryAll();
}

然后开始写UserMapper.xml中的代码:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.UserDao">
    
    <!--
   		将一对一的代码改一下就实现了多对多	
    -->
    <resultMap id="user" type="pojo.User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <association property="dept" javaType="pojo.Dept">
            <result property="dept_name" column="dept_name"></result>
        </association>
        <!--
			和一对一相比
			在这里加一个标签
			collection代表集合
			roles代表User中成员变量的名字
		-->
        <collection property="roles" ofType="pojo.Role">
            <id property="role_id" column="role_id"></id>
            <result property="role_name" column="role_name"></result>
        </collection>
    </resultMap>

    <!--
        多对多
    -->
    <select id="queryAll" resultMap="user">
        select * from t_user u left join t_user_role ur on u.id=ur.uid left join t_role r on ur.id=r.role_id
    </select>

</mapper>

下面写测试类:

//多对多
    @org.junit.Test
    public void _test() {
        //定义读取文件名
        String resources = "mybatis.xml";
        //创建流
        Reader reader = null;
        try {
            //读取mybatis-config.xml文件到reader对象中
            reader = Resources.getResourceAsReader(resources);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //初始化mybatis,创建SqlSessionFactory类的实例
        SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
        //创建session实例
        SqlSession session = sqlMapper.openSession(true);

        UserDao userDao = session.getMapper(UserDao.class);
        List<User> users = userDao.queryAll();
        for (User u :
                users) {
            System.out.println(u);
        }
    }

运行结果:

在这里插入图片描述

可以看到:打印了三条数据,且每条数据中还有一个集合数据,实现了多对多的查询。

一对多,只要把dao层的方法返回值改成User类而非集合就可以实现。

一对多会返回一条数据,且每条数据中包含集合数据。

注:其实mybatis很简单,只要注意映射关系,还有association和collection的用法就可以上手了。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐