Springboot整合通用mapper
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質(zhì)文章,第一時間送達
引言
我第一次整合orm框架的時候,本來使用jpa,多表聯(lián)查比較麻煩(只是單純的使用,沒深入使用,可能有比較好的方法使用,我沒用到),單純使用mybatis,寫單純的crud的方法,感覺自己手寫太麻煩,如果用mybatis的逆向工程,它又給你生成各種方法,我覺得很煩。那有沒有一個框架可以簡簡單單的讓我不需要太多的東西就可以使用單表的操作呢,我發(fā)現(xiàn)了通用mapper。(后來其實發(fā)現(xiàn),mybatis-plus兩個思路大同小異,都挺好的。)
一、導入依賴
????
????????
????????????tk.mybatis
????????????mapper
????????????4.1.5
????????
????????
????????????tk.mybatis
????????????mapper-spring-boot-starter
????????????2.1.5
????????
????????
???????
????????????org.mybatis.generator
????????????mybatis-generator-core
????????????1.3.6
????????
????????
????????????org.mybatis.spring.boot
????????????mybatis-spring-boot-starter
????????????2.1.0
????????
????????
????????????mysql
????????????mysql-connector-java
????????????runtime
????????
????????
????????????org.springframework.boot
????????????spring-boot-starter-jdbc
????????
????????
????????????com.github.pagehelper
????????????pagehelper-spring-boot-starter
????????????1.2.5
????????
????????
????????????org.springframework.boot
????????????spring-boot-starter-test
????????
????????
?????????
??????????
????????????org.mybatis.generator
????????????mybatis-generator-core
????????????1.3.6
????????
????????
????????????org.springframework.boot
????????????spring-boot-starter-freemarker
????????
?????????
??????????
????????????org.springframework.boot
????????????spring-boot-starter-web
????????
第一部分核心依賴,第二部分是一些配套的,看你需求。我是用mybatis的逆向工程的
二、啟動類添加注解
@MapperScan(value?=?"com.xyo.it.service.**.mapper")
注意,這個是import tk.mybatis.spring.annotation.MapperScan;掃描的你的mapper,注意通配符的使用
三、yaml
mybatis:
??????mapper-locations:?classpath:mapping/**/*Mapper.xml
??????type-aliases-package:?com.xyo.it.*.entity
這個應(yīng)該是mybatis的注解,用于掃描xml的吧?
四、使用
前面都不是重點,重點在使用,幫我們做到了什么。
1. 繼承通用的Mapper,必須指定泛型
public?interface?RecordMapper?extends?BaseMapper?{
}
一旦繼承了Mapper,繼承的Mapper就擁有了Mapper所有的通用方法。
里面包含了幾乎所有的單表的crud方法。而查詢的話,基本使用的Example。
?????Example?example?=?new?Example(FiveClassRecord.class);
????????Example.Criteria?criteria?=?example.or();
????????criteria.andEqualTo("taskNo",?lcyhTaskNo);//注意,這個是類的屬性,與mybatis不同,不是用數(shù)據(jù)庫的字段名,是用的類的屬性,
咋一看是沒什么東西,但是我主要看上了他的組裝功能
2.接口可以自定義搭配繼承
如果你想按需選擇接口,不想使用Mapper包含的那么多的方法,你可以創(chuàng)建自己的MyMapper,自己搭配想要的方法
主要場景在于,我可能之前用的是oracle數(shù)據(jù)庫,然后我切換回db2數(shù)據(jù)庫,突然發(fā)現(xiàn),id自增,不需要指定id了,那怎么辦
Mapper3接口有兩種形式,一種是提供了一個方法的接口。還有一種是不提供方法,但是繼承了多個單方法的接口,一般是某類方法的集合。
你可以按需的組裝
//注意,如果是sqlserverMapper這種,因為insert不允許id包含為null,所以繼承sqlServerMapper
//另外這倆方法和base中的插入方法重名,不能同時存在!所以拆分了
public?interface?BaseMapper?extends?BaseSelectMapper,?BaseUpdateMapper,?BaseDeleteMapper,?ExampleMapper,?RowBoundsMapper,?SqlServerMapper,?MyBatchInsertMapper?{
}
我的基本mapper就是這樣,組合了基本的crud,查詢,分頁。加上一個自定義的mapper,這個后續(xù)說。
主要問題在于,mybatis不是跟hibernate一樣提供方言,所以,d自增,不需要指定id了,那么我們就可以用支持不帶上id的插入。
3.支持逆向工程
public?class?GeneratorSqlmap?{
????public?void?generator()?throws?Exception?{
????????List?warnings?=?new?ArrayList();
????????boolean?overwrite?=?true;
????????//?指定配置文件
????????File?configFile?=?new?File("./src/main/resources/generatorConfig/generatorConfig.xml");
????????ConfigurationParser?cp?=?new?ConfigurationParser(warnings);
????????Configuration?config?=?cp.parseConfiguration(configFile);
????????DefaultShellCallback?callback?=?new?DefaultShellCallback(overwrite);
????????MyBatisGenerator?myBatisGenerator?=?new?MyBatisGenerator(config,?callback,?warnings);
????????myBatisGenerator.generate(null);
????}
????//?執(zhí)行main方法以生成代碼
????public?static?void?main(String[]?args)?{
????????try?{
????????????GeneratorSqlmap?generatorSqlmap?=?new?GeneratorSqlmap();
????????????generatorSqlmap.generator();
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????}
}
generatorConfig.xml
"-//mybatis.org//DTD?MyBatis?Generator?Configuration?1.0//EN"?"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
????"DB2Tables"?targetRuntime="MyBatis3">
????????type="tk.mybatis.mapper.generator.MapperPlugin">
????????????"mappers"?value="com.platform.common.BaseMapper"/>
????????
????????
????????????
????????????"suppressAllComments"?value="true"/>
????????
????????
????????"com.ibm.db2.jcc.DB2Driver"
????????????????????????connectionURL="jdbc:db2://66.10.93.82:60004/DFTCE:currentSchema=DFTCE;"
????????????????????????userId="dftce"
????????????????????????password="2vgrTNY51pK3hQ2e">
????????
????????
????????
????????
????????????"forceBigDecimals"?value="false"?/>
????????
????????
????????"com.beawan.exterinvoke.out.newhfw.entity"?targetProject=".\src\main\java">
????????????
????????????"enableSubPackages"?value="false"?/>
????????????
????????????"trimStrings"?value="true"?/>
????????
????????
????????"mapping.newhfw"??targetProject=".\src\main\resources">
????????????
????????????"enableSubPackages"?value="false"?/>
????????
????????
????????type="XMLMAPPER"?targetPackage="com.beawan.exterinvoke.out.newhfw.mapper"?targetProject=".\src\main\java">
????????????
????????????"enableSubPackages"?value="false"?/>
????????
????????
????????"DFTCE"?tableName="COM_EXECUTE_INFO"?domainObjectName="comExecuteInfo"
???????????????enableCountByExample="false"??enableUpdateByExample="false"?enableDeleteByExample="false"?enableSelectByExample="false"?>
????????????"ID"?sqlStatement="JDBC"/>
????????????"ID"?javaType="java.lang.Long"/>
????????????"C_CASE_CODE"?property="C_CASE_CODE"?/>
????????????"C_INAME"?property="C_INAME"?/>
????????????"N_CARD_TYPE"?property="N_CARD_TYPE"?/>
????????????"C_CARD_NUM"?property="C_CARD_NUM"?/>
????????????"C_GIST_CID"?property="C_GIST_CID"?/>
????????????"APPLY_PARTY"?property="APPLY_PARTY"?/>
????????????"EXECUTED_PARTY"?property="EXECUTED_PARTY"?/>
????????????"C_COURT_NAME"?property="C_COURT_NAME"?/>
????????????"C_PARTY_TYPE"?property="C_PARTY_TYPE"?/>
????????????"C_BUEINESS_ENTITY_NAME"?property="C_BUEINESS_ENTITY_NAME"?/>
????????????"C_ADDRESS"?property="C_ADDRESS"?/>
????????????"C_PUBLISH_DATE"?property="C_PUBLISH_DATE"?/>
????????????"C_REG_DATE"?property="C_REG_DATE"?/>
????????????"N_APPLY_MONEY"?property="N_APPLY_MONEY"?/>
????????????"N_EXECUTED_MONEY"?property="N_EXECUTED_MONEY"?/>
????????????"C_EFFECTIVE_FLAG"?property="C_EFFECTIVE_FLAG"?/>
????????????"D_DATA_DATE"?property="D_DATA_DATE"?/>
????????
????
這里我指定了mybatis的插件為tkmapper的,然后讓他mapper繼承我的通用mapper,同時不讓生成example類。
那么會生成什么呢?
就兩個,一個entity類,一個mapper。
entity
@Table(name?=?"AC_CONFIGURATION")
public?class?AcConfiguration?{
????@Id
????@Column(name?=?"ID")
????@GeneratedValue(generator?=?"JDBC")
????private?Long?id;
????@Column(name?=?"ASSESS_CARD_ID")
????private?Long?assessCardId;
????@Column(name?=?"STATE")
????private?String?state;
????@Column(name?=?"PASS_SCORE")
????private?Double?passScore;
????@Column(name?=?"REJECT_SCORE")
????private?Double?rejectScore;
????@Column(name?=?"FINANCE_RATION")
????private?Double?financeRation;
????@Column(name?=?"UNFINANCE_RATIO")
????private?Double?unfinanceRatio;
????@Column(name?=?"SCORE_WAY")
????private?String?scoreWay;
????@Column(name?=?"LOAN_TYPE")
????private?String?loanType;
????@Column(name?=?"GUARANTEE_TYPE")
????private?String?guaranteeType;
????@Column(name?=?"ENTERPRISE_TYPE")
????private?String?enterpriseType;
????@Column(name?=?"CARD_TYPE")
????private?String?cardType;
????@Column(name?=?"SUGG_SCORE")
????private?Double?suggScore;
????@Column(name?=?"AC_CUS_LEVEL_SET")
????private?String?acCusLevelSet;
????/**
?????*?非持久化字段
?????*/
????private?List?acCusLevelList;
????/**
?????*?@return?ID
?????*/
????public?Long?getId()?{
????????return?id;
????}
????/**
?????*?@param?id
?????*/
????public?void?setId(Long?id)?{
????????this.id?=?id;
????}
????public?List?getAcCusLevelList()?{
????????return?acCusLevelList;
????}
????public?void?setAcCusLevelList(List?acCusLevelList)?{
????????this.acCusLevelList?=?acCusLevelList;
????}
????/**
?????*?@return?ASSESS_CARD_ID
?????*/
????public?Long?getAssessCardId()?{
????????return?assessCardId;
????}
????/**
?????*?@param?assessCardId
?????*/
????public?void?setAssessCardId(Long?assessCardId)?{
????????this.assessCardId?=?assessCardId;
????}
????/**
?????*?@return?STATE
?????*/
????public?String?getState()?{
????????return?state;
????}
????/**
?????*?@param?state
?????*/
????public?void?setState(String?state)?{
????????this.state?=?state?==?null???null?:?state.trim();
????}
????/**
?????*?@return?PASS_SCORE
?????*/
????public?Double?getPassScore()?{
????????return?passScore;
????}
看出來了沒有,就是用的jpa的注解
所以切換的成本很低
非持久化字段,可以加?@Transient?注解
而mapper就繼承了我的通用mapper,比mybatis的逆向工程生成簡潔了很多。
4.支持開發(fā)自己的mapper
我還是看上了這個功能,開發(fā)自己的mapper,diy很開心
比如我們要開發(fā)一個批量插入功能,那么怎么做
定義批量接口
@RegisterMapper
public?interface?MyBatchInsertMapper?{
????@Options(useGeneratedKeys?=?true,keyProperty?=?"id")
????@InsertProvider(type?=?MyBatchInsertProvider.class,method?=?"dynamicSQL")
????int?batchInsert(List?recoordList);
}
實現(xiàn)自定義的類MyBatchInsertProvider.class
public?class?MyBatchInsertProvider?extends?MapperTemplate?{
????public?MyBatchInsertProvider(Class>?mapperClass,?MapperHelper?mapperHelper)?{
????????super(mapperClass,?mapperHelper);
????}
????public?String?batchInsert(MappedStatement?ms){
????????final?Class>?entiyClass?=?this.getEntityClass(ms);
????????EntityTable?table?=?EntityHelper.getEntityTable(entiyClass);
????????LinkedHashSet?tableColumns?=?table.getEntityClassColumns();
????????LinkedHashSet?nopkColumns?=?getNoPKColumn(tableColumns);
????????StringBuilder?sql?=?new?StringBuilder();
????????sql.append("insert?into?");
????????sql.append(table.getName());
????????sql.append("(");
????????boolean?first?=?true;
????????for(EntityColumn?column?:nopkColumns){
????????????if(!first){
????????????????sql.append(",");
????????????}
????????????sql.append(column.getColumn());
????????????first=false;
????????}
????????sql.append(")?values?");
????????sql.append("" );
????????sql.append("(");
????????first=true;
????????for(EntityColumn?column?:?nopkColumns){
????????????if(!first){
????????????????sql.append(",");
????????????}
????????????sql.append("#{record.").append(column.getProperty()).append("}");
????????????first=false;
????????}
????????sql.append(")");
????????sql.append("");
????????return?sql.toString();
????}
?????public?static?LinkedHashSet?getNoPKColumn(?LinkedHashSet ?tableColumns){
?????????LinkedHashSet?noPKColumn?=new?LinkedHashSet<>();
?????????if(CollectionUtil.isNullOrEmpty(tableColumns))?return?null;
?????????for(EntityColumn?entityColumn:tableColumns){
?????????????if(!"id".equals(entityColumn.getColumn().toLowerCase())?){
?????????????????noPKColumn.add(entityColumn);
?????????????}
?????????}
?????????return?noPKColumn;
?????}
}
其實思路就是憑借mybatis格式的xml
這樣我們就實現(xiàn)了批量插入,支持的是不帶上id的批量插入
結(jié)語
通用Mapper都可以極大的方便開發(fā)人員??梢噪S意的按照自己的需要選擇通用方法,還可以很方便的開發(fā)自己的通用方法。
極其方便的使用MyBatis單表的增刪改查。
支持單表操作,不支持通用的多表聯(lián)合查詢。
其實這樣還是比較簡單的使用,我的使用方法是先在數(shù)據(jù)庫設(shè)計生成好表,加好注釋,然后運行逆向工程,生成了entity和mapper和xml,然后我再運行我自己寫的自動生成 模板的servcie接口和實現(xiàn)類,以及controller,這樣一個完整的后臺的單表查詢接口就寫完了,我只需要設(shè)計表就好,其他都只是運行下代碼就好。
toLowerCase())?){
noPKColumn.add(entityColumn);
}
}
return?noPKColumn;
}
}其實思路就是憑借mybatis格式的xml
這樣我們就實現(xiàn)了批量插入,支持的是不帶上id的批量插入
##? 結(jié)語
通用Mapper都可以極大的方便開發(fā)人員??梢噪S意的按照自己的需要選擇通用方法,還可以很方便的開發(fā)自己的通用方法。
極其方便的使用MyBatis單表的增刪改查。
支持單表操作,不支持通用的多表聯(lián)合查詢。
其實這樣還是比較簡單的使用,我的使用方法是先在數(shù)據(jù)庫設(shè)計生成好表,加好注釋,然后運行逆向工程,生成了entity和mapper和xml,然后我再運行我自己寫的自動生成 模板的servcie接口和實現(xiàn)類,以及controller,這樣一個完整的后臺的單表查詢接口就寫完了,我只需要設(shè)計表就好,其他都只是運行下代碼就好。
大部分市面上的單表接口,也是這樣的思路生成的,不過不同的是,我加上了自己的邏輯,寫了自己的模板。
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循?CC 4.0 BY-SA?版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。
本文鏈接:
http://blog.csdn.net/Wzy000001/article/details/108542223
粉絲福利:108本java從入門到大神精選電子書領(lǐng)取
???
?長按上方鋒哥微信二維碼?2 秒 備注「1234」即可獲取資料以及 可以進入java1234官方微信群
感謝點贊支持下哈?
