目录
实验步骤
- 在数据库中创建两张表(员工表:编号、姓名、年龄、邮箱、部门编号,部门表:部门编号、部门名称)并插入测试数据
- 创建员工表对应的POJO类和映射文件,在映射文件中使用<association>元素实现多对一查询,即根据员工id查询员工信息和部门信息
- 创建部门表对应的POJO类和映射文件,在映射文件中使用<collection>元素实现一对多的查询,即根据部门id查询所有部门员工的信息
- 创建JUnit测试类,每个表创建一个测试类,每个类中有一个测试方法,分别测试一对多和多对一的关联关系
前言:
主要是关于员工表和部门表的查询,建表语句在后面。数据库和实体类中的字段名是相同的
//部门表
public class department {
private Integer id;
private String did; //部门编号
private String dname; //部门名称
private List<employee> employeeList; //员工集合
@Override
public String toString() {
return "部门:"+did+" "+dname+" "+employeeList;
}
}
//员工表
public class employee {
private Integer id;
private String eid; //员工编号
private String name;
private String age;
private String email;
private String did;
private department department1; //部门信息
@Override
public String toString() {
return "员工:"+id+" "+eid+" "+name+" "+age+" "+email+" "+did+" "+department1;
}
}
思路:
本次实验主要是关联表的查询,包括一对一和一对多。那么这里首先就需要搞清楚这两个标签association和collection的用法。然后呢就是一些其他的类的编写了,诸如映射类和测试类这样的。本次实验的全部代码我会放在文章的后面,有需要的提取即可。接下来我们看一下这两个标签的用法。
- association 中的property表示的是类中的属性,也就是此时主表employee中department1。他是一个集合,不可能是string或者integer这种只表示单个元素的,因为下面的两行的意思是将数据库中的column的值映射到实体类中的属性property中(这样也能解决因为数据库中的字段名与实体类中的字段名不一致的情况,对它是没影响的)。然后id和result的区别我暂时没搞懂,感觉二者好像是没有什么区别的(这个问题先挂这儿~)。所以property是实体类中的属性,column是数据库中的字段名,记住了嗷!
- 同理可得,collection也差不多,二者没太大区别。主要是需要加个oftype,不然会报错。因为他需要将查询结果映射到集合中的对象上,作用也是如此。
结合代码进行理解,接下来我们开始解决实验了!Ready?
//1.collection查询的相关代码,我把她两给抽出来了,不是一起的哦
<collection property="employeeList" ofType="pojo.employee">
<id property="id" column="id"/>
<result property="eid" column="eid"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
</collection>
<association property="department1" >
<id property="did1" column="did"/>
<result property="dname" column="dname"/>
</association>
一、配置
首先我们需要配置好pom.xml,mybatis-config.xml以及数据库表的创建,还有sqlSessFactory工具类的创建,这个代码会有点多,但是你复制就行了。等到后面学到了aop再简化吧。项目的结构大致如下:
1、建表语句+添加语句
CREATE TABLE `employee` (
`id`int NOT NULL AUTO_INCREMENT,
`eid` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`age` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`did` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE `department` (
`id` int NOT NULL AUTO_INCREMENT,
`did` varchar(255) DEFAULT NULL,
`dname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
drop TABLE employee
INSERT INTO department (did, dname) VALUES ('1001', 'IT');
INSERT INTO department (did, dname) VALUES ('1002', 'HR');
INSERT INTO employee (eid, name, age, email, did) VALUES ('2000', '张三', '30', 'zhangsan@example.com', '1001');
INSERT INTO employee (eid, name, age, email, did) VALUES ('2001', '李四', '28', 'lisi@example.com', '1002');
INSERT INTO employee (eid, name, age, email, did) VALUES ('2002', '王五', '35', 'wangwu@example.com', '1001');
INSERT INTO employee (eid, name, age, email, did) VALUES ('2003', '王思', '39', 'wangsi@example.com', '1002');
2、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>mybais</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<!-- 把mybatis配置文件拷贝到target/clasess目录下-->
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
3、mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--环境配置: 数据库的连接信息 default:必须和某个environment的id值一样。 告诉mybatis使用哪个数据库的连接信息。也就是访问哪个数据库 -->
<environments default="mydev">
<!-- environment : 一个数据库信息的配置, 环境 id:一个唯一值,自定义,表示环境的名称。 -->
<environment id="mydev">
<!--transactionManager :mybatis的事务类型 type: JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理) -->
<transactionManager type="JDBC"/>
<!-- dataSource:表示数据源,连接数据库的 type:表示数据源的类型, POOLED表示使用连接池 -->
<dataSource type="POOLED">
<!-- driver, user, username, password 是固定的,不能自定义。 -->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost/mybatis?serverTimezone=GMT%2B8"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="12315"/>
</dataSource>
</environment>
</environments>
<!-- sql mapper(sql映射文件)的位置-->
<mappers>
<!--一个mapper标签指定一个文件的位置。 从类路径开始的路径信息。 target/clasess(类路径)-->
<mapper resource="mapper/employeeMapper.xml"/>
<mapper resource="mapper/departmentMapper.xml"/>
</mappers>
</configuration>
4、sqlSessionFactory
package utils;
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 java.io.IOException;
import java.io.Reader;
public class sqlSessionFactory {
public static SqlSession createSql() throws IOException {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
}
二、实体类pojo
1、employee
package pojo;
public class employee {
private Integer id;
private String eid; //员工编号
private String name;
private String age;
private String email;
private String did;
private department department1; //部门信息
@Override
public String toString() {
return "员工:"+id+" "+eid+" "+name+" "+age+" "+email+" "+did+" "+department1;
}
}
2、department
package pojo;
import java.util.List;
public class department {
private Integer id;
private String did1; //部门编号
private String dname; //部门名称
private List<employee> employeeList; //员工集合
@Override
public String toString() {
return "部门:"+did1+" "+dname+" "+employeeList;
}
}
三、映射mapper类
1、employeeMapper.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="dao.employeeDao">
<resultMap id="employeeResultMap" type="pojo.employee">
<id property="id" column="id"/>
<result property="eid" column="eid"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
<result property="did" column="did"/>
<association property="department1" >
<id property="did1" column="did"/>
<result property="dname" column="dname"/>
</association>
</resultMap>
<select id="getEmployeeById" resultMap="employeeResultMap">
SELECT e.id,e.eid,e.name,e.age,e.email,e.did,d.dname
FROM employee e
left JOIN department d ON e.did = d.did
WHERE e.eid = #{eid}
</select>
</mapper>
2、departmentMapper.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="dao.departmentDao">
<resultMap id="departmentResultMap" type="pojo.department">
<id property="id" column="id"/>
<result property="did1" column="did"/>
<result property="dname" column="dname"/>
<collection property="employeeList" ofType="pojo.employee">
<id property="id" column="id"/>
<result property="eid" column="eid"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
</collection>
</resultMap>
<select id="getDepartmentById" resultMap="departmentResultMap">
select d.did,d.dname,e.id,e.eid,e.name,e.age,e.email
from employee e
left join department d on e.did=d.did
where d.did=#{did}
</select>
</mapper>
四、dao
1、employeeDao
package dao;
import pojo.employee;
import java.util.List;
public interface employeeDao {
List<employee> getEmployeeById(String id);
}
2、departmentDao
package dao;
import pojo.department;
import java.util.List;
public interface departmentDao {
List<department> getDepartmentById(String id);
}
五、测试类
import dao.departmentDao;
import dao.employeeDao;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import pojo.department;
import pojo.employee;
import utils.sqlSessionFactory;
import java.io.IOException;
import java.util.List;
public class test {
SqlSession sqlSession;
@Test
void getEmployeeById() throws IOException {
sqlSession= sqlSessionFactory.createSql();
try {
// 获取Mapper接口的代理对象
employeeDao employee=sqlSession.getMapper(employeeDao.class);
//定义员工编号进行查询
String eid="2000";
// 调用Mapper接口的方法
List<pojo.employee> employees = employee.getEmployeeById(eid);
for (employee employee1 : employees) {
System.out.println(employee1);
}
sqlSession.commit();
} finally {
// 关闭SqlSession
sqlSession.close();
}
}
@Test
void getDepartmentById() throws IOException {
sqlSession= sqlSessionFactory.createSql();
try {
// 获取Mapper接口的代理对象
departmentDao department=sqlSession.getMapper(departmentDao.class);
//定义员工编号进行查询
String did="1001";
// 调用Mapper接口的方法
List<department> departments = department.getDepartmentById(did);
for (department d : departments) {
System.out.println(d);
}
sqlSession.commit();
} finally {
// 关闭SqlSession
sqlSession.close();
}
}
}
六、结果
查询结果如下:
1、association
2、collection
六、完整项目
最后,觉得复制很麻烦的可以直接去我的gitee里面拷
Mybatis-association和collection: 关于1V1和1Vn的查询,Mybatis进行操作https://gitee.com/not-to-say/Mybatis.git
\ / _\/_ .-'-. //o\ _\/_ _ ___ __ _ --_ / \ _--_ __ __ _ | __/o\\ _ =-=-_=-=-_=-=_=-_= -=======- = =-=_=-=_,-'|"'""-|-,_ =- _=-=-_=- _=-= _--=====- _=-=_-_,-" | =- =- =-= =- = - -===- -= - ." -Art by Joan G. Stark [jqs]-