Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式

前言

整合Mybtis對於Spring Boot來說,是非常簡單的, 通過這一篇文章, 你可以無壓力快速入門,不過開始之前我要說一下我的版本信息:

  • maven 3.2.5

  • jdk 1.8

  • Spring Boot 2.1.6

創建項目

依然是使用idea的自動化配置, 不過這裏,我們需要勾選以下依賴:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


如果你勾選了 MyBatis , 你會發現你的pom文件裏有 :

		<dependency>
 <groupId>org.mybatis.spring.boot</groupId>
 <artifactId>mybatis-spring-boot-starter</artifactId>
 <version>2.1.0</version>
 </dependency>

這條依賴

只要是帶 *-spring-boot-starter的,都是Spring Boot官方推薦的, 這裏的mybatis就是, 讓我們來看一下mybatis包下的所有包:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


我們發現它引入了, mybatis-spring 的包等等,以及還有mybatis-spring-boot-autoconfigure, 這個是自動配置的意思, 對於Spring Boot來說,自動配置是一大特點

配置Druid數據源

Spring Boot2.x的數據源 hikari 的, 而1.x則是 Tomcat的, 所以我們要配置以下自己的數據源

 <dependency>
 <groupId>com.alibaba</groupId>
 <artifactId>druid</artifactId>
 <version>1.1.16</version>
 </dependency>

引入這個依賴就好了

然後在 application.yml 配置文件下:

spring:
 datasource:
 password: root
 username: root
 url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
 driver-class-name: com.mysql.cj.jdbc.Driver
 type: com.alibaba.druid.pool.DruidDataSource
 initialSize: 5
 minIdle: 5
 maxActive: 20
 maxWait: 60000
 timeBetweenEvictionRunsMillis: 60000
 minEvictableIdleTimeMillis: 300000
 validationQuery: SELECT 1 FROM DUAL
 testWhileIdle: true
 testOnBorrow: false
 testOnReturn: false
 poolPreparedStatements: true
 # 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用於防火牆
 filters: stat,wall,log4j
 maxPoolPreparedStatementPerConnectionSize: 20
 useGlobalDataSourceStat: true
 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

下面這一堆的屬性是不生效的, 如果想要生效, 需要特殊配置一下, Druid監控也配置了:

package com.carson.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DruidConfig {
 @ConfigurationProperties(prefix = "spring.datasource")
 @Bean
 public DataSource druid() {
 return new DruidDataSource();
 }
 // 配置 Druid 監控
 //1) 配置一個管理後臺的Servlet
 @Bean
 public ServletRegistrationBean statViewServlet() {
 ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
 Map<String, String> initParams = new HashMap<>();
 // 這裏是 druid monitor(監視器)的 賬號密碼, 可以任意設置
 initParams.put("loginUsername", "admin");
 initParams.put("loginPassword", "123456");
 initParams.put("allow", "");
 initParams.put("deny", "192.123.11.11");
 // 設置初始化參數
 bean.setInitParameters(initParams);
 return bean;
 }
 // 2)配置一個監控的 filter
 @Bean
 public FilterRegistrationBean webStatFilter() {
 FilterRegistrationBean bean = new FilterRegistrationBean();
 bean.setFilter(new WebStatFilter());
 Map<String, String> initParams = new HashMap<>();
 initParams.put("exclusions","*.js,*.css,/druid/*");
 bean.setInitParameters(initParams);
 bean.setUrlPatterns(Arrays.asList("/*"));
 return bean;
 }
}

啓動主類, 查看是否可以進入到 德魯伊監視器, 如果你報錯了請添加 log4j 依賴:

 <dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <version>1.2.17</version>
 </dependency>
<!--我也不清楚爲什麼, 不加log4j的話就會報錯-->

查看效果:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


利用SpringBoot建表

然後在 resources/sql 下引入兩個建表的sql文件:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


  • department.sql:

SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for department
-- ----------------------------
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `departmentName` VARCHAR(255) DEFAULT NULL,
 PRIMARY KEY (`id`)
)
 ENGINE = InnoDB
 AUTO_INCREMENT = 1
 DEFAULT CHARSET = utf8;
  • employee.sql:

SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `lastName` VARCHAR(255) DEFAULT NULL,
 `email` VARCHAR(255) DEFAULT NULL,
 `gender` INT(2) DEFAULT NULL,
 `d_id` INT(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
)
 ENGINE = InnoDB
 AUTO_INCREMENT = 1
 DEFAULT CHARSET = utf8;

並且在 application.yml 文件下寫入:

 schema:
 - classpath:sql/department.sql
 - classpath:sql/employee.sql
 initialization-mode: always

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


schema`是與 password/username 等等同級的,哦對了, 如果你是 springboot 2.x版本以上的, 你可能需要加上initialization-mode這個屬性。

運行主類, 查看是否建表成功,

如果你的程序在設置sql文件後 啓動報錯了:

  • 重啓 idea (重啓大法好啊!)

  • 查看 schema是否配置對了 sql文件的名字

  • schema:

  • -(空格)classpath:sql/xxx.sql

  • 注意格式

對應數據庫實體類

  • Employee.java

package com.carson.domain;
public class Employee {
 private Integer id;
 private String lastName;
 private Integer gender;
 private String email;
 private Integer dId;
 public Integer getId() {
 return id;
 }
 public void setId(Integer id) {
 this.id = id;
 }
 public String getLastName() {
 return lastName;
 }
 public void setLastName(String lastName) {
 this.lastName = lastName;
 }
 public Integer getGender() {
 return gender;
 }
 public void setGender(Integer gender) {
 this.gender = gender;
 }
 public String getEmail() {
 return email;
 }
 public void setEmail(String email) {
 this.email = email;
 }
 public Integer getdId() {
 return dId;
 }
 public void setdId(Integer dId) {
 this.dId = dId;
 }
}
  • Department.java

package com.carson.domain;
public class Department {
 private Integer id;
 private String departmentName;
 public Integer getId() {
 return id;
 }
 public void setId(Integer id) {
 this.id = id;
 }
 public String getDepartmentName() {
 return departmentName;
 }
 public void setDepartmentName(String departmentName) {
 this.departmentName = departmentName;
 }
}

記得把剛纔我配置文件的 schema屬性全部註釋掉, 我們不希望下次運行的時候會再次創建表

數據庫交互

- 註解版

  • 建立一個 Mapper, 把sql語句直接寫在上面

package com.carson.mapper;
import com.carson.domain.Department;
import org.apache.ibatis.annotations.*;
// 指定這是一個 mapper
@Mapper
public interface DepartmentMapper {
 @Select("select * from department where id=#{id}")
 public Department getDepById(Integer id);
 @Delete("delete from department where id=#{id}")
 public int deleteDepById(Integer id);
 @Insert("insert into department(departmentName) values(#{departmentName})")
 public int insertDept(Department department);
 @Update("update department set departmentName=#{departmentName} where id=#{id}")
 public int updateDept(Department department);
}

然後寫一個Controller :

package com.carson.controller;
import com.carson.domain.Department;
import com.carson.mapper.DepartmentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController // 代表返回 json 數據的 controller
public class DeptController {
 @Autowired
 DepartmentMapper departmentMapper;
 @GetMapping("/dept/{id}")
 public Department getDept(@PathVariable("id") Integer id) {
 return departmentMapper.getDepById(id);
 }
 @GetMapping
 public Department inserDept(Department department) {
 departmentMapper.insertDept(department);
 return department;
 }
}
  • 通過 @PathVariable 可以將 URL 中佔位符參數綁定到控制器處理方法的入參中:URL 中的 {xxx} 佔位符可以通過@PathVariable(“xxx“) 綁定到操作方法的入參中。

啓動主類, 輸入這個: localhost:8080/dept?departmentName=AA , 這是往數據庫增加一條數據:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


然後查詢: localhost:8080/dept/3 , 我數據庫id是3, 所以我要查詢3:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


不過發現一個問題, 在插入數據的時候獲取不到 id:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


所以我們要使用一個@Options註解:

 @Options(useGeneratedKeys = true,keyProperty = "id")
 @Insert("insert into department(departmentName) values(#{departmentName})")
 public int insertDept(Department department);

添加到剛纔 mapper中insert 的 @value註解上面

  • useGeneratedKeys : 使用生成的主鍵

  • keyProperty: 意思是 Department 裏面的哪個屬性是主鍵, 就是我們的 id

試着插入一條數據:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


但是實際忘記註釋掉 schema , 導致每次運行都會重新創建數據庫, 各位要注意

還有一個問題

我們把數據庫的字段名改成 department_name 而實體類是departmentName;

並且把sql語句也改正

 @Options(useGeneratedKeys = true,keyProperty = "id")
 @Insert("insert into department(department_name) values(#{departmentName})")
 public int insertDept(Department department);
 @Update("update department set department_name=#{departmentName} where id=#{id}")
 public int updateDept(Department department);

然後在進行查詢操作的話:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


我們發現獲取不到 departmentName 了, 以前Spring 我們是使用配置文件來應對這種情況的, 但是我們現在沒有了xml文件,我們該怎麼辦呢?

世上無難事

創建自定義配置類:

package com.carson.config;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisConfig {
 @Bean
 public ConfigurationCustomizer configurationCustomizer() {
 return new ConfigurationCustomizer() {
 @Override
 public void customize(org.apache.ibatis.session.Configuration configuration) 			 {
 configuration.setMapUnderscoreToCamelCase(true);
 }
 };
 }
}

注意這裏面的 setMapUnderscoreToCamelCase,意思是:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


翻譯大法好啊, 我的英文太差了, 再次訪問 http://localhost:8080/dept/1 查詢操作, 我發現已經不是 null了:

{"id":1,"departmentName":"jackMa"}

馬總正確的展現出來了!

MapperScan註解

掃描器, 用來掃描mapper接口的

我把它標記到 啓動類 上(你可以標記在任何地方):

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


指定一個包,它會掃描這個包下所有的 mapper 接口, 防止你的mapper文件太多, 並且忘記加 @mapper 註解, 這樣可以提高正確性

- 配置文件版

註解版貌似很方便, 但是如果遇到複雜的sql , 比如動態sql等等, 還是需要用 xml 配置文件的;

創建一個 Employee 的Mapper接口:

package com.carson.mapper;
import com.carson.domain.Employee;
public interface EmployeeMapper {
 public Employee getEmpById(Integer id);
 public void insertEmp(Employee employee);
}

在 resources/mybatis 下創建一個 mybatis-config.xml 全局配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>

在 resources/mybatis/mapper 包下創建 EmployeeMapper.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">
<!-- 綁定接口 並且寫兩條 SQL 語句-->
<mapper namespace="com.carson.mapper.EmployeeMapper">
 <select id="getEmpById" resultType="com.carson.domain.Employee">
 select * from employee where id = #{id}
 </select>
 <insert id="insertEmp">
 insert into employee(lastName,email,gender,d_id) values (#{lastName},	 		#{email},#{gender},#{d_id})
 </insert>
</mapper>

然後再 application.yml 配置文件下添加一條配置:

# mybatis屬性是跟 spring 屬性平級的, 千萬不要把格式搞錯
mybatis:
# 指定全局配置文件
 config-location: classpath:mybatis/mybatis-config.xml
# 指定 mapper 映射文件, * 代表所有 
 mapper-locations: classpath:mybatis/mapper/*.xml

讓我們在剛纔的DeptController類裏添加一段 Controller :

 @Autowired
 EmployeeMapper employeeMapper
 
 @GetMapping("emp/{id}")
 public Employee getEmp(@PathVariable("id") Integer id) {
 return employeeMapper.getEmpById(id);
 }

啓動主類訪問一下 localhost:8080/emp/1 , 查看結果:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


我們發現 dId沒有查詢出來, 這是因爲 數據庫字段是 d_id , 而java裏是 dId , 所以我們要像剛纔註解版一樣, 配置一樣東西, 讓我們打開 mapper全局配置文件添加:

<?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
 <settings>
 <setting name="mapUnderscoreToCamelCase" value="true"/>
 </settings>
</configuration>

mapUnderscoreToCamelCase : 是否開啓自動駝峯命名規則(camel case)映射,即從經典數據庫列名 A_COLUMN 到經典 Java 屬性名 aColumn 的類似映射。

再次試驗:

Spring Boot-甜蜜的整合MyBatis&註解方式&配置方式


可以看出已經成功了

無論是哪種版本. 要根據自己的實際情況來定, 註解雖然方便, 但是複雜業務的就不行了


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章