目录
- 前期回顾
- MyBatis简介
- 特点
- 持久化(Persistence)
- 什么是持久化
- ORM(Object Relational Mapping)
- ORM解决方案包含下面四个部分
- ORM解决方案
- 经典面试题:MyBatis与Hibernate区别
- Springboot整合MyBatis
- 1.新建工程,导入依赖
- 2.添加配置
- 3.mapper层接口与mapper.xml
- 5.mapper.xml
- 6.serivce层
- 7.controller层
- 异常案例分析
- 数据库连接池
- 什么是数据源连接池:
- 数据源连接池的优势
- SpringBoot项目中的单元测试
- 在Spring Boot项目中加入单元测试
- 什么是单元测试
- 为什么要进行单元测试
- JUnit
- Junit5中常用的注解
- SpringBoot整合Junit
前期回顾
MyBatis简介
- 官方网站:https://blog.mybatis.org/
- MyBatis 原本是Apache的一个开源项目iBatis, 2010年项目由Apache迁移到了Google Code,并且改名为MyBatis 。2013年11月迁移到GitHub。
- MyBatis通过实体类和SQL语句之间建立映射关系,是半自动化的ORM框架,是一款优秀的基于Java的数据持久层框架。
特点
- 基于SQL语法,简单易学
- 能了解底层封装过程,内部通过JDBC访问数据库的操作
- SQL语句封装在配置文件中,便于统一管理与维护,降低程序的耦合度
- 方便程序代码调试
持久化(Persistence)
什么是持久化
- 持久化是将程序数据在持久状态和瞬时状态间转换的机制
- 通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据(比如持久化至数据库中,能够长久保存)。
- 持久化就是将内存中的数据模型转换为存储模型,将存储模型转换为内存中的数据模型的统称。
- 数据模型可以是任何数据结构或对象模型,存储模型可以是关系模型、XML、二进制流等。
ORM(Object Relational Mapping)
- ORM即对象/关系映射,是一种数据持久化技术。它在对象模型和关系型数据库之间建立起对应关系,并且提供了一种机制,通过JavaBean对象去操作数据库表中的数据。
- 编写程序的时候,以面向对象的方式处理数据
- 保存数据的时候,却以关系型数据库的方式存储
ORM解决方案包含下面四个部分
- 在持久化对象上执行基本的增、删、改、查操作
- 对持久化对象提供一种查询语言或者API
- 对象关系映射工具
- 提供与事务对象交互、执行检查、延迟加载以及其他优化功能
ORM解决方案
框架名称 | 所属公司 | 适用场合 |
---|---|---|
Hibernate | 创始人:Gavin King 公司:JBOSS 所有 | 适用与需求变化不多的中小型项目中,比如后台管理系统 |
Mybatis | Apache社区 | 适用于表关联较多的项目,持续维护开发迭代较快的项目,需求变化较多的项目,如互联网项目 |
Mybatis-Plus | 苞米豆社区, 为猿类崛起而生 | MyBatis-Plus是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 |
Spring Data JPA | Spring的母公司是VMware | 传统项目或者关系模型较为清晰稳定的项目,建议JPA |
经典面试题:MyBatis与Hibernate区别
- Hibernate是全自动的ORM框架,Mybatis是半自动化的ORM框架
- Hibernate数据库移植性远大于Mybatis
- Hibernate拥有完整的日志系统,Mybatis则欠缺一些
- Mybatis相比Hibernate需要关心很多细节一些,更灵活一些
- SQL直接优化上,Mybatis要比Hibernate方便很多
- 缓存机制上,Hibernate要比Mybatis更好一些
Springboot整合MyBatis
1.新建工程,导入依赖
boot版本:2.3.12,jdk:1.8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
2.添加配置
server:
port: 7777
logging:
level:
org.springframework.web: debug
com.kgc.mapper: debug
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml # 指定mapper映射文件位置
type-aliases-package: com.kgc.pojo # 指定别名包
# config-location: classpath:mybatis/mybatis-config.xml # 指定mybatis核心配置文件
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印sql语句
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/smbms?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
3.mapper层接口与mapper.xml
public interface UserMapper {
int selectCount();
}
添加注解@Mapper或者启动类上加@MapperScan,这里推荐方式2
- 方式1:在Mapper接口上添加@Mapper,在编译之后会生成相应的实现类
- 方式2:在启动类中添加@MapperScan,@MapperScan注解的作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
@SpringBootApplication
@MapperScan(basePackages = {"com.kgc.mapper"})
public class BootdemoApplication {
public static void main(String[] args) {
SpringApplication.run(BootdemoApplication.class, args);
}
}
5.mapper.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="com.kgc.mapper.UserMapper">
<select id="selectCount" resultType="int">
SELECT COUNT(1) FROM SMBMS_USER
</select>
</mapper>
6.serivce层
@Service
//@Transactional
public class UserService {
@Resource
private UserMapper userMapper;
//@Transactional
public Integer getUserCount(){
return userMapper.selectCount();
}
}
7.controller层
@RestController
public class UserController {
@Resource
private UserService userService;
@RequestMapping("/count")
public Object getCount(){
return userService.getUserCount();
}
}
异常案例分析
如果添加了mybatis依赖,就需要配置数据库连接信息,否则就会报错
- 报错的根源在mybatis-spring-boot-starter这个组件上,mybatis-spring-boot-starter类的作用是整合Spring Boot和MyBatis,建立基于Spring Boot的MyBatis应用程序。该组件完成的工作:
- 它会自动检测现有的数据源(因为你没有配置数据源,所以报错了)
利用SqlSessionFactoryBean创建SqlSessionFactory,将该实例的数据源作为输入传递。 - 创建并注册SqlSessionTemplate实例
- 自动扫描您的映射器,将它们链接到SqlSessionTemplate并将它们注册到Spring上下文中,以便可以将它们注入到您的bean中。
- 它会自动检测现有的数据源(因为你没有配置数据源,所以报错了)
- 在SSM 整合中,开发者需要提供两个 Bean,一个 是SqlSessionFactoryBean ,还有一个是 MapperScannerConfigurer,在 Spring Boot 中,这两个东西不需要配置,但是并不意味着这两个Bean不需要了 , 在自动配置类MybatisAutoConfiguration 类中完成了
数据库连接池
什么是数据源连接池:
- 数据库连接的建立是一种耗时、性能低、代价高的操作,频繁的数据库连接的建立和关闭极大的影响了系统的性能。
- 数据库连接池是系统初始化过程中创建一定数量的数据库连接放于连接池中,当程序需要访问数据库时,不再建立一个新的连接,而是从连接池中取出一个已建立的空闲连接,使用完毕后,程序将连接归还到连接池中,供其他请求使用,从而实现的资源的共享,连接的建立、断开都由连接池自身来管理。
数据源连接池的优势
- 昂贵的数据库连接资源得到重用;
- 减少了数据库连接建立和释放的时间开销,提高了系统响应速度;
- 统一的数据库连接管理,避免了连接资源的泄露。
SpringBoot项目中的单元测试
在Spring Boot项目中加入单元测试
什么是单元测试
- 单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。
为什么要进行单元测试
- 单元测试是由程序员自己来完成,最终受益的也是程序员自己。
- 程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。
- 执行单元测试,就是为了证明代码的行为和我们期望的一致。
- 编写单元测试可以帮助开发人员编写高质量的代码,提升代码质量,减少Bug,便于重构。
JUnit
- JUnit是一个Java语言的单元测试框架
- 官网地址:https://junit.org/
- Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库
Junit5中常用的注解
- @Test :表示方法是测试方法。但是与JUnit4的@Test不同,它的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供。
- @RepeatedTest :表示方法可重复执行
- @BeforeEach :表示在每个单元测试之前执行
- @AfterEach :表示在每个单元测试之后执行
- @BeforeAll :表示在所有单元测试之前执行
- @AfterAll :表示在所有单元测试之后执行
SpringBoot整合Junit
- Spring Boot提供了一些实用程序和注解,用来帮助我们测试应用程序,在Spring Boot中开启单元测试只需引入spring-boot-starter-test即可。
- 在Spring Boot项目中加入单元测试:
- 在test/java目录中,单元测试类,并添加测试方法
- 示例
@SpringBootTest
class BootdemoApplicationTests {
@Resource
private UserMapper userMapper;
@Test
void contextLoads() {
System.out.println(userMapper.selectCount());
}
}