一、框架
1.1 框架概念
框架就是软件的半成品,框架完成了软件开发过程中的通用操作,程序猿只需要很少或者不用加工就能够实现特定的功能,从而简化开发人员在软件开发中的步骤,提高开发效率。
1.2 常用框架
- MVC框架:简化了Servlet的开发步骤,负责和前端进行交互
- Struts2
- SpringMVC
- 持久层框架:完成数据库操作的框架,负责和数据库交互
- MyBatis
- Hibernate
- 胶水框架:Spring
SSM:Spring + SpringMVC + MyBatis
SSH:Spring + Struts2 + Hibernate
二、MyBatis简介
2.1 MyBatis介绍
MyBatis是一个半自动的ORM框架
ORM(Object Relation Mapping)对象关系映射,将Java中的一个对象和数据表中的一行记录一一对应。
ORM框架提供了实体类与数据表的映射关系,通过映射文件的配置,实现了对象的持久化。
MyBatis特点:
- 支持自定义SQL、存储过程
- 对原有的JDBC进行了封装,几乎消除了所有JDBC的代码,让开发人员只需要关注SQL语句本身
- 支持XML和注解配置的方式自动完成ORM操作,实现结果映射
2.2 MyBatis部署
框架部署就是把框架引入到我们自己的项目里
2.2.1 创建Maven项目
- Java项目
- Web项目
2.2.2 在项目中添加MyBatis依赖
- 在 pom.xml 中添加依赖
- mybatis
- mysqldriver
1 | <dependency> |
2.2.3 创建MyBatis配置文件
- 在resources中创建名为mybatis-config.xml的文件
- 在mybatis-config.xml文件中配置数据库连接信息
1 |
|
2.3 MyBatis框架使用
案例:学生信息的数据库操作
2.3.1 创建数据表
tb_students
SQL语句如下:
1 | create table tb students( |
2.3.2 创建实体类
2.3.3 创建DAO接口,定义操作方法
2.3.4 创建DAO接口下的映射文件
- 在
resources
目录下,新建名为mappers
文件夹 - 在
mappers
中新建名为StudentMapper.xml
的映射文件(根据模板创建) - 在映射文件中对DAO中定义的方法进行实现:
1 |
|
2.3.5 将映射文件添加到主配置文件
2.4 单元测试
2.4.1 添加单元测试依赖
1 | <dependency> |
2.4.2 创建单元测试类
被测试类名后,alt + insert – 选择Test
2.4.3 测试代码
1 | package com.qfedu.dao; |
三、MyBatis的CRUD操作
案例:学生信息的增删查改
3.1 添加操作
略
3.2 删除操作
根据学号删除一条学生信息
在StudentDAO中定义删除方法
在StudentMapper.xml中对接口方法进行实现
单元测试:在StudentDAO的测试类中添加测试方法
1 | .junit.Test |
3.3 修改操作
根据学生学号,修改学生信息
在StudentDAO定义修改方法
在StudentMapper.xml中对接口方法进行实现
单元测试
1 |
|
其中,assertEquals()方法表示断言,如果与期望值不同则会出现断言异常。
3.4 查询操作-查询所有数据操作
在StudentDAO中定义查询所有学生的方法
在StudentMapper.xml对接口方法进行实现
定义实体类和数据库表的映射关系
引用实体类和数据库表的映射关系
单元测试
1 |
|
3.5 查询操作-查询单条记录
在StudentDAO中定义查询所有学生的方法
在StudentMapper.xml对接口方法实现
单元测试
1 |
|
3.6 查询操作-多参数查询
在MyBatis进行操作时:
- 如果操作方法只有一个简单类型或者字符串类型的参数,在Mapper配置中可以直接通过#{str}直接获取
- 如果操作方法只有一个对象类型的参数,在Mapper配置中可以直接通过#{attrName}来获取对象的指定属性值
- 如果操作方法有一个Map类型,在Mapper配置中可以直接通过#{key}获取key对应的value
- 如果操作方法有多个参数,可以使用
@Param
注解声明参数的别名
分页查询(参数 start,pageSize)
在StudentDAO定义分页查询的方法
在StudentMapper.xml对接口方法进行实现,,使用
#{别名}
获取到指定的参数单元测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void testListStudentByPage(){
//不能保证文件名一定是正确的,所以可能会抛出异常,需要进行捕获
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//sqlSessionFactory表示MyBatis的会话工厂
SqlSessionFactory factory = builder.build(is);
//sqlSession表示MyBatis与数据库之间的会话:通过工厂方法设计模式
SqlSession sqlSession = factory.openSession();
//通过SqlSession对象调用getMapper方法来获取DAO对象
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
//调用被测试方法
List<Student> students = studentDAO.listStudentByPage(0,2);
for (Student student : students) {
System.out.println(student);
}
//断言
assertNotNull(students);
} catch (IOException e) {
e.printStackTrace();
}
}注意:
如果DAO操作方法没有通过@Param
指定参数别名,在SQL中也可以使用arg0,arg1,...
或者param1,param2,...
的方式来获取参数。
3.7 查询操作-查询总记录数
在StudentDAO中定义操作方法
在StudentMapper.xml中实现接口方法,通过resultType指定当前操作的返回类型为int
单元测试
1 |
|
3.7 添加操作-主键回填
- 在
StudentMapper.xml
中添加操作标签–insert
1 | <!--useGeneratedKey 表示设置添加操作是否需要回填生成的主键--> |
四、工具类封装
- MyBatisUtil
1 | /** |
五、事务管理
- SqlSession功能:
- getMapper(DAO.class):获取Mapper(DAO对象的实例)
- 事务管理
5.1 手动提交事务
测试类中的手动事务管理
1 | .junit.Test |
5.2 自动提交事务
通过SqlSessionFactory调用openSession方法获取SQLSession对象时,可以通过参数来设置事务是否自动提交:
- 如果参数设置为true,表示自动事务提交
- 如果不设置参数或者设置为false,表示手动事务提交
MyBatisUtil优化
1 |
|
测试操作
- 手动事务提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28.junit.Test
public void insertStudent() {
SqlSession sqlSession = MyBatisUtil.getSqlSession(false);
//1.当获取SqlSession对象时,就默认开启了事务
try {
//通过会话获取DAO对象
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
//测试StudentDAO中的方法
Student student = new Student(5, "10009", "周杰伦", "男", 28);
int i = studentDAO.insertStudent(student);
//操作1
//操作2
//...
//操作3
//如果需要使用SqlSession进行多步操作,建议使用手动提交事务
//2.操作成功之后,需要手动提交事务
sqlSession.commit();
System.out.println(student);
} catch (Exception e) {
//3.操作出现异常,需要对事务进行rollback回滚事务
sqlSession.rollback();
}
} - 自动事务提交
1 | .junit.Test |
五、MyBatis主配置文件
mybatis-config.xml是MyBatis框架的主配置文件,主要用于配置MyBatis数据源以及属性信息
5.1 properties标签
用于设置键值对,或者加载属性文件
- 在resources目录下创建jdbc.properties文件,配置键值对如下
1 | mysql_driver=com.mysql.jdbc.Driver |
- 在mybatis-config.xml中通过properties标签引用jdbc.properties文件;
- 引入文件之后,在配置environment时可以直接使用jdbc.properties的key来获取对应的value
注意
:${}是properties文件中的变量占位符,#{}是sql的参数占位符。
5.2 setting标签
1 | <!--设置mybatis的属性--> |
8.3 typeAliases标签
1 | <!--typeAliases标签用于给实体类取别名,在映射文件中可以直接使用别名来替代实体类的全限定名--> |
5.4 plugins标签
1 | <!--plugins标签,用于配置MyBatis插件(分页插件)--> |
5.5 environments标签
1 | <!-- 在environments配置数据库连接信息 --> |
5.6 mappers标签
加载映射配置(映射文件、DAO注解)
1 | <!--mappers标签用于载入映射文件--> |
六、映射文件
6.1 MyBatis Mapper初始化
XML文件解析:读取xml文件中的标签配置封装到Java对象中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n7eXPOJ3-1648176376717)(imgs/1616487875112.png)]
6.2 mapper根标签
mapper文件相当于DAO接口的‘实现类’,namespace属性要指定
实现
DAO接口的全限定名
6.3 insert标签
声明添加操作(sql: insert …)
常用属性
id属性,绑定对应DAO接口中的方法
parameterType属性,用以指定接口中对应方法的参数类型(可省略)
useGeneratedKeys属性, 设置添加操作是否需要回填生成的主键
keyProperty属性,指定回填的id设置到参数对象中的哪个属性
timeout属性,设置此操作的超时时间,如果不设置则一直等待
主键回填
1 | <insert id="insertStudent" useGeneratedKeys="true" keyProperty="stuId"> |
1 | <insert id="insertStudent" > |
6.4 delete标签
声明删除操作
6.5 update标签
声明修改操作
6.6 select标签
声明查询操作
id属性, 指定绑定方法的方法名
parameterType属性,设置参数类型
resultType属性,指定当前sql返回数据封装的对象类型(实体类)
resultMap属性,指定从数据表到实体类的字段和属性的对应关系
useCache属性,指定此查询操作是否需要缓存
timeout属性,设置超时时间
6.7 resultMap标签
1 | <!-- resultMap标签用于定义实体类与数据表的映射关系(ORM) --> |
6.8 cache标签
设置当前DAO进行数据库操作时的缓存属性设置
1 | <cache type="" size="" readOnly="false"/> |
6.9 sql和include
SQL片段
1 | <sql id="wanglaoji">sid , stu_num , stu_name , stu_gender , stu_age</sql> |
七、分页插件
分页插件是一个独立于MyBatis框架之外的第三方插件;
7.1 添加分页插件的依赖
PageHelper
1 | <!-- pagehelper分页插件 --> |
7.2 配置插件
在mybatis的主配置文件
mybatis-config.xml
中通过plugins
标签进行配置
1 | <!--plugins标签,用于配置MyBatis插件(分页插件)--> |
7.3 分页实例
对学生信息进行分页查询
1 |
|
带条件分页
1 |
|
八、关联映射
8.1 实体关系
实体——数据实体,实体关系指的就是数据与数据之间的关系
例如:用户和角色、房屋和楼栋、订单和商品
实体关系分为以下四种:
一对一关联
实例:人和身份证、学生和学生证、用户基本信息和详情
数据表关系:
主键关联(用户表主键 和详情主键相同时,表示是匹配的数据)
唯一外键关联
一对多关联、多对一关联
实例:
- 一对多: 班级和学生 、 类别和商品、楼栋和房屋
- 多对一:学生和班级 、 商品和类别
数据表关系:
- 在多的一端添加外键和一的一段进行关联
多对多关联
实例:用户和角色、角色和权限、房屋和业主、学生和社团、订单和商品
数据表关系:建立第三张关系表添加两个外键分别与两张表主键进行关联
用户(user_id) 用户角色表(uid,rid) 角色(role_id)
8.2 创建项目,部署MyBatis框架
- 创建web项目(maven)
1 | <!--添加web依赖--> |
部署MyBatis框架
- 添加依赖
1
2
3
4
5
6
7
8
9
10
11
12
13<!--添加MyBatis依赖-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53package com.qfedu.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.InputStream;
/**
* @auther xiaochen
* @create 2022-03-29 20:38
*/
public class MyBatisUtil {
private static SqlSessionFactory factory;
private static final ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();
static {
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory() {
return factory;
}
public static SqlSession getSqlSession(boolean isAutoCommit) {
SqlSession sqlSession = local.get();
if (sqlSession == null) {
sqlSession = factory.openSession(isAutoCommit);
local.set(sqlSession);
}
return sqlSession;
}
public static SqlSession getSqlSession() {
return getSqlSession(false);
}
public static <T extends Object> T getMapper(Class<T> c) {
SqlSession sqlSession = getSqlSession(true);
return sqlSession.getMapper(c);
}
}