数据持久层框架MyBatis
数据库是企业应用中非常重要的部分,而MyBatis是流行的数据库持久层框架之一,本文将主要介绍MyBatis的使用。
一、 简介
MyBatis是一款优秀的数据持久层ORM框架,最早是Apache的一个开源项目,2010年这个项目迁移到Google Code,并且改名为MyBatis,2013年11月又迁移到GitHub。它支持定制化的SQL、存储过程、高级映射,可以使用简单的XML或注解配置和映射原生信息,轻松地将普通的JAVA对象与数据库的表进行关联。具有以下特点:
(1)易学易用,没有第三方依赖,
(2)封装JDBC操作,减少开发人员工作量
(3)SQL和代码解耦,业务逻辑与访问逻辑分离。
(4)灵活动态SQL,支持各种条件动态生成SQL
(5)自动映射结果集,减少重复的编码工作。
核心概念
(1)Mapper 配置文件,可以使用XML、注解、API实现。
(2)Mapper接口: 类似于DAO接口,自定义或动态代理。
(3)Executor(执行器) 所有的SQL执行都是通过它执行。
(4)SqlSession(会话)完全包含数据库相关所有执行操作的方法,底层封装了JDBC连接。
(5)SqlSessionFactory(会话工厂) 是单个数据库映射关系经过编译后的内存镜像。
(6)SqlSessionFactoryBuilder(构建器) 用于解析配置文件,包括属性配置、别名配置、拦截器配置、数据源和事务管理器等。
启动流程:
(1)加载Mapper配置的SQL映射文件。
(2)创建会话工厂
(3)创建会话
(4)创建执行器
(5)封装SQL对象
(6)操作数据库
总之,MyBatis主要有两大核心部件,SqlSessionFactory和Mapper. SqlSessionFactory负责创建数据库会话,Mapper主要提供SQL映射。
二、构建MyBatis应用程序
MyBatis官方对Spring Boot提供了完善的支持,能够方便将MyBatis集成到Spring Boot项目中。
1、MyBatis-Spring-Boot-Starter简介
它是构建基于SpringBoot的MyBatis应用程序的启动器,它不是SpringBoot官方的启动器,是一个集成包,对MyBatis、MyBatis-Spring、SpringBoot都存在依赖。需注意三者版本对应关系。
特点:
(1)构建独立应用 (2)几乎零配置 (3)需要XML配置
启动过程:
自动发现存在的数据源
创建并注册SqlSessionFactory
创建并注册SqlSessionTemplate
自动扫描Mappers, 并注册到Spring上下文中。
注意: MaBatis对于SQL映射提供两种方案,一是简化后的XML配置版,二是使用注解。
2、Spring Boot 集成MyBatis
(1) 首先在pom.xml文件中引入MyBatis-Spring-boot-starter依赖包。
<dependency><groupId>org.MyBatis.spring.boot</groupId><artifactId>MyBatis-spring-boot-starter</artifactId><version>2.1.1</version>
</dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>
(2) 应用配置
在application.properties中添加MyBatis的相关配置:
//mapper.xml配置文件的路径
MyBatis.mapper-locations=classpath: /mapper/*.xml
MyBatis.type-aliases-package=org.weiz.example01.model#数据库连接
spring.datasource.url=jdbc: mysql://localhost:3306/MyBatis_test? serverTimezone=UTC&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-clas-name=com.mysql.cj.jdbc.Driver
注意: locations配置Mapper对应的XML文件路径,type-aliases-package配置项目中的实体类包路径,datasource数据源相关配置。
(3)修改启动类
@Spring BootApplication
@MapperScan("org.weiz.example01.mapper")
public class Application{public static void main(String[] args){SpringApplication.run(Application.class,args);}
}
(4) 创建数据库和表,脚本如下:
Drop table if exists 'student';
create table 'student' ('id' bigint(20) not null auto_increment comment '主键id','name' varchar(32) default null comment '姓名','sex' int(11) default null,'age' int(11) default null,primary key ('id‘)) Engine=InnoDB auto_increment=1 default charset=utf8;
(5)创建实体类
在model目录创建Student实体类,示例代码如下:
public class Student {private Long id;private String name;private int sex;private int age;public Student(){}public Student(String name,int sex, int age){this.name=name;this.sex=sex;this.age=age;}public void setName(String name){ this.name=name; }public String getName(){ return name ; }public void setAge(Integer age){ this.age=age; }public Integer getAge(){ return age; }};
(6)添加mapper接口和映射文件
首选在mapper包中创建StudentMapper接口,然后定义一个查询方法,具体代码如下 :
public interface StudentMapper{List<Student> selectAll();
}
注意: mapper接口中的方法名需要和XML配置中的id属性一致。
定义mapper映射文件,在resources/mapper目录创建StudentMapper.xml文件,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.weiz.example01.mapper.StudentMapper"><resultMap id="BaseResultMap" type="org.weiz.example01.model.Student"><id property="id" column="id"/><result property="name" column="name"/><result property="sex" column="sex"/><result property="age" column="age"/></resultMap><select id="selectAll" resultMap="BaseResultMap">SELECT * FROM student</select>
</mapper>
(7)测试调用
创建单元测试类和测试方法testSelectAll(),具体代码如下:
@Autowired
private StudentMapper studentMapper;@Autowired
JdbcTemplate jdbcTemplate;//测试数据源
@Test
public void querytest() throws SQLException {List <Map<String,Object>> list=jdbcTemplate.queryForList("select * from student");System.out.println(list.size());}//测试MyBatis框架
@Test
public void testSelectAll(){//查询List<Student> students=studentMapper.selectAll();for(Student stu: students) {System.out.println('name'+stu.getName()+’ ,age: ‘+ stu.getAge());}}
单击 Run Test ,运行测试方法。
