Spring Boot 整合Mybatis
在Mybatis初期 需要配置实体类、 配置映射文件 、DAO层代码等一大堆配置. 当然Mybatis 为了解决这些弊端开发了generator 可以根据数据库-数据表自动生成实体类、配置文件和dao层代码,减轻了一部分开发量. MyBatis还提供了注解的方式,适用于小型项目,不用在写配置文件,但是需要在注解上写SQL语句不利于管理. Spring Boot 化繁为简提供了mybatis-spring-boot-starter 可以轻松配置上手.
mybatis-spring-boot-starter 是Mybatis 整合Spring Boot的一套解决方案. 官方的:MyBatis Spring-Boot-Starter will help you use MyBatis with Spring Boot. 官方地址
- 首先构建一个Spring Web的Spring Boot项目. 在pom文件中,引入mybatis-spring-boot-starter 依赖包括mysql驱动.spring-boot-starter-web 引入的spring-mvc的依赖实现restful.
<!-- mybatis整合springboot的依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入mysql驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
- 在application.yml中配置,端口信息 数据源信息以及mybatis的配置(配置pojo实体类所在的包路径)
server:
port: 8089
tomcat:
uri-encoding: UTF-8
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/foodie-shop?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: root
mybatis:
type-aliases-package: com.prim.demo.t_spring_boot_mybatis.pojo #配置pojo所在包的路径
Spring Boot 会自动加载spring.datasource.* 的数据源配置,并且会自动注入到SqlSessionFactory中.
如果你还不理解,看一看原始的MyBatis加载配置操作,通过SqlSessionFactoryBuilder加载配置,Spring Boot帮助我们大大简化了操作,只需要关注配置文件的维护,Spring Boot内部已经自动加载注入到SqlSessionFactory中了.
private static SqlSessionFactory sqlSessionFactory = null;
static {
try {
//加载xml配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//得到SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new ExceptionInInitializerError(e);
}
}
public static SqlSession openSession(){
return sqlSessionFactory.openSession();
}
/**
* 设置SQL是否自动提交事务,一般对于数据库的写操作:插入 更新 删除 都需要手动提交事务来保证数据的完整性
* @param isAutoCommit
* @return
*/
public static SqlSession openSession(boolean isAutoCommit){
//默认情况下自动提交事务
//false 关闭自动提交 需要手动提交事务
return sqlSessionFactory.openSession(isAutoCommit);
}
public static void closeSession(SqlSession sqlSession){
if (sqlSession != null){
sqlSession.close();
}
}
在启动类中添加对Mapper包的扫描注解@MapperScan
@SpringBootApplication
@MapperScan(basePackages = "com.prim.demo.t_spring_boot_mybatis.mapper")
//扫描mapper 或者在每个Mapper类上加入@Mapper注解不推荐这样使用推荐直接配置包名
public class TSpringBootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(TSpringBootMybatisApplication.class, args);
}
}
通过配置mapper包,SpringBoot 会自动将mapper注入到SqlSession中,并且我们在使用时可直接获得实体对象调用.类似原始的方法:
<!-- 采用注解方式 两种方式为了更好的进行维护建议采用package的方式 -->
<mappers>
<!-- <mapper class="com.prim.dao.GoodsDAO"/>-->
<package name="com.prim.dao"/>
</mappers>
public void selectDao(){
SqlSession sqlSession = null;
try {
sqlSession = com.prim.utils.MyBatisUtils.openSession();
GoodsDAO mapper = sqlSession.getMapper(GoodsDAO.class);
List<Goods> list = mapper.selectPriceRange(100, 500, 20);
System.out.println(list.size());
}catch (Exception e){
e.printStackTrace();
}finally {
com.prim.utils.MyBatisUtils.closeSession(sqlSession);
}
}
在Spring Boot中将这些操作,全部在内部处理了,只需通过注入Mapper即可使用.
使用注解的方式
Mapper类,通过注解的方式输入SQL语句
public interface StuMapper {
@Insert("INSERT INTO stu(name,age) VALUES(#{name},#{age})")
void save(Stu stu);
@Update("UPDATE stu SET name=#{name},age=#{age} where id=#{id}")
void update(Stu stu);
@Results(id = "resultMap", value = {
@Result(property = "id", column = "id", id = true),
@Result(property = "name", column = "name"),
@Result(property = "age", column = "age")
})
@Select("SELECT * FROM stu WHERE id=#{id}")
Stu selectOne(int id);
@ResultMap("resultMap")
@Select("SELECT * FROM stu")
List<Stu> selectAll();
@Delete("DELETE FROM stu WHERE id=#{id}")
void delete(int id);
}
- @Select 查询类的注解,所有的查询操作
- @Results 修饰返回的结果集,关联实体类属性和数据库中的字段,可通过设置id,其他方法的查询结果集可以复用
- @Insert 插入数据操作
- @Update 修改数据操作
- @Delete 删除数据操作
注意:一定要使用#符号不要使用\(符号,因为\)符号有SQL注入攻击的漏洞
符号类似:SELECT * FROM stu WHERE id=?
$符号类似:SELECT * FROM stu WHERE id='id'
构建业务成Service,@Service 注入业务类,通过@Autowired注入mapper对象
@Service
public class StuServiceImpl implements StuService {
@Autowired
private StuMapper stuMapper;
@Override
public void save() {
Stu stu = new Stu();
stu.setName("test-1");
stu.setAge(32);
stuMapper.save(stu);
}
@Override
public void update(int id) {
Stu stu = new Stu();
stu.setId(id);
stu.setName("update-1");
stu.setAge(28);
stuMapper.update(stu);
}
@Override
public void delete(int id) {
stuMapper.delete(id);
}
@Override
public Stu getOne(int id) {
return stuMapper.selectOne(id);
}
@Override
public List<Stu> getAll() {
return stuMapper.selectAll();
}
}
在api层也就是controller层使用
@RestController
public class TestController {
@Autowired
private StuService stuService;
@GetMapping("/getStu")
public Object getStu(int id) {
return stuService.getOne(id);
}
@PostMapping("/add")
public Object addStu() {
stuService.save();
return "保存 ok";
}
@PostMapping("/update")
public Object updateStu(int id) {
stuService.update(id);
return "更新 ok";
}
@PostMapping("/delete")
public Object deleteStu(int id) {
stuService.delete(id);
return "删除 ok";
}
}
极简XML方式
通过XML的方式,不需要在Java类中通过注解写SQL语句,而是和Java代码分离,通过XML的方式映射文件,mapper只需要定义空方法即可
- 配置mybatis的xml方式 在application.yml中配置映射文件路径和mybatis的配置文件路径,Spring Boot会自动装配这些配置
mybatis:
type-aliases-package: com.prim.demo.t_spring_boot_mybatis.pojo #配置pojo所在包的路径
mapper-locations: classpath:mapper/*.xml #映射文件的路径
config-location: classpath:mybatis/mybatis-config.xml #mybatis配置文
- 配置映射文件 其实就是将注解中的SQL移到映射文件中
insert into stu(name, age)
values (#{name}, #{age})
update stu
set name=#{name},
age=#{age}
where id = #{id}
delete
from stu
where id = #{id}
select *
from stu
SELECT *
FROM stu
WHERE id = #{id}
mybatis-config.xml 配置,主要配置了一些基础的信息,比如类名的简化等,这样在映射文件中的parameterType="java.lang.Integer" 不用这样写了 直接写parameterType="Integer"
<?xml version="1.0" encoding="utf-8" ?>
<!-- mybatis 的文档约束 -->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias alias="Integer" type="java.lang.Integer"/>
<typeAlias alias="Long" type="java.lang.Long"/>
<typeAlias alias="HashMap" type="java.util.HashMap"/>
<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
<typeAlias alias="ArrayList" type="java.util.ArrayList"/>
<typeAlias alias="LinkedList" type="java.util.LinkedList"/>
</typeAliases>
</configuration>
Mapper层的代码方法名只要和映射文件中的id一一对应即可
public interface StuMapper {
void save(Stu stu);
void update(Stu stu);
Stu selectOne(int id);
List<Stu> selectAll();
void delete(int id);
}
至于service层和controller层的代码不用修改.
如何选择呢?
一般在项目中,注解方式适合简单快速的项目.xml方式更加适合大型项目方便管理.实际项目中根据实际情况来选择.