十四、Mybatis的逆向工程
(一)逆向工程介绍
Mybatis的一个主要的特点就是需要程序员自己编写sql,但是如果表太多的话难免会很麻烦,所以Mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需的代码。
(二)构建项目环境
1、构建maven工程并导入依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
</dependencies>
2、编写配置框架配置文件
?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>
<properties resource="db.properties"></properties>
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<typeAliases>
<package name="cn.offcn.entity"></package>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--在核心配置文件中注册mapper-->
<mappers>
<package name="cn.offcn.mapper"></package>
</mappers>
</configuration>
3、编写逆向工程的配置文件generator.xml
<?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="testTables" targetRuntime="MyBatis3">
<!--实体类实现序列化接口-->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<!--生成实体类中的toString方法-->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis828_002"userId="root" password="root">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时
把JDBC DECIMAL 和NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成实体类的位置 -->
<javaModelGenerator targetPackage="cn.offcn.entity"
targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="cn.offcn.mapper"targetProject=".\src\main\resources">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"targetPackage="cn.offcn.mapper"
targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="department"></table>
<table tableName="employee"></table>
<table tableName="person"></table>
<table tableName="idcard"></table>
<table tableName="student"></table>
<table tableName="teacher_student"></table>
<table tableName="teacher"></table>
</context>
</generatorConfiguration>
4、调用官方api实现逆向工程
package cn.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.ArrayList;
import java.util.List;
public class GeneratorTest {
public static void main(String[] args) throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//指定 逆向工程配置文件
File configFile = new
File("F:\\828class\\workspace\\mybatis\\mybatis004_reflect\\generatorConfig.
xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callba ck = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,callback, warnings);
myBatisGenerator.generate(null);
}
}
5、使用逆向工程完成数据CRUD
//添加员工
public static void addEmployee(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
Employee employee=new Employee();
employee.seteName("马大力");
employee.seteGender("男");
employee.seteAge(23);
employee.seteDepartId(1);
employeeMapper.insert(employee);
session.commit();
MyBatisUtils.close(session);
}
//根据id查询员工
public static void queryEmployeeById(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
Employee emp=employeeMapper.selectByPrimaryKey(2);
System.out.println(emp);
session.commit();
MyBatisUtils.close(session);
}
//根据年龄查询员工
public static void queryEmployeeByAge(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
EmployeeExample employeeExample=new EmployeeExample();
EmployeeExample.Criteria criteria=employeeExample.createCriteria();
criteria.andEAgeGreaterThan(20);
List<Employee> employeeList=employeeMapper.selectByExample(employeeExample);
for (Employee employee : employeeList) {
System.out.println(employee);
}
session.commit();
MyBatisUtils.close(session);
}
//根据年龄和性别查询员工
public static void queryEmployeeByAgeAndGender(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
EmployeeExample employeeExample=new EmployeeExample();
EmployeeExample.Criteria criteria=employeeExample.createCriteria();
criteria.andEAgeGreaterThan(20);
criteria.andEGenderEqualTo("男");
List<Employee> employeeList=employeeMapper.selectByExample(employeeExample);
for (Employee employee : employeeList) {
System.out.println(employee);
}
session.commit();
MyBatisUtils.close(session);
}
//根据id修改员工
public static void updateEmployeeById(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
Employee employee= employeeMapper.selectByPrimaryKey(1);
employee.seteGender("女");
employee.seteDepartId(2);
employeeMapper.updateByPrimaryKey(employee);
session.commit();
MyBatisUtils.close(session);
}
//根据id删除员工
public static void deleteEmployeeById(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
employeeMapper.deleteByPrimaryKey(10);
session.commit();
MyBatisUtils.close(session);
}
//根据姓名更新员工
public static void updateEmployeeByName(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
Employee employee= employeeMapper.selectByPrimaryKey(1);
employee.seteGender("男");
employee.seteAge(24);
EmployeeExample employeeExample=new EmployeeExample();
EmployeeExample.Criteria criteria = employeeExample.createCriteria();
criteria.andENameEqualTo(employee.geteName());
employeeMapper.updateByExample(employee,employeeExample);
session.commit();
MyBatisUtils.close(session);
}
//根据性别和部门查询员工
public static void queryEmployeeByGenderNum(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
EmployeeExample employeeExample=new EmployeeExample();
EmployeeExample.Criteria criteria = employeeExample.createCriteria();
criteria.andEGenderEqualTo("男");
criteria.andEDepartIdEqualTo(1);
long count= employeeMapper.countByExample(employeeExample);
System.out.println(count);
session.commit();
MyBatisUtils.close(session);
}
//根据部门查询员工
public static Employee queryEmployeeDepartmentById(int eid){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
Employee employee=employeeMapper.selectByPrimaryKey(eid);
//查部门
DepartmentMapper departmentMapper=session.getMapper(DepartmentMapper.class);
Department department=departmentMapper.selectByPrimaryKey(employee.geteDepartId());
employee.setDepart(department);
session.commit();
MyBatisUtils.close(session);
return employee;
}
public static void main(String[] args) {
addEmployee();
queryEmployeeById();
queryEmployeeByAge();
queryEmployeeByAgeAndGender();
updateEmployeeById();
updateEmployeeByName();
deleteEmployeeById();
queryEmployees();
queryEmployeeByGenderNum();
Employee employee=queryEmployeeDepartmentById(1);
System.out.println(employee.geteName()+"\t"+employee.getDepart().getdName());
queryEmployees(1,2);
}
十五、Mybatis缓存
(一)缓存简介
缓存是存在于内存中的临时数据,使用缓存的目的是减少和数据库的交互次数,提高执行效率。像大多数的持久化框架一样,Mybatis也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。Mybatis中缓存分为一级缓存、二级缓存。
(二)一级缓存
1、一级缓存介绍
mybatis一级缓存是一种session级别的,针对同一会话SqlSession中,执行多次条件完全相同的同一个sql,那么会共享这一缓存
2、一级缓存结构图
3、编写用户持久层Dao层
public interface EmployeeDao {
public Employee getEmployeeById(int id);
}
4、编写用户持久层映射文件
<select id="getEmployeeById" resultMap="EmployeeResultMap">
SELECT * FROM employee WHERE e_id=#{id}
</select>
<resultMap id="EmployeeResultMap" type="Employee">
<id column="e_id" property="id"></id>
<result column="e_name" property="name"></result>
<result column="e_gender" property="gender"></result>
<result column="e_age" property="age"></result>
</resultMap>
5、编写测试方法
public static void firstCahce(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
//第一次查询
Employee employee1=employeeMapper.getEmployeeById(1);
System.out.println(employee1.getName());
//第二次查询
Employee employee2=employeeMapper.getEmployeeById(1);
System.out.println(employee2.getName());
MyBatisUtils.close(session);
}
结果:
6、一级缓存分析
从上面的代码可以看出,我们写了两次查询操作,但在访问数据时,只有一次。第一次先从一级缓存中获取,因为session是新创建的,一级缓存中没有数据,于是就查询数据获取数据,然后把查询的数据放到一级缓存中,此时一定要注意,一级缓存是一个Map集合,map的key是你的查询条件字符串,值就是查询出来的对象。
第二次查询时,先从一级缓存中获取,因为上一次查询后已经放到一级缓存中,所以从一级缓存中获取到了,就不用访问数据库,减少了和数据库的一次交互,提高了执行效率。
7、测试一级缓存的清空
当我们在两次查询之间做增、删、改操作都会把一级缓存清空,因为不清空就不能保证缓存中的数据与数据库中数据的一致性,可能会读取不正确的数据。
public static void firstCahce(){
SqlSession session = MyBatisUtils.getSession();
EmployeeMapper employeeMapper=session.getMapper(EmployeeMapper.class);
//第一次查询
Employee employee1=employeeMapper.getEmployeeById(1);
System.out.println(employee1.getName());
//新增员工
employeeMapper.addEmployee(new Employee("张小志","男",18));
//第二次查询
Employee employee2=employeeMapper.getEmployeeById(1);
System.out.println(employee2.getName());
MyBatisUtils.close(session);
}
(三)二级缓存
1、二级缓存简介
二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的Sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
2、二级缓存结构图
3、二级缓存的开启与关闭
(1)在SqlMapConfig.xml文件开启二级缓存
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
(2)配置相关的Mapper映射文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.offcn.dao.EmployeeDao">
<!-- 开启二级缓存的支持 -->
<cache></cache>
</mapper>
(3)配置statement上面的useCache属性
<select id="getEmployeeById" resultMap="EmployeeResultMap" useCache="true">
SELECT * FROM employee WHERE e_id=#{id}
</select>
<resultMap id="EmployeeResultMap" type="Employee">
<id column="e_id" property="id"></id>
<result column="e_name" property="name"></result>
<result column="e_gender" property="gender"></result>
<result column="e_age" property="age"></result>
</resultMap>
将EmployeeDao.xml映射文件中的<select>标签中设置useCache="true"代表当前这个statement要使用二级缓存,如果不使用二级缓存可以设置为false。
(4)二级缓存测试
public static void secondCahce(){
SqlSession session1 = MyBatisUtils.getSession();
SqlSession session2 = MyBatisUtils.getSession();
EmployeeMapper employeeMapper1=session1.getMapper(EmployeeMapper.class);
//第一次查询
Employee employee1=employeeMapper1.getEmployeeById(1);
System.out.println(employee1.getName());
session1.commit();
MyBatisUtils.close(session1);
//第二次查询
EmployeeMapper employeeMapper2=session2.getMapper(EmployeeMapper.class);
Employee employee2=employeeMapper2.getEmployeeById(1);
System.out.println(employee2.getName());
session2.commit();
MyBatisUtils.close(session2);
}
经过上面的测试,我们发现执行了两次查询,并且在执行第一次查询后,我们关闭了一级缓存,再去执行第二次查询时,我们发现没有对数据库发出sql语句,所以此时的数据就只能是来自于我们所说的二级缓存。
十六、Mybatis分页插件
(一)分页插件的介绍
分页是一种将所有数据分段展示给用户的技术,用户每次看到的不是全部数据,而是其中一部分。如果在其中没有找到自己想要的内容,用户可以通过制定页码或是翻页的方式转换可见内容,直到找到自己想要的内容为止。
(二)分页插件的引入和配置
//1.在pom.xml中引入插件依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
//2.在mybatis核心配置文件中进行配置
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
(三)定义接口方法getInfo
public class EmployeeDao{
public void getInfo();
}
(四)配置sql语句对于接口方法
<select id="getInfo" resultType="cn.offcn.entity.Employee">
SELECT * FROM employee
</select>
(五)测试分页插件作用
@Test
public void queryEmployees(){
//在查询前设置当前页与每页显示的记录数
PageHelper.startPage(1,5);
SqlSession session = MyBatisUtils.getSession();
EmployeeDao employeeDao=session.getMapper(EmployeeDao.class);
//查询
List<Employee> employeeList=employeeDao.getInfo();
//创建一个PageInfo对象,把查询出的结果集合当做参数传入
PageInfo<Employee> pageInfo=new PageInfo<>(employeeList);
List<Employee> empList=pageInfo.getList(); //取当前页的所有记录
long totalRecored=pageInfo.getTotal();//总记录数
int totalPages=pageInfo.getPages(); //总页数
System.out.println("总记录数:"+totalRecored);
System.out.println("总页数:"+totalPages);
for (Employee employee : empList) {
System.out.println(employee);
}
session.commit();
MyBatisUtils.close(session);
}
十七、Mybatis的注解开发
(一)注解开发的背景介绍
注解提供了一种简单的方式来实现简单映射渔具,而不会引入大量开销。特别是框架相关代码,本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解来代替,这样就使得变成更加简洁。
(二)常用注解介绍
@Insert | 实现新增 |
@Update | 实现更新 |
@Delete | 实现删除 |
@Select | 实现查询 |
@Result | 实现结果集封装 |
@Results | 可以与@Result一起使用,封装多个结果集 |
@ResultMap | 实现引用@Results定义的封装 |
@One | 实现一对一结果集封装 |
@Many | 实现一对多结果集封装 |
@SelectProvider | 实现动态SQL映射 |
(三)项目环境搭建
构建maven工程,导入依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
(四)使用Mybatis注解实现基本CRUD
1、编写实体类
public class Worker {
private Integer id;
private String name;
private String gender;
private Integer age;
public Worker(){}
public Worker(String name, String gender, Integer age) {
this.name = name;
this.gender = gender;
this.age = 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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Worker{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
2、使用注解方式开发持久层接口
public interface WorkerMapper {
@Insert("insert into worker (w_name,w_gender,w_age) " + "values(#{name},#{gender},#{age})")
public void saveWorker(Worker worker);
@Update("update worker set w_name=#{name},w_gender=#{gender},w_age=#{age} where w_id=#{id}")
public void updateWorker(Worker worker);
@Delete("delete from worker where w_id=#{id}")
public void deleteWorkerById(Integer 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_gender",property="gender"),
@Result(column = "w_age",property="age")
})
public Worker getWorkerById(Integer id);
@Select("select * from worker")
@Results({
@Result(column = "w_id",property="id"),
@Result(column = "w_name",property="name"),
@Result(column = "w_gender",property="gender"),
@Result(column = "w_age",property="age")
})
public List<Worker> getWorkers();
}
3、编写SqlMapConfig配置文件
<?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>
<!-- 配置 mybatis的环境 -->
<environments default="development">
<!-- 配置环境 -->
<environment id="development">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接数据库的信息:用的是数据源【连接池】-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis002"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="cn.offcn.dao"></package>
</mappers>
</configuration>
4、编写测试方法
import cn.offcn.dao.WorkerMapper;
import cn.offcn.entity.Worker;
import cn.offcn.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class WorkerTest {
@Test
public void testSaveWorker(){
SqlSession session = MyBatisUtils.getSession();
WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
Worker worker=new Worker("白晓云","女",20);
workerMapper.saveWorker(worker);
session.commit();
MyBatisUtils.close(session);
}
@Test
public void testUpdateWorker(){
SqlSession session = MyBatisUtils.getSession();
WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
Worker worker=new Worker(1,"白晓云","男",22);
workerMapper.updateWorker(worker);
session.commit();
MyBatisUtils.close(session);
}
@Test
public void testDeleteWorkerById(){
SqlSession session = MyBatisUtils.getSession();
WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
workerMapper.deleteWorkerById(1);
session.commit();
MyBatisUtils.close(session);
}
@Test
public void testGetWorkerById(){
SqlSession session = MyBatisUtils.getSession();
WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
Worker worker= workerMapper.getWorkerById(2);
System.out.println(worker);
MyBatisUtils.close(session);
}
@Test
public void testGetWorkers(){
SqlSession session = MyBatisUtils.getSession();
WorkerMapper workerMapper = session.getMapper(WorkerMapper.class);
List<Worker> workerList=workerMapper.getWorkers();
workerList.forEach(System.out::println);
MyBatisUtils.close(session);
}
}
(五)使用注解实现复杂关系映射开发
1、复杂关系映射的注解介绍
注解 | 属性 | 格式 |
@Results | 代替的是标签<resultMap> | @Results({@Result(),@Result()}) 或@Results(@Result()) |
@Result | 代替了<id>标签和<result>标签 | one需要使用的@One注解(@Result(one=@one)())) many需要使用的@Many注解(@Result(many=@many)) |
@One | 代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象 | @Result(column=" ",property="",one=@One(select="")) |
@Many | 代替了<Collection>标签,是多表查询的关键,在注解中用来指定子查询返回对象集合 | @Result(property=" ",column=" ",many=@Many(select="")) |
2、使用注解实现一对一复杂关系映射及延迟加载
(1)添加Person实体类及IdCard实体类
Person实体类:
public class Person {
private int id;
private String name;
private IdCard idCard;
public int getId() {
return id;
}
public void setId(int 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;
}
}
IdCard实体类:
public class IdCard {
private int id;
private String cardno;
private Date useLife;
public int getId() {
return id;
}
public void setId(int 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)添加IdCard的持久层接口并使用注解配置
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 = "e_uselife",property = "useLife")
})
public IdCard getIdCardByPersonId(int id);
}
(3)添加Person持久层接口并使用注解配置
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(property = "idCard",javaType = IdCard.class,column = "p_id",one = @One(select =
"cn.offcn.dao.IdCardDao.getIdCardByPersonId",fetchType = FetchType.LAZY))
})
public Person getPersonById(int id);
}
(4)测试一对一关联及延迟加载
@Test
public void testGetPersonById(){
SqlSession session=MyBatisUtils.getSession();
PersonMapper personMapper=session.getMapper(PersonMapper.class);
Person person=personMapper.getPersonById(1);
System.out.println(person)
MyBatisUtils.close(session);
}
3、使用注解实现一对多复杂关系映射
(1)构建Department和Employee实体类
Department实体类:
public class Department {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Employee实体类:
public class Employee {
private int id;
private String name;
private String gender;
private Integer age;
public Employee(){}
public Employee(int id,String name, String gender, int age) {
this.id=id;
this.name = name;
this.gender = gender;
this.age = age;
}
public Employee(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int 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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
(2)Department实体类加入List
private List<Employee> emps;
public List<Employee> getEmps() {
return emps;
}
public void setEmps(List<Employee> emps) {
this.emps = emps;
}
(3)编写EmployeeMapper持久层接口并使用注解配置
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_gender",property = "gender"),
@Result(column = "e_age",property = "age")
})
public List<Employee> getEmployeeByDepartId(int id);
}
(4)编写DepartmentMapper持久层接口使用注解配置
public interface DepartmentDao {
@Select("select d_id id,d_name name from department where d_id=#{id}")
public Department getDepartmentById(int id);
@Select("select * from department where d_id=#{id}")
@Results({
@Result(column = "d_id",property = "id"),
@Result(column = "d_name",property = "name"),
@Result(property = "emps",column = "d_id",many = @Many(select ="cn.offcn.dao.EmployeeMapper.getEmployeeByDepartId",fetchType =FetchType.LAZY))
})
public Department getDepartmentById(int id);
}
(5)添加测试方法
public void testGetDepartmentById(){
SqlSession session=MyBatisUtils.getSession();
DepartmentMapper departmentMapper=session.getMapper(DepartmentMapper.class);
Department department=departmentMapper.getDepartmentById(1);
System.out.println(department)
MyBatisUtils.close(session);
}