本教程主要詳細講解SpringBoot整合MyBatis進行數據庫操作,本次講解我們使用純註解方式進行。
基礎環境
技術 | 版本 |
---|---|
Java | 1.8+ |
SpringBoot | 2.x.x |
MyBatis | 3.5.x |
創建項目
- 初始化項目
mvn archetype:generate -DgroupId=com.edurt.sli.slisma -DartifactId=spring-learn-integration-springboot-mybatis-annotations-DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false
- 修改pom.xml增加MyBatis
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-learn-integration-springboot-mybatis</artifactId>
<groupId>com.edurt.sli</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-learn-integration-springboot-mybatis-annotations</artifactId>
<name>SpringBoot整合MyBatis教程(註解版)</name>
<properties>
<system.java.version>1.8</system.java.version>
<plugin.maven.compiler.version>3.3</plugin.maven.compiler.version>
<springboot.common.version>2.1.3.RELEASE</springboot.common.version>
<springboot.mybatis.common.version>2.1.1</springboot.mybatis.common.version>
<mysql.version>5.1.47</mysql.version>
<lombox.version>1.18.8</lombox.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.common.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.common.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${springboot.mybatis.common.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombox.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.common.version}</version>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${plugin.maven.compiler.version}</version>
<configuration>
<source>${system.java.version}</source>
<target>${system.java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
mybatis-spring-boot-starter
:該starter是我們使用SpringBoot整合MyBatis的依賴整合包
- 在
src/main/java
目錄下新建com.edurt.sli.slisma目錄並在該目錄下新建SpringBootMyBatisIntegration
類文件,在文件輸入以下內容
package com.edurt.sli.slisma;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
@SpringBootApplication
@Component(value = "com.edurt.sli.slisma")
public class SpringBootMyBatisIntegration {
public static void main(String[] args) {
SpringApplication.run(SpringBootMyBatisIntegration.class, args);
}
}
構建基本使用的SQL文件
在src/main
目錄下新建example.sql文件,鍵入以下內容
create database spring;
use spring;
drop table if exists user;
create table user (
id int(20) auto_increment,
userName varchar(20),
primary key (id)
)
default charset 'utf8';
我們運行該sql文件進行創建數據庫/數據表操作.
配置MyBatis數據源
- 在
/src/main/java/com/edurt/sli/slisma
目錄下創建config目錄,並在該目錄下新建MyBatisConfig
配置類,鍵入以下代碼
package com.edurt.sli.slisma.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(value = {"com.edurt.sli.slisma.mapper"})
public class MyBatisConfig {
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager(
@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "sqlSessionFactory")
@ConditionalOnMissingBean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
return sessionFactory.getObject();
}
@Bean
ConfigurationCustomizer mybatisConfigurationCustomizer() {
return configuration -> {
configuration.setMapUnderscoreToCamelCase(Boolean.TRUE);
configuration.setLogPrefix("com.edurt.sli.slismat");
};
}
}
該代碼中有3個Bean分別是:transactionManager(用於構建事務管理器),sqlSessionFactory(用於構建sqlSession工廠提供查詢操作),mybatisConfigurationCustomizer(定製化MyBatis信息)
@MapperScan
註解用於指定我們Mapper文件所在的位置
配置Mapper支持數據插入(@Insert
)
- 在
/src/main/java/com/edurt/sli/slisma
目錄下創建model目錄,並在該目錄下新建UserModel
實體類,鍵入以下代碼
package com.edurt.sli.slisma.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class UserModel {
private Integer id;
private String userName;
}
- 在
/src/main/java/com/edurt/sli/slisma
目錄下創建mapper目錄,並在該目錄下新建UserMapper
映射類,用於映射數據庫和實體類,鍵入以下代碼
package com.edurt.sli.slisma.mapper;
import com.edurt.sli.slisma.model.UserModel;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserMapper {
@Insert("INSERT INTO user (username) VALUES (#{user.userName})")
@Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "user.id")
Integer insertModel(@Param(value = "user") UserModel model);
}
我們在Mapper中提供了一個添加數據方法,我們使用到了@Insert
和@Options
註解
@Insert
註解用於標誌我們要進行數據插入操作
@Options
該註解比較特殊,主要是用於標記我們對插入後返回數據的操作,比如我們指定了useGeneratedKeys=true和keyColumn = “id”,這樣的話我們插入數據的時候會自動生成主鍵,keyProperty = "user.id"標記着我們插入數據成功後返回當前插入數據庫表中的id數據.需要注意的是我們如果在傳遞參數的時候使用@Param
修飾參數後,那麼keyProperty需要指定修飾的域名,如果未進行修飾的話,我們可以直接使用實體類中的字段名稱.
- 接下來我們在
/src/test/java
目錄下新建com.edurt.sli.slisma目錄,並在該目錄下新建UserMapperTest測試文件,鍵入以下內容
package com.edurt.sli.slisma.mapper;
import com.edurt.sli.slisma.SpringBootMyBatisIntegration;
import com.edurt.sli.slisma.model.UserModel;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@SpringBootTest(
classes = SpringBootMyBatisIntegration.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
public class UserMapperTest {
private UserModel user;
private String value = "UserMapperTest";
@Autowired
private UserMapper userMapper;
@Before
public void before() {
user = new UserModel();
user.setUserName(value);
}
@After
public void after() {
}
@Test
public void testInsertModel() {
Assert.assertTrue(this.userMapper.insertModel(user) > 0);
}
}
我們在@Before
中初始化了一個新的實體信息
然後使用testInsertModel
方法進行測試我們UserMapper提供的插入數據方法是否有效
- 在
/src/main/resources
資源目錄下創建一個application.properties的配置文件,用於數據庫連接配置,鍵入以下內容
server.port=8989
spring.datasource.url=jdbc:mysql://localhost:3306/spring?useSSL=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
此時我們直接運行單元測試便可看到數據庫表中新增的數據信息
數據查詢操作(@Select
)
- 在
UserMapper
文件中鍵入以下內容支持查詢操作
@Results(value = {
@Result(property = "id", column = "id", id = true),
@Result(property = "userName", column = "username")
})
@Select(value = "SELECT id, username FROM user WHERE username = #{userName}")
UserModel findByUserName(@Param(value = "userName") String userName);
將頂部引入的包import org.apache.ibatis.annotations.XXXX
修改爲import org.apache.ibatis.annotations.*
- 在
UserMapperTest
文件中鍵入以下內容支持數據查詢測試
@Test
public void testFindByUserName() {
Assert.assertNotNull(this.userMapper.findByUserName(value));
}
然後使用testFindByUserName
方法進行測試我們UserMapper提供的查詢數據方法是否有效
數據查詢操作(@Select
)動態條件判斷
我要想使用類似xml中的if-else的話我們需要用到<script></script>
區間塊標誌.
- 修改
UserMapper
文件中鍵入以下內容支持自定義script查詢操作
@Results(value = {
@Result(property = "id", column = "id", id = true),
@Result(property = "userName", column = "username")
})
@Select(value = "<script>" +
"SELECT id, username FROM user WHERE 1=1" +
"<if test='userName != null'> and username=#{userName} </if>" +
"</script>")
UserModel findByUserNameAndCustomScript(@Param(value = "userName") String userName);
我們在<script></script>
區間塊可以使用xml配置中的if語句
- 在
UserMapperTest
文件中鍵入以下內容支持自定義腳本數據查詢測試
@Test
public void testFindByUserNameAndCustomScript() {
Assert.assertNotNull(this.userMapper.findByUserNameAndCustomScript(value));
}
注意: 如果字段類型是String的話test裏面的字符串必需要轉義,如果使用單引號的話是不支持的
數據查詢操作(@Select
)共享Results結果數據
在實際開發中很多時候我們在不同的方法中會返回相同的結果信息,那麼這個時候我們就要使用到了共享Results
結果數據,共享結果數據很簡單,我們只需要修改@Results
在裏面增加id屬性(該id值是唯一的)後期在其他方法中使用即可.
- 修改
UserMapper
文件中的findByUserName方法在@Results
中增加id屬性,內容如下
@Results(id = "userRequiredResults", value = {
@Result(property = "id", column = "id", id = true),
@Result(property = "userName", column = "username")
})
@Select(value = "SELECT id, username FROM user WHERE username = #{userName}")
UserModel findByUserName(@Param(value = "userName") String userName);
我們定義了一個id爲userRequiredResults
的返回全局結果集
- 修改
UserMapper
文件中鍵入以下內容支持共享結果查詢操作
@ResultMap(value = "userRequiredResults")
@Select(value = "<script>" +
"SELECT id, username FROM user WHERE 1=1" +
"<if test='userName != null'> and username=#{userName} </if>" +
"</script>")
UserModel findByUserNameAndCommonResult(@Param(value = "userName") String userName);
注意此時我們使用的是@ResultMap
註解,該註解只有一個屬性,那就是value,指定的是我們需要使用的是返回哪個數據結果集
- 在
UserMapperTest
文件中鍵入以下內容支持共享結果集數據查詢測試
@Test
public void testFindByUserNameAndCommonResult() {
Assert.assertNotNull(this.userMapper.findByUserNameAndCommonResult(value));
}
關於分頁的功能,我們後續會有單獨文章詳解
數據修改操作(@Update
)
- 在
UserMapper
文件中鍵入以下內容支持修改操作
@Update(value = "UPDATE user SET userName = #{user.userName} WHERE id = #{user.id}")
void updateModel(@Param(value = "user") UserModel model);
- 在
UserMapperTest
文件中鍵入以下內容支持數據修改測試
@Test
public void testUpdateModel() {
user.setId(1);
user.setUserName("Modify");
this.userMapper.updateModel(user);
}
運行我們的測試示例,在此查詢即可看到數據已經被修改
目前@Update值只支持返回受影響的行數,只需要修改返回值爲Integer類型即可,不需要的話直接設置爲void
數據刪除操作(@Delete)
- 在
UserMapper
文件中鍵入以下內容支持刪除操作
@Delete(value = "DELETE FROM user WHERE id = #{id}")
Integer deleteModel(@Param(value = "id") Integer id);
- 在
UserMapperTest
文件中鍵入以下內容支持數據刪除測試
@Test
public void testDeleteModel() {
this.userMapper.deleteModel(1);
}
目前@Delete值只支持返回受影響的行數,只需要修改返回值爲Integer類型即可,不需要的話直接設置爲void
在MyBatis中
@Select
,@Update
,@Delete
,@Insert
都是支持自定義script的
打包文件部署
- 打包數據
mvn clean package -Dmaven.test.skip=true -X
運行打包後的文件即可
java -jar target/spring-learn-integration-springboot-mybatis-annotations-1.0.0.jar