前言
很多人在做ORM框架選型的時(shí)候,都在猶豫:Mybatis定硝、Mybatis plus皿桑、Spring data JPA 如何選?尤其是Mybatis系列和Spring data JPA如何選蔬啡。經(jīng)過筆者在實(shí)際項(xiàng)目中使用诲侮,極力推薦Mybatis plus。理由如下:
- Spring data JPA 提供標(biāo)準(zhǔn)化API箱蟆,如MySQL沟绪、Oracle、Elasticsearch都支持空猜。一些簡(jiǎn)單的CURD擼起代碼來(lái)還是很爽绽慈。但復(fù)雜的查詢恨旱,比起Mybatis Plus、Nutz等ORM框架坝疼,復(fù)雜很多搜贤,沒那么容易上手。另外裙士,自定義SQL方面,復(fù)雜一點(diǎn)的SQL管毙,在注解里面來(lái)表達(dá)腿椎,很不美觀,也不易于維護(hù)夭咬。
- Spring data JPA 底層是使用 Hibernate 的 JPA 技術(shù)實(shí)現(xiàn)啃炸,服務(wù)啟動(dòng)真的是巨慢無(wú)比,尤其是在表很多的時(shí)候卓舵。但應(yīng)該有解決辦法南用,當(dāng)時(shí)沒有時(shí)間研究。
- 如果選擇了Mybatis掏湾、那何必不選擇Mybatis plus呢裹虫?Mybatis plus只做增強(qiáng)不做改變,真的是潤(rùn)物細(xì)如聲融击。很多簡(jiǎn)單的CURD直接條件構(gòu)造器完成筑公,省去了很多xml代碼。如果又想寫復(fù)雜的SQL秀一秀尊浪,可以去xml定義SQL匣屡,就跟Mybatis一樣!
如何集成
Step1: 引入相關(guān)jar依賴
<!-- Spring Boot Mybatis plus 依賴 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!-- Spring Boot Dynamic Datasource 依賴 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>2.5.6</version>
</dependency>
<!-- MySQL 連接驅(qū)動(dòng)依賴 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!-- Druid 連接池管理依賴 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.18</version>
</dependency>
Step2:數(shù)據(jù)源配置拇涤。我這里舉例:db1-master捣作、db1-slave、db2-slave這種在實(shí)際項(xiàng)目中遇到的場(chǎng)景:寫主庫(kù)鹅士、讀從庫(kù)券躁,甚至還依賴別的庫(kù)。
spring:
application:
name: spring-demo
# DB 配置
datasource:
dynamic:
primary: db1-master
p6spy: true
druid:
initial-size: 5
min-idle: 5
max-active: 20
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
validation-query-timeout: 2
filters: stat,wall,slf4j
datasource:
# db1-主庫(kù)數(shù)據(jù)源
db1-master:
url: jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true
username: root
password: 123456
# db1-從數(shù)據(jù)源
db1-slave:
url: jdbc:mysql://localhost:3306/user2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true
username: root
password: 123456
# db2-從數(shù)據(jù)源
db2-slave:
url: jdbc:mysql://localhost:3006/user3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
username: root
password: 123456
Step3:@MapperScan 聲明掉盅。我這里放到了 MybatisPlusConfig 類里嘱朽,如果你高興,@MapperScan 也可以定義到啟動(dòng)的Main方法類里怔接。
package com.yb.demo.config.db;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author daoshenzzg@163.com
* @date 2019-09-05 09:41
*/
@Configuration
@MapperScan({"com.yb.demo.dao.mapper"})
public class MybatisPlusConfig {
/**
* 分頁(yè)插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLimit(100);
return paginationInterceptor;
}
}
Step4:定義Model實(shí)體搪泳。@TableName 對(duì)應(yīng)的就是表名,字段對(duì)應(yīng)表的字段扼脐,表字段是下劃線隔開岸军,實(shí)體類直接是駝峰了奋刽,具體見配置文件:capital-mode: true。
package com.yb.demo.pojo.model.db1;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @author daoshenzzg@163.com
* @date 2019-08-05 17:58
*/
@Data
@TableName("student")
public class Student1DO {
private Long id;
private String studName;
private Integer studAge;
private String studSex;
@TableField(fill = FieldFill.INSERT)
private Integer createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Integer updateTime;
}
Step5:自動(dòng)填充艰赞。上面的 @TableField(fill = FieldFill.INSERT)佣谐、@TableField(fill = FieldFill.INSERT_UPDATE) 估計(jì)有同學(xué)就在好奇,這是干什么用的方妖。這其實(shí)是Mybatis plus的自動(dòng)填充注解標(biāo)記狭魂。配置 MetaObjectHandler 使用,可以做到自動(dòng)填充字段的效果党觅。
package com.yb.demo.config.db;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
/**
* @author daoshenzzg@163.com
* @date 2019-09-04 17:08
*/
@Component
public class DefaultMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", (int) System.currentTimeMillis() / 1000, metaObject);
this.setFieldValByName("updateTime", (int) System.currentTimeMillis() / 1000, metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", (int) System.currentTimeMillis() / 1000, metaObject);
}
}
Step6:定義Mapper雌澄。其中@DS注解可以明確指定使用哪個(gè)數(shù)據(jù)源,用以實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源配置杯瞻。如果是同一數(shù)據(jù)源镐牺,實(shí)體類都一樣,只是有主從之分魁莉,如何切換呢睬涧?其實(shí)也簡(jiǎn)單:只需要在調(diào)用該mapper的service方法上加上 @DS("db1-master") 或 @DS("db1-slave") 就可以完成主從切換了。
package com.yb.demo.dao.mapper.db1;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yb.demo.pojo.model.db1.Student1DO;
import org.springframework.stereotype.Repository;
/**
* @author daoshenzzg@163.com
* @date 2019-08-05 17:56
*/
@DS("db1-master")
@Repository
public interface Student1Mapper extends BaseMapper<Student1DO> {
}
Step7:XML配置旗唁,如果你愿意畦浓,幾乎不需要寫任何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="com.yb.demo.dao.mapper.db1.Student1Mapper">
</mapper>
Step8:如何做到的呢检疫?Mybatis plus 支持條件構(gòu)造器宅粥。
@Slf4j
@Service
public class StudentService extends ServiceImpl<Student1Mapper, Student1DO> {
/**
* 學(xué)生列表
*
* @return
*/
public List<Student1DO> listStudent(String studName) {
QueryWrapper<Student1DO> queryWrapper = new QueryWrapper<>();
queryWrapper.like("student_name", studName);
return super.list(queryWrapper);
}
}
Step9:分頁(yè)也不需要寫任何xml代碼!电谣!
@Slf4j
@Service
public class StudentService extends ServiceImpl<Student1Mapper, Student1DO> {
/**
* 學(xué)生列表
*
* @return
*/
public IPage<Student1DO> listStudentByPage(String studName, int pageNum, int pageSize) {
Page<Student1DO> page = new Page<>(pageNum, pageSize);
QueryWrapper<Student1DO> queryWrapper = new QueryWrapper<>();
queryWrapper.like("student_name", studName);
return super.page(page, queryWrapper);
}
}
Step10:很關(guān)鍵的一步秽梅。@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
package com.yb.demo;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author daoshenzzg@163.com
* @date 2019-08-05 16:19
*/
@EnableTransactionManagement
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
結(jié)束語(yǔ)
實(shí)際開發(fā)過程中,使用Mybatis plus基礎(chǔ)的CURD方法及條件構(gòu)造器剿牺,可以提升許多開發(fā)效率企垦。