1. SpringBoot集成MyBatis
1.1 準(zhǔn)備數(shù)據(jù)庫
-
啟動(dòng)數(shù)據(jù)庫,并通過Navicat連接
image 創(chuàng)建新的數(shù)據(jù)庫springboot,指定數(shù)據(jù)庫字符編碼為utf-8, 并創(chuàng)建表t_person

- 向表中插入幾條數(shù)據(jù)

1.2 創(chuàng)建新項(xiàng)目

1.3 在pom.xml中添加相關(guān)jar依賴
<!--MyBatis 整合SpringBoot的起步依賴-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!--MySql 的驅(qū)動(dòng)依賴-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
1.4 在SpringBoot的核心配置文件application.properties中配置數(shù)據(jù)源
根據(jù)自己數(shù)據(jù)庫的信息修改以下內(nèi)容
server:
# 配置內(nèi)嵌Tomcat端口號(hào)
port: 8888
servlet:
# 配置項(xiàng)目上下文根
context-path: /springboot-web
# 配置數(shù)據(jù)源
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 代碼實(shí)現(xiàn)
1.5.1 使用Mybatis反向工程生成接口、映射文件以及實(shí)體Bean
創(chuàng)建Mybatis反向工程配置文件 GeneratorMapper.xml
在pom.xml文件中添加反向工程依賴
<!--Mybatis 代碼動(dòng)生成插件-->
<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>
<!--指定連接數(shù)據(jù)庫的JDBC驅(qū)動(dòng)包所在位置, 指定到你本地的完整路徑-->
<classPathEntry location="/Volumes/developer/workspace/java-workspace/springboot/springboot-web/mysql-connector-java-8.0.25.jar"/>
<!-- 配置 table 表信息內(nèi)容體,targetRuntime 指定采用 MyBatis3 的版本 -->
<context id="tables" targetRuntime="MyBatis3">
<!-- 抑制生成注釋,由于生成的注釋都是英文的,可以不讓它生成 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 配置數(shù)據(jù)庫連接信息 -->
<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 放在 哪個(gè)工程下面-->
<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 放在哪個(gè)工程下面 -->
<sqlMapGenerator targetPackage="com.mufeng.springbootweb.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 生成 MyBatis 的 Mapper 接口類文件,targetPackage 指定 Mapper 接口類的包名, targetProject 指定生成的 Mapper 接口放在哪個(gè)工程下面 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.mufeng.springbootweb.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 數(shù)據(jù)庫表名及對(duì)應(yīng)的 Java 模型類名 -->
<table tableName="t_person" domainObjectName="Person"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
- 運(yùn)行插件,生成相關(guān)文件


1.5.2 在controller包下創(chuàng)建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包下創(chuàng)建service接口并編寫代碼
package com.mufeng.springbootweb.services;
import com.mufeng.springbootweb.model.Person;
public interface PersonService {
/**
* 根據(jù)用戶標(biāo)識(shí)獲取用戶詳情
* @param id
* @return
*/
Person findPersonById(Integer id);
}
1.5.4 在 service.impl 包下創(chuàng)建 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 接口上加一個(gè) Mapper 注解
@Mapper 作用:mybatis 自動(dòng)掃描數(shù)據(jù)持久層的映射文件及 DAO 接口的關(guān)系
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);
}
注意:默認(rèn)情況下,MyBatis的xml映射文件不會(huì)編譯到target的class目錄下,所以我們需要在pom.xml中配置resource
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>
**/*.xml
</include>
</includes>
</resource>
</resources>
1.6 啟動(dòng)Application應(yīng)用,訪問測試

1.7 在運(yùn)行的主類上添加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);
}
在運(yùn)行主類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);
}
}
運(yùn)行測試結(jié)果

1.8 接口和映射文件分開
- 修改GeneratorMapper.xml 文件中Mapper映射文件生成目標(biāo)位置, 目標(biāo)指向resources下的mapper文件夾下
<!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的包名, targetProject 指定生成的 mapper.xml 放在哪個(gè)工程下面 -->
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
- 重新運(yùn)行代碼生成插件

把之前生成的映射文件刪除掉
- 在application.yml配置文件中需要指定映射文件的位置,這個(gè)配置只有接口和映射文件不再同一個(gè)包的情況下,才需要指定
mybatis:
mapper-locations: classpath:mapper/*.xml
2. SpringBoot的事務(wù)支持
SpringBoot 使用事務(wù)非常簡單,底層依然采用的是Spring本身提供的事務(wù)管理
在入口類中使用注解@EnableTransactionManagement 開啟事務(wù)支持
在訪問數(shù)據(jù)庫的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接口中添加更新用戶的方法
/**
* 根據(jù)用戶id更新用戶信息
* @param person
* @return
*/
int updatePersonById(Person person);
在PersonServiceImpl接口實(shí)現(xiàn)類中更新用戶信息方法進(jìn)行實(shí)現(xiàn),并主動(dòng)制造一個(gè)異常拋出
@Override
public int updatePersonById(Person person) {
int updateCount = personMapper.updateByPrimaryKeySelective(person);
System.out.println("更新結(jié)果:" + updateCount);
//在此構(gòu)造一個(gè)除數(shù)為 0 的異常,測試事務(wù)是否起作用
int a = 10/0;
return updateCount;
}
運(yùn)行并測試未開啟事務(wù)的情況


拋出了異常但是數(shù)據(jù)修改成功了,我們需要做的是在動(dòng)作出現(xiàn)異常時(shí),所有的增刪改的操作都要回滾
在PersonServiceImpl更新的實(shí)現(xiàn)方法上添加@Transactional注解
@Override
@Transactional
public int updatePersonById(Person person) {
int updateCount = personMapper.updateByPrimaryKeySelective(person);
System.out.println("更新結(jié)果:" + updateCount);
//在此構(gòu)造一個(gè)除數(shù)為 0 的異常,測試事務(wù)是否起作用
int a = 10/0;
return updateCount;
}
在Application類上加@EnableTransactionManagement注解開始事務(wù)支持
@SpringBootApplication
@MapperScan("com.mufeng.springbootweb.mapper")
@EnableTransactionManagement
public class SpringbootWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebApplication.class, args);
}
}
@EnableTransactionManagement是可選的,但是業(yè)務(wù)方法上必須添加@Transactional事務(wù)才生效
修改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;
}
運(yùn)行測試


同樣拋出了異常,但是數(shù)據(jù)庫的年齡信息還是之前的20,并沒有被修改,說明我們的事務(wù)開啟成功了
