1. SpringBoot集成MyBatis
1.1 准备数据库
-
启动数据库,并通过Navicat连接
创建新的数据库springboot,指定数据库字符编码为utf-8, 并创建表t_person
- 向表中插入几条数据
1.2 创建新项目
1.3 在pom.xml中添加相关jar依赖
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.3
mysql
mysql-connector-java
1.4 在SpringBoot的核心配置文件application.properties中配置数据源
根据自己数据库的信息修改以下内容
server:
# 配置内嵌Tomcat端口号
port: 8888
servlet:
# 配置项目上下文根
context-path: /springboot-web
# 配置数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
username: root
password: 12345678
1.5 代码实现
1.5.1 使用Mybatis反向工程生成接口、映射文件以及实体Bean
创建Mybatis反向工程配置文件 GeneratorMapper.xml
在pom.xml文件中添加反向工程依赖
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.6
GeneratorMapper.xml
true
true
- 修改GeneratorMapper.xml配置
- 运行插件,生成相关文件
1.5.2 在controller包下创建PersonController并编写代码
package com.mufeng.springbootweb.controller;
import com.mufeng.springbootweb.model.Person;
import com.mufeng.springbootweb.services.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class PersonController {
@Autowired
private PersonService personService;
@RequestMapping(value = "/springboot/getPersonDetails")
@ResponseBody
public Object getPersonDetails(){
Person person = personService.findPersonById(1);
return person;
}
}
1.5.3 在Service包下创建service接口并编写代码
package com.mufeng.springbootweb.services;
import com.mufeng.springbootweb.model.Person;
public interface PersonService {
/**
* 根据用户标识获取用户详情
* @param id
* @return
*/
Person findPersonById(Integer id);
}
1.5.4 在 service.impl 包下创建 service 接口并编写代码
package com.mufeng.springbootweb.services.impl;
import com.mufeng.springbootweb.mapper.PersonMapper;
import com.mufeng.springbootweb.model.Person;
import com.mufeng.springbootweb.services.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonMapper personMapper;
@Override
public Person findPersonById(Integer id) {
return personMapper.selectByPrimaryKey(id);
}
}
1.5.5 在 Mybatis 反向工程生成的 StudentMapper 接口上加一个 Mapper 注解
@Mapper 作用:mybatis 自动扫描数据持久层的映射文件及 DAO 接口的关系
package com.mufeng.springbootweb.mapper;
import com.mufeng.springbootweb.model.Person;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface PersonMapper {
int deleteByPrimaryKey(Integer id);
int insert(Person record);
int insertSelective(Person record);
Person selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Person record);
int updateByPrimaryKey(Person record);
}
注意:默认情况下,MyBatis的xml映射文件不会编译到target的class目录下,所以我们需要在pom.xml中配置resource
src/main/java
**/*.xml
1.6 启动Application应用,访问测试
1.7 在运行的主类上添加mapper扫描注解
注释掉PersonMapper接口上的@Mapper注解
package com.mufeng.springbootweb.mapper;
import com.mufeng.springbootweb.model.Person;
import org.apache.ibatis.annotations.Mapper;
//@Mapper
public interface PersonMapper {
int deleteByPrimaryKey(Integer id);
int insert(Person record);
int insertSelective(Person record);
Person selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Person record);
int updateByPrimaryKey(Person record);
}
在运行主类Application上加@MapperScan("com.mufeng.springbootweb.mapper")
package com.mufeng.springbootweb;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.mufeng.springbootweb.mapper")
public class SpringbootWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebApplication.class, args);
}
}
运行测试结果
1.8 接口和映射文件分开
- 修改GeneratorMapper.xml 文件中Mapper映射文件生成目标位置, 目标指向resources下的mapper文件夹下
- 重新运行代码生成插件
把之前生成的映射文件删除掉
- 在application.yml配置文件中需要指定映射文件的位置,这个配置只有接口和映射文件不再同一个包的情况下,才需要指定
mybatis:
mapper-locations: classpath:mapper/*.xml
2. SpringBoot的事务支持
SpringBoot 使用事务非常简单,底层依然采用的是Spring本身提供的事务管理
在入口类中使用注解@EnableTransactionManagement 开启事务支持
在访问数据库的Service方法上添加注解@Transactional即可
在PersonController中添加更新用户的方法
@RequestMapping(value = "/springboot/updatePersonById")
@ResponseBody
public Object updatePersonById(){
int count = 0;
try{
Person person = new Person();
person.setId(1);
person.setName("MuFeng_update");
person.setAge(20);
count = personService.updatePersonById(person);
}catch (Exception e){
e.printStackTrace();
return "fail";
}
return count;
}
在PersonService接口中添加更新用户的方法
/**
* 根据用户id更新用户信息
* @param person
* @return
*/
int updatePersonById(Person person);
在PersonServiceImpl接口实现类中更新用户信息方法进行实现,并主动制造一个异常抛出
@Override
public int updatePersonById(Person person) {
int updateCount = personMapper.updateByPrimaryKeySelective(person);
System.out.println("更新结果:" + updateCount);
//在此构造一个除数为 0 的异常,测试事务是否起作用
int a = 10/0;
return updateCount;
}
运行并测试未开启事务的情况
抛出了异常但是数据修改成功了,我们需要做的是在动作出现异常时,所有的增删改的操作都要回滚
在PersonServiceImpl更新的实现方法上添加@Transactional注解
@Override
@Transactional
public int updatePersonById(Person person) {
int updateCount = personMapper.updateByPrimaryKeySelective(person);
System.out.println("更新结果:" + updateCount);
//在此构造一个除数为 0 的异常,测试事务是否起作用
int a = 10/0;
return updateCount;
}
在Application类上加@EnableTransactionManagement注解开始事务支持
@SpringBootApplication
@MapperScan("com.mufeng.springbootweb.mapper")
@EnableTransactionManagement
public class SpringbootWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebApplication.class, args);
}
}
@EnableTransactionManagement是可选的,但是业务方法上必须添加@Transactional事务才生效
修改Controller的修改用户信息的代码
@RequestMapping(value = "/springboot/updatePersonById")
@ResponseBody
public Object updatePersonById(){
int count = 0;
try{
Person person = new Person();
person.setId(1);
person.setName("MuFeng_update");
person.setAge(25);
count = personService.updatePersonById(person);
}catch (Exception e){
e.printStackTrace();
return "fail";
}
return count;
}
运行测试
同样抛出了异常,但是数据库的年龄信息还是之前的20,并没有被修改,说明我们的事务开启成功了