1. SpringBoot集成MyBatis
1.1 准备数据库
-
启动数据库,并通过Navicat连接
image
-
创建新的数据库springboot,指定数据库字符编码为utf-8, 并创建表t_person
![](https://img.haomeiwen.com/i9344550/585973798465fe2d.png)
- 向表中插入几条数据
![](https://img.haomeiwen.com/i9344550/8dc2417b1a17c01c.png)
1.2 创建新项目
![](https://img.haomeiwen.com/i9344550/ca3188a7862a6d78.png)
1.3 在pom.xml中添加相关jar依赖
<!--MyBatis 整合SpringBoot的起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!--MySql 的驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
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文件中添加反向工程依赖
<!--Mybatis 代码动生成插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<!--配置文件的位置-->
<configurationFile>GeneratorMapper.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
- 修改GeneratorMapper.xml配置
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--指定连接数据库的JDBC驱动包所在位置, 指定到你本地的完整路径-->
<classPathEntry location="/Volumes/developer/workspace/java-workspace/springboot/springboot-web/mysql-connector-java-8.0.25.jar"/>
<!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 -->
<context id="tables" targetRuntime="MyBatis3">
<!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 配置数据库连接信息 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true"
userId="root"
password="12345678">
</jdbcConnection>
<!-- 生成 model 类,targetPackage 指定 model 类的包名, targetProject 指定生成的 model 放在 哪个工程下面-->
<javaModelGenerator targetPackage="com.mufeng.springbootweb.model"
targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
<property name="trimStrings" value="false" />
</javaModelGenerator>
<!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的包名, targetProject 指定生成的 mapper.xml 放在哪个工程下面 -->
<sqlMapGenerator targetPackage="com.mufeng.springbootweb.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包名, targetProject 指定生成的 Mapper 接口放在哪个工程下面 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.mufeng.springbootweb.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 数据库表名及对应的 Java 模型类名 -->
<table tableName="t_person" domainObjectName="Person"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
- 运行插件,生成相关文件
![](https://img.haomeiwen.com/i9344550/b75b11b64af072db.png)
![](https://img.haomeiwen.com/i9344550/11ebd47e446ec342.png)
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
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>
**/*.xml
</include>
</includes>
</resource>
</resources>
1.6 启动Application应用,访问测试
![](https://img.haomeiwen.com/i9344550/71743c1d64b4da78.png)
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);
}
}
运行测试结果
![](https://img.haomeiwen.com/i9344550/99b0a5e817ad8db6.png)
1.8 接口和映射文件分开
- 修改GeneratorMapper.xml 文件中Mapper映射文件生成目标位置, 目标指向resources下的mapper文件夹下
<!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的包名, targetProject 指定生成的 mapper.xml 放在哪个工程下面 -->
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
- 重新运行代码生成插件
![](https://img.haomeiwen.com/i9344550/1ad02093a8106cc3.png)
把之前生成的映射文件删除掉
- 在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;
}
运行并测试未开启事务的情况
![](https://img.haomeiwen.com/i9344550/0397c1bb83a18e72.png)
![](https://img.haomeiwen.com/i9344550/4fbe5b2402475c34.png)
抛出了异常但是数据修改成功了,我们需要做的是在动作出现异常时,所有的增删改的操作都要回滚
在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;
}
运行测试
![](https://img.haomeiwen.com/i9344550/04c47b5733543b5a.png)
![](https://img.haomeiwen.com/i9344550/4a2c1ae02e88798f.png)
同样抛出了异常,但是数据库的年龄信息还是之前的20,并没有被修改,说明我们的事务开启成功了
网友评论