Java EE 目錄:https://blog.csdn.net/dkbnull/article/details/87932809
Spring Boot 專欄:https://blog.csdn.net/dkbnull/category_9278145.html
Spring Cloud 專欄:https://blog.csdn.net/dkbnull/category_9287932.html
0. 開發環境
- IDE:IntelliJ IDEA 2017.1 x64
- jdk:1.8.0_91
- Spring Boot:2.1.1.RELEASE
- Maven:3.3.9
- MySQL:5.7.13
1. 引入依賴
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
<scope>runtime</scope>
</dependency>
這裏,如果使用的 MySQL 是 8.X版本的話,mysql-connector-java 版本必須是 8.0以上,否則會報錯:
java.sql.SQLException: Unable to load authentication plugin 'caching_sha2_password'.
2. 引入數據源
這裏根據個人習慣使用 properties 或 yml 文件配置,本項目使用的是更爲簡潔的 yml 配置文件。
刪除原來的 application.properties ,新建 application.yml。
application.yml 增加如下配置信息
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
這裏,如果使用的 mysql-connector-java 是5.X版本的話,driver-class-name 可以直接省略使用默認,或者配置爲 com.mysql.jdbc.Driver
到這裏,Spring Boot就可以訪問數據庫了,我們來做下測試。
3. 測試
3.1 新建數據庫表
CREATE SCHEMA `test` ;
CREATE TABLE `test`.`test` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
INSERT INTO `test`.`test` (`name`) VALUES ('張三');
INSERT INTO `test`.`test` (`name`) VALUES ('李四');
INSERT INTO `test`.`test` (`name`) VALUES ('王五');
INSERT INTO `test`.`test` (`name`) VALUES ('週六');
3.2 創建實體
package cn.wbnull.springbootdemo.model;
public class TestModel {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.3 DAO層
package cn.wbnull.springbootdemo.dao;
import cn.wbnull.springbootdemo.model.TestModel;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface TestMapper {
@Select("select id,name from test")
List<TestModel> select();
@Insert("insert into test(name) values(#{name})")
int insert(@Param("name") String name);
}
3.4 Service層
package cn.wbnull.springbootdemo.service;
import cn.wbnull.springbootdemo.dao.TestMapper;
import cn.wbnull.springbootdemo.model.TestModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MySQLTestService {
@Autowired
private TestMapper testMapper; //這裏會有報錯,不用管
public List<TestModel> select() {
return testMapper.select();
}
public int insert(String name) {
return testMapper.insert(name);
}
}
這裏使用 @Autowired 自動裝配TestMapper時會有報錯,原因是TestMapper使用了@Mapper註解,idea不能把@Mapper註解的TestMapper識別爲Bean,但實際運行時@Mapper會被Spring識別爲Bean,自動裝配不會出錯。所以這裏的報錯可以不用在意。
但如果看着代碼中有報錯很不順眼,可以在TestMapper類增加@Repository註解,標註該類爲DAO組件。
3.5 Controller層
package cn.wbnull.springbootdemo.controller;
import cn.wbnull.springbootdemo.model.TestModel;
import cn.wbnull.springbootdemo.service.MySQLTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Scope("prototype")
@RequestMapping("/mysql/test")
public class MySQLTestController {
@Autowired
private MySQLTestService mySQLTestService;
@PostMapping(value = "/select")
public List<TestModel> select() throws Exception {
return mySQLTestService.select();
}
@PostMapping(value = "/insert")
public int insert(@RequestParam(value = "name") String name) throws Exception {
return mySQLTestService.insert(name);
}
}
3.6 測試
使用Postman進行測試,輸出結果如下
3.6.1 select
3.6.2 insert
Postman接收到輸出爲1,表示成功,我們去查下數據庫
數據成功插入。
4. MyBatis映射文件
以上,我們訪問數據庫時,SQL語句還是寫死在代碼裏面,處理起來並沒有很方便。通常,我們把SQL語句與代碼分離,使用MyBatis映射文件方式來訪問數據庫。
4.1 MyBatis配置
我們在resources文件夾下新建mapper文件夾,用於存放MyBatis映射文件
application.yml 增加MyBatis配置信息
mybatis:
mapper-locations: classpath:mapper/*.xml #對應mapper映射xml文件所在路徑
type-aliases-package: cn.wbnull.springbootdemo.model #對應實體類路徑
完整配置如下,注意spring與mybatis都是根節點
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
#
mybatis:
mapper-locations: classpath:mapper/*.xml #對應mapper映射xml文件所在路徑
type-aliases-package: cn.wbnull.springbootdemo.model #對應實體類路徑
4.2 DAO層
我們創建一個新的DAO類
package cn.wbnull.springbootdemo.dao;
import cn.wbnull.springbootdemo.model.TestModel;
import java.util.List;
public interface TestMapperV2 {
List<TestModel> select();
int insert(TestModel testModel);
}
4.3 創建MyBatis映射文件
resources/mapper下新建映射文件 TestMapper.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" >
<mapper namespace="cn.wbnull.springbootdemo.dao.TestMapperV2">
<resultMap id="BaseResultMap" type="cn.wbnull.springbootdemo.model.TestModel">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id, name
</sql>
<select id="select" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from test
</select>
<insert id="insert" parameterType="cn.wbnull.springbootdemo.model.TestModel">
insert into test (id, name
)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}
)
</insert>
</mapper>
這裏着重注意這幾點
1、<mapper namespace=“cn.wbnull.springbootdemo.dao.TestMapperV2”> namespace 一定要對應自己dao包所在的包路徑,對應我們需要匹配的dao層類
2、<resultMap id=“BaseResultMap” type=“cn.wbnull.springbootdemo.model.TestModel”> type 一定要對應我們需要匹配的實體類
3、 <id column=“id” property=“id” jdbcType=“INTEGER”/>
<result column=“name” property=“name” jdbcType=“VARCHAR”/>
對應數據庫表的字段
4、<select id=“select” resultMap=“BaseResultMap”>
select <include refid=“Base_Column_List”/> from test
</select>
<select> 表示這是一條查詢語句, id=“select” 一定要與dao層需要匹配的方法名一致,resultMap 表示對應的返回值類型
5、<insert id=“insert” parameterType=“cn.wbnull.springbootdemo.model.TestModel”> parameterType表示對應的輸入參數類型
4.4 Service層
創建一個新的Service類
package cn.wbnull.springbootdemo.service;
import cn.wbnull.springbootdemo.dao.TestMapperV2;
import cn.wbnull.springbootdemo.model.TestModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MySQLTestServiceV2 {
@Autowired
private TestMapperV2 testMapperV2; //這裏會有報錯,不用管
public List<TestModel> select() {
return testMapperV2.select();
}
public int insert(int id, String name) {
TestModel testModel = new TestModel();
testModel.setId(id);
testModel.setName(name);
return testMapperV2.insert(testModel);
}
}
4.5 Controller層
創建一個新的Controller類
package cn.wbnull.springbootdemo.controller;
import cn.wbnull.springbootdemo.model.TestModel;
import cn.wbnull.springbootdemo.service.MySQLTestServiceV2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Scope("prototype")
@RequestMapping("/mysql/test")
public class MySQLTestControllerV2 {
@Autowired
private MySQLTestServiceV2 mySQLTestServiceV2;
@PostMapping(value = "/selectV2")
public List<TestModel> select() throws Exception {
return mySQLTestServiceV2.select();
}
@PostMapping(value = "/insertV2")
public int insert(@RequestParam(value = "id") int id,
@RequestParam(value = "name") String name) throws Exception {
return mySQLTestServiceV2.insert(id, name);
}
}
4.6 項目啓動類
增加@MapperScan(“cn.wbnull.springbootdemo.dao”),對應DAO層的包名
package cn.wbnull.springbootdemo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("cn.wbnull.springbootdemo.dao")
public class SpringBootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
4.7 測試
4.7.1 select
4.7.2 insert
Postman接收到輸出爲1,表示成功,我們去查下數據庫
數據成功插入
截至這裏,Spring Boot已成功整合MyBatis並連接上了數據庫,且測試正常。
但我們實際開發過程中,如果存在大量數據庫表,那我們就需要創建大量的實體類、DAO層、映射文件,工作量較大。我們使用mybatis generator來自動生成代碼。
5. Generator
5.1 新建數據庫表
我們先新建一個數據庫表,便於一會自動生成代碼使用
CREATE TABLE `test`.`testv2` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
5.2 Generator配置文件
在resources文件夾下新建generator文件夾,新建generatorConfig.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>
<!--數據庫驅動,選擇本地硬盤上的數據庫驅動包,建議與pom.xml引入的jar包版本相同-->
<classPathEntry
location="D:\Program Files\Maven\repository\mysql\mysql-connector-java\8.0.15\mysql-connector-java-8.0.15.jar"/>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<!--是否去除自動生成的註釋,true:是 false:否-->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--數據庫驅動類、鏈接url、用戶名、密碼,與application.yml配置相同即可-->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8"
userId="root"
password="root">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成實體類的包名和位置-->
<javaModelGenerator targetPackage="cn.wbnull.springbootdemo.model"
targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射文件的包名和位置-->
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成DAO的包名和位置-->
<javaClientGenerator type="XMLMAPPER"
targetPackage="cn.wbnull.springbootdemo.dao"
targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!--需要自動生成代碼的數據庫表
tableName表示數據庫中的表名或視圖名 domainObjectName表示實體類名-->
<table tableName="testv2" domainObjectName="TestV2"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
5.3 引入依賴
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>
5.4 Generator配置
1、Run --> Edit Configurations…
2、增加Maven配置
3、增加Generator配置 (mybatis-generator:generate -e),OK
4、運行
生成代碼如下。這裏我們運行成功後,同一個表,不要運行多次,否則mapper映射文件中會生成多次的代碼。
package cn.wbnull.springbootdemo.model;
public class TestV2 {
private Integer id;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username == null ? null : username.trim();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
}
package cn.wbnull.springbootdemo.dao;
import cn.wbnull.springbootdemo.model.TestV2;
public interface TestV2Mapper {
int insert(TestV2 record);
int insertSelective(TestV2 record);
}
<?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" >
<mapper namespace="cn.wbnull.springbootdemo.dao.TestV2Mapper" >
<resultMap id="BaseResultMap" type="cn.wbnull.springbootdemo.model.TestV2" >
<result column="id" property="id" jdbcType="INTEGER" />
<result column="username" property="username" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
</resultMap>
<insert id="insert" parameterType="cn.wbnull.springbootdemo.model.TestV2" >
insert into testv2 (id, username, password
)
values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}
)
</insert>
<insert id="insertSelective" parameterType="cn.wbnull.springbootdemo.model.TestV2" >
insert into testv2
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="username != null" >
username,
</if>
<if test="password != null" >
password,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="username != null" >
#{username,jdbcType=VARCHAR},
</if>
<if test="password != null" >
#{password,jdbcType=VARCHAR},
</if>
</trim>
</insert>
</mapper>
5.5 測試
5.5.1 Service層
package cn.wbnull.springbootdemo.service;
import cn.wbnull.springbootdemo.dao.TestV2Mapper;
import cn.wbnull.springbootdemo.model.TestV2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MySQLTestV2Service {
@Autowired
private TestV2Mapper testV2Mapper; //這裏會有報錯,不用管
public int insert(int id, String username, String password) {
TestV2 testV2 = new TestV2();
testV2.setId(id);
testV2.setUsername(username);
testV2.setPassword(password);
return testV2Mapper.insert(testV2);
}
}
5.5.1 Controller層
package cn.wbnull.springbootdemo.controller;
import cn.wbnull.springbootdemo.service.MySQLTestV2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Scope("prototype")
@RequestMapping("/mysql/testv2")
public class MySQLTestV2Controller {
@Autowired
private MySQLTestV2Service mySQLTestV2Service;
@PostMapping(value = "/insert")
public int insert(@RequestParam(value = "id") int id,
@RequestParam(value = "username") String username,
@RequestParam(value = "password") String password
) throws Exception {
return mySQLTestV2Service.insert(id, username, password);
}
}
5.5.2 insert
Postman接收到輸出爲1,表示成功,我們去查下數據庫
數據成功插入
這樣,對於大量的數據庫表,我們就可以使用Generator來生成基本的代碼,然後自己再添加其他所需要的代碼即可。
GitHub:https://github.com/dkbnull/SpringBootDemo
微信:https://mp.weixin.qq.com/s/TVtmbSBrctv9R9EucIggYg
微博:https://weibo.com/ttarticle/p/show?id=2309404339889012367676
知乎:https://zhuanlan.zhihu.com/p/95635187