十、MyBatis的逆向工程
(一)逆向工程介绍
MyBatis的一个主要的特点就是需要程序员自己编写sql,那么如果表太多的话,难免会很麻烦,所以mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需要的代码(包括mapper.xml、mapper.java、po..)。一般在开发中,常用的逆向工程方式是通过数据库的表生成代码。
(二)构建项目环境
1.构建maven工程
2.编写配置框架配置文件
(三)逆向工程实现
1.配置generator.xml
官网配置如下:
MyBatis Generator Core – MyBatis Generator XML Configuration File Reference
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 -->
<property name="suppressAllComments" value="true"/>
<!-- 生成注释是否带时间戳-->
<property name="suppressDate" value="true"/>
<!-- 生成的Java文件的编码格式 -->
<property name="javaFileEncoding" value="utf-8"/>
<!-- 格式化java代码-->
<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />
<!-- 格式化XML代码-->
<property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter" />
</commentGenerator>
<!-- 数据库连接驱动类,URL,用户名、密码 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatisdatabase100?rewriteBatchedStatements=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true"
userId="root" password="123456">
</jdbcConnection>
<!-- java类型处理器:处理DB中的类型到Java中的类型 -->
<javaTypeResolver type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
<!-- 是否有效识别DB中的BigDecimal类型 -->
<property name="forceBigDecimals" value="true"/>
</javaTypeResolver>
<!-- 生成实体类的位置 -->
<javaModelGenerator targetPackage="com.jn.entity" targetProject=".\src\main\java">
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="true"/>
<!-- 设置是否在getter方法中,对String类型字段调用trim()方法-->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成xml映射文件:包名(targetPackage)、位置(targetProject) -->
<sqlMapGenerator targetPackage="com.jn.mapper" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 生成DAO接口:包名(targetPackage)、位置(targetProject) -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.jn.mapper" targetProject="./src/main/java">
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- 要生成的表:tableName - 数据库中的表名或视图名,domainObjectName - 实体类名 -->
<table tableName="users"></table>
</context>
</generatorConfiguration>
2.添加插件
<?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>com.jn</groupId>
<artifactId>MybatisProject04</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.0</version>
<!-- 插件的依赖 -->
<dependencies>
<!-- 逆向工程的核心依赖 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.2</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
<configuration>
<configurationFile>C:\Users\20665\IdeaProjects\frame\MybatisProject04\generatorConfig.xml</configurationFile>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.逆向工程生成
在pom.xml里面添加完逆向工程的依赖以及插件之后, 按照下图所示的方式双击进行项目构建
也可以使用官方的API文档添加
package com.jn;
import org.junit.Test;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.util.List;
public class GeneratorTest {
//调用官方的api实现逆向工程
@Test
public void testGenerator() throws Exception{
List<String> warnings = null;
boolean overwrite = true;
File configFile = new File("C:\\Users\\20665\\IdeaProjects\\frame\\MybatisProject04\\generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
然后就自动生成了配置文件指定的数据库表的实体类
4.测试
在进行测试之前,先对生成的实体类进行toString重写
package com.jn;
import com.jn.entity.Users;
import com.jn.entity.UsersExample;
import com.jn.mapper.UsersMapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.jn.utils.MyBatisUtils;
import java.util.Date;
public class UserTest {
//添加用户测试
@Test
public void addUser(){
SqlSession sqlSession = MyBatisUtils.getSession();
UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);
Users users = new Users();
users.setName("王五");
users.setAge(20);
users.setGender("男");
users.setBirthday(new Date());
mapper.insert(users);
sqlSession.commit();
MyBatisUtils.close(sqlSession);
System.out.println("添加成功");
}
//部分添加测试
@Test
public void addUserSelective(){
SqlSession sqlSession = MyBatisUtils.getSession();
UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);
Users users = new Users();
users.setName("王十");
users.setAge(20);
mapper.insertSelective(users);
sqlSession.commit();
MyBatisUtils.close(sqlSession);
}
//根据id查询
@Test
public void selectById(){
SqlSession sqlSession = MyBatisUtils.getSession();
UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);
Users users = mapper.selectByPrimaryKey(1);
System.out.println(users);
MyBatisUtils.close(sqlSession);
}
//根据id和名称查询
@Test
public void selectByExample(){
SqlSession sqlSession = MyBatisUtils.getSession();
UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);
UsersExample example = new UsersExample();
example.createCriteria().andNameEqualTo("王五");
System.out.println(mapper.selectByExample(example));
MyBatisUtils.close(sqlSession);
}
//根据id删除user
@Test
public void deleteById(){
SqlSession sqlSession = MyBatisUtils.getSession();
UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);
mapper.deleteByPrimaryKey(23);
sqlSession.commit();
MyBatisUtils.close(sqlSession);
System.out.println("删除成功");
}
//根据id进行修改
@Test
public void updateById(){
SqlSession sqlSession = MyBatisUtils.getSession();
UsersMapper mapper = sqlSession.getMapper(UsersMapper.class);
Users users = new Users();
users.setId(22);
users.setName("任我行");
users.setAge(20);
users.setGender("男");
users.setBirthday(new Date());
mapper.updateByPrimaryKey(users);
sqlSession.commit();
MyBatisUtils.close(sqlSession);
System.out.println("修改成功");
}
}
十一、Mybatis 缓存
(一)缓存简介
缓存是存在于内存中的临时数据,使用缓存的目的是减少和数据库的交互次数,提高执行效率。像大多数的持久化框架一样,Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能,Mybatis 中缓存分为一级缓存,二级缓存。
(二)一级缓存
1.一级缓存介绍
mybatis一级缓存一种是SESSION级别的,针对同一个会话SqlSession中,执行多次条件完全相同的同一个sql,那么会共享这一缓存。
2.一级缓存结构图
3.持久层 Dao
//根据id查询数据,测试一级缓存
public User findById(Integer id);
4.编写用户持久层映射文件
<!--根据id查询数据,测试一级缓存-->
<select id="findById" parameterType="int" resultType="User">
select * from users where id = #{id}
</select>
5.编写测试方法
//测试一级缓存
@Test
public void testCache() throws Exception{
//获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
//第一次查询数据
User user1 = userDao.findById(1);
System.out.println(user1);
//第二次查询数据
User user2 = userDao.findById(1);
System.out.println(user2);
sqlSession.close();
}
6.一级缓存的分析
从上面的代码可以出,我们写了两次查询操作,但在访问数据时,只有一次。第一次先从一级缓存中获取,因为session是新创建的,一级缓存中没有数据,于是就查询数据获取数据,然后把查询的数据放到一级缓存中,此时一定要注意的是,一级缓存是一个Map集合,map的key是你的查询条件字符串,值就是查询出来的对象。等第二次查询时,先从一缓存中获取,因为上一次查询后已经放到一级缓存中了,所以从一级缓存中获取到了,就不用访问数据库了,减少和数据次的一次交互,提高了执行效率。
7.clearCache
在测试的过程中加入清除缓存的指令 sqlSession.clearCache();
//测试一级缓存
@Test
public void testCache() throws Exception{
//获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
//第一次查询数据
User user1 = userDao.findById(1);
System.out.println(user1);
sqlSession.clearCache();
//第二次查询数据
User user2 = userDao.findById(1);
System.out.println(user2);
sqlSession.close();
}
查看结果:
进行了两次的数据库查询操作
8.CRUD
当我们在两次查询之间做增、删、改操作都会把一级缓存清空,因为不清空就不能保证缓存中的数据与数据库中数据的一致性,可能会读取不正确的数据。
//测试一级缓存
@Test
public void testCache() throws Exception{
//获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
//第一次查询数据
User user1 = userDao.findById(1);
System.out.println(user1);
//清除缓存的方式一 sqlSession.clearCache();
//清除缓存的方式二,在两次查询数据之间进行增删改——更新数据
User user3 = new User("岳灵珊", 28, "女", new Date());
userDao.updateBatchUser(user3);
sqlSession.commit();
//第二次查询数据
User user2 = userDao.findById(1);
System.out.println(user2);
sqlSession.close();
}
然后也是进行了两次的数据库查询操作
(三)二级缓存
1.二级缓存简介
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。
2.二级缓存结构图
3.二级缓存的开启与关闭
3.1SqlMapConfig.xml 开启二级缓存
因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为false 代表不开启二级缓存。
<!--开启二级缓存的支持-->
<settings>
<setting name="cacheEnable" value="true"/>
</settings>
3.2Mapper 映射文件
<!--开启二级缓存的支持-->
<cache></cache>
3.3配置 useCache 属性
将 UserDao.xml 映射文件中的<select>标签中设置 useCache=”true”代表当前这个 statement 要使用二级缓存,如果不使用二级缓存可以设置为 false。
注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。
<!--根据id查询数据,测试一级缓存-->
<select id="findById" parameterType="int" resultType="User" useCache="true">
select * from users where id = #{id}
</select>
3.4二级缓存测试
3..4.1出现错误
说是user实体类不能被序列化
3.4.2User序列化
public class User implements java.io.Serializable{
}
3.4.3测试
经过上面的测试,我们发现执行了两次查询,并且在执行第一次查询后,我们关闭了一级缓存,再去执行第二次查询时,我们发现并没有对数据库发出 sql 语句,所以此时的数据就只能是来自于我们所说的二级缓存。
十二 、MyBatis分页插件
(一)分页插件的介绍
分页是一种将所有数据分段展示给用户的技术.用户每次看到的不是全部数据,而是其中的一部分,如果在其中没有找到自己想要的内容,用户可以通过制定页码或是翻页的方式转换可见内容,直到找到自己想要的内容为止。
分页的的好处:
1.提高性能,一次查20个,比一次查20000个性能肯定更好;另外如果数据量很大,一次性将内容都查询出来,查询出来的结果是放在内存存里面的,会增加cpu的开销造成内存的浪费,效率极低。
2.展现层面的考虑:如果一次展现太多的数据,不管是排版,还是美观上都不好。
(二)分页插件的引入和配置
1.pom.xml引入插件
<!--分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
2.核心配置文件
<!--插件配置——分页插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
</plugins>
(三)定义接口方法getInfo
//分页查询
public void getInfo();
(四)配置sql语句对应接口方法
<!--分页查询-->
<select id="getInfo" resultType="User">
select * from users
</select>
(五)测试分页插件作用
//测试分页查询
@Test
public void testPage() throws Exception{
PageHelper.startPage(1,5);
SqlSession sqlSession = MyBatisUtils.getSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getInfo();
PageInfo<User> pageInfo = new PageInfo<>(userList);
List<User> uList = pageInfo.getList();
int totalCount = (int) pageInfo.getTotal();
int pageNum = pageInfo.getPageNum();
System.out.println("总记录数:"+totalCount);
System.out.println("当前页码:"+pageNum);
uList.forEach(user -> System.out.println(user));
sqlSession.close();
MyBatisUtils.close(sqlSession);
}
十三、MyBatis的注解开发
(一)注解开发介绍
注解提供了一种简单的方式来实现简单映射语句,而不会引入大量的开销。能够读懂别人写的代码,特别是框架相关的代码。本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解来替代,这样就使得编程更加简洁,代码更加清晰。
(二)常用注解介绍
这几年来注解开发越来越流行,Mybatis 也可以使用注解开发方式,这样我们就可以减少编写 Mapper 映射文件了。
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
(三)项目环境搭建
(四)注解实现基本CRUD
1.编写实体类
package com.jn.entity;
public class Workers {
private Integer id;
private String name;
private String age;
private String gender;
public Workers() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Workers(Integer id, String name, String age, String gender) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
public Workers(String name, String age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
@Override
public String toString() {
return "Workers{" +
"id=" + id +
", name='" + name + '\'' +
", age='" + age + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
2.注解开发持久层接口
package com.jn.dao;
import com.jn.entity.Workers;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface WorkerMapper {
//插入数据
@Insert("insert into worker(w_name,w_age,w_gender) values(#{name},#{age},#{gender})")
int insertWorker(Workers worker);
//更新数据
@Update("update worker set w_name=#{name},w_age=#{age},w_gender=#{gender} where w_id=#{id}")
Workers updateWorker(Workers worker);
//删除数据
@Update("delete from worker where w_id=#{id}")
int deleteWorker(Integer id);
//根据id查询数据
@Select("select * from worker where w_id=#{id}")
@Results({
@Result(column = "w_id",property = "id"),
@Result(column = "w_name",property = "name"),
@Result(column = "w_age",property = "age"),
@Result(column = "w_gender",property = "gender")
})
Workers selectWorkerById(Integer id);
//查询所有数据
@Select("select * from worker")
@Results({
@Result(column = "w_id",property = "id"),
@Result(column = "w_name",property = "name"),
@Result(column = "w_age",property = "age"),
@Result(column = "w_gender",property = "gender")
})
public List<Workers> selectAllWorker();
}
3.编写测试方法
package com.jn;
import com.jn.dao.WorkerMapper;
import com.jn.entity.Workers;
import com.jn.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class WorkerTest {
//插入数据测试
@Test
public void insertWorker(){
SqlSession sqlSession = MyBatisUtils.getSession();
WorkerMapper mapper = sqlSession.getMapper(WorkerMapper.class);
Workers worker = new Workers("小明", "18", "男");
int i = mapper.insertWorker(worker);
sqlSession.commit();
MyBatisUtils.close(sqlSession);
System.out.println(i+"添加成功");
}
//更新数据
@Test
public void updateWorker(){
SqlSession sqlSession = MyBatisUtils.getSession();
WorkerMapper mapper = sqlSession.getMapper(WorkerMapper.class);
Workers worker = new Workers(1,"张飞", "18", "女");
int i = mapper.updateWorker(worker);
sqlSession.commit();
MyBatisUtils.close(sqlSession);
System.out.println(i+"修改成功");
}
//删除数据
@Test
public void deleteWorker(){
SqlSession sqlSession = MyBatisUtils.getSession();
WorkerMapper mapper = sqlSession.getMapper(WorkerMapper.class);
int i = mapper.deleteWorker(2);
sqlSession.commit();
MyBatisUtils.close(sqlSession);
System.out.println(i+"删除成功");
}
//根据id查找数据
@Test
public void selectWorkerById(){
SqlSession sqlSession = MyBatisUtils.getSession();
WorkerMapper mapper = sqlSession.getMapper(WorkerMapper.class);
Workers worker = mapper.selectWorkerById(1);
System.out.println(worker);
MyBatisUtils.close(sqlSession);
}
//查看所有数据
@Test
public void selectAllWorker(){
SqlSession sqlSession = MyBatisUtils.getSession();
WorkerMapper mapper = sqlSession.getMapper(WorkerMapper.class);
for (Workers worker : mapper.selectAllWorker()) {
System.out.println(worker);
}
MyBatisUtils.close(sqlSession);
}
}
(五)使用注解实现复杂关系映射
1.复杂关系注解介绍
@Results 注解
代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合
@Results({@Result(),@Result()})或@Results(@Result())
@Resutl 注解
代替了 <id> 标签和<result> 标签
属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)()))
many 需要使用的@Many 注解(@Result(many=@many)()))
@One 注解(一对一)
代替了<assocation> 标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
属性介绍:
select 指定用的 来多表查询的 sqlmapper
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。
使用格式:
@Result(column=" ",property="",one=@One(select=""))
@Many 注解(多对一)
代替了<Collection> 标签, 是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType(一般为 ArrayList)但是注解中可以不定义;
使用格式:
@Result(property="",column="",many=@Many(select=""))
2.一对一复杂关系映射
2.1实体类添加
package com.jn.entity;
public class Person {
private Integer id;
private String name;
private Idcard idcard;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Idcard getIdcard() {
return idcard;
}
public void setIdcard(Idcard idcard) {
this.idcard = idcard;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", idcard=" + idcard +
'}';
}
}
package com.jn.entity;
import java.beans.Introspector;
import java.util.Date;
public class Idcard {
private Integer id;
private String cardno;
private Date uselife;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCardno() {
return cardno;
}
public void setCardno(String cardno) {
this.cardno = cardno;
}
public Date getUselife() {
return uselife;
}
public void setUselife(Date uselife) {
this.uselife = uselife;
}
}
2.2IdCard持久层接口
package com.jn.dao;
import com.jn.entity.Idcard;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
public interface IdCardMapper {
@Select("select * from idcard where c_id=#{id}")
@Results({
@Result(column = "c_id",property = "id"),
@Result(column = "c_cardno",property = "cardno"),
@Result(column = "c_uselife",property = "uselife")
})
public Idcard findById(Integer id);
}
2.3Person持久层接口
package com.jn.dao;
import com.jn.entity.Idcard;
import com.jn.entity.Person;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
public interface PersonMapper {
@Select("select * from person where p_id=#{id}")
@Results({
@Result(column = "p_id", property = "id"),
@Result(column = "p_name", property = "name"),
@Result(column = "p_id",property= "idcard",
javaType = Idcard.class,
one = @One(select="com.jn.dao.IdCardMapper.findById"))
})
public Person findById(Integer id);
}
2.4测试
package com.jn;
import com.jn.dao.PersonMapper;
import com.jn.entity.Idcard;
import com.jn.entity.Person;
import com.jn.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class PersonTest {
@Test
public void test1(){
SqlSession session= MyBatisUtils.getSession();
PersonMapper mapper=session.getMapper(PersonMapper.class);
Person person=mapper.findById(1);
System.out.println(person);
MyBatisUtils.close(session);
}
}
3.使用注解实现一对多复杂关系映射
3.1实体类构建
package com.jn.entity;
public class Employee {
private Integer id;
private String name;
private String gender;
private String age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age='" + age + '\'' +
'}';
}
}
package com.jn.entity;
public class Department {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.2Department加入 List
package com.jn.entity;
import java.util.List;
public class Department {
private Integer id;
private String name;
private List<Employee> employeeList;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmployeeList() {
return employeeList;
}
public void setEmployeeList(List<Employee> employeeList) {
this.employeeList = employeeList;
}
@Override
public String toString() {
return "Department{" +
"id=" + id +
", name='" + name + '\'' +
", employeeList=" + employeeList +
'}';
}
}
3.3EmployeeMapper
package com.jn.dao;
import com.jn.entity.Department;
import com.jn.entity.Employee;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface EmployeeMapper {
@Select("select * from employee where e_depart_id=#{id}")
@Results({
@Result(column = "e_id",property = "id"),
@Result(column = "e_name",property = "name"),
@Result(column = "e_age",property = "age"),
@Result(column = "e_gender",property = "gender")
})
public List<Employee> findById(Integer id);
}
3.4DepartmentMapper
package com.jn.dao;
import com.jn.entity.Department;
import com.jn.entity.Employee;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
public interface DepartmentMapper {
@Select("select * from department where d_id=#{id}")
@Results({
@Result(column = "d_id",property = "id"),
@Result(column = "d_name",property = "name"),
@Result(column = "d_id",property = "employeeList",
many = @Many(select = "com.jn.dao.EmployeeMapper.findById"))
})
public Department findById(Integer id);
}
3.5测试
package com.jn;
import com.jn.dao.DepartmentMapper;
import com.jn.dao.EmployeeMapper;
import com.jn.entity.Department;
import com.jn.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class EmployeeTest {
@Test
public void test1(){
SqlSession session= MyBatisUtils.getSession();
DepartmentMapper departmentMapper=session.getMapper(DepartmentMapper.class);
Department department=departmentMapper.findById(1);
System.out.println(department.getName());
department.getEmployeeList().forEach(System.out::println);
MyBatisUtils.close(session);
}
}