MybatisX 是一款基于IDEA的快速开发插件,为效率而生。用于一键生成ORM代码;该插件在本文中的主要目的是为了快速生成基于MyBatis Plus相关的代码< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> mybatis-plus-boot-starter</ artifactId>
< version> 3.4.3.4</ version>
</ dependency>
< dependency>
< groupId> mysql</ groupId>
< artifactId> mysql-connector-java</ artifactId>
< version> 5.1.46</ version>
</ dependency>
< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> mybatis-plus-extension</ artifactId>
< version> 3.4.1</ version>
</ dependency>
< dependency>
< groupId> com.github.yulichang</ groupId>
< artifactId> mybatis-plus-join</ artifactId>
< version> 1.1.8</ version>
</ dependency>
< dependency>
< groupId> com.alibaba</ groupId>
< artifactId> druid-spring-boot-starter</ artifactId>
< version> 1.1.9</ version>
</ dependency>
< dependency>
< groupId> org.projectlombok</ groupId>
< artifactId> lombok</ artifactId>
< optional> true</ optional>
</ dependency>
< dependency>
< groupId> com.alibaba</ groupId>
< artifactId> fastjson</ artifactId>
< version> 1.2.73</ version>
</ dependency>
create table user_info
(
id int auto_increment comment '主键ID' primary key ,
user_name varchar ( 64 ) null comment '用户名' ,
age int null comment '年龄' ,
source tinyint null comment '来源'
)
row_format = DYNAMIC;
create index source_id on user_info ( source) ;
spring :
application :
name : mybatis- plus
datasource :
url : jdbc: mysql: //ip: port/ehang? useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
username : root
password : ******
type : com.alibaba.druid.pool.DruidDataSource
driver-class-name : com.mysql.jdbc.Driver
启动类配置Dao扫描 其中basePackages
路径,请根据个人的实际路径填写 @SpringBootApplication ( exclude = DataSourceAutoConfiguration . class )
@MapperScan ( basePackages = { "com.ehang.springboot.mybatisplus.generator.**.mapper" } )
<?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.ehang.springboot.mybatisplus.generator.user.mapper.UserInfoMapper" >
< resultMap id = " BaseResultMap" type = " com.ehang.springboot.mybatisplus.generator.user.demain.UserInfo" >
< id property = " id" column = " id" jdbcType = " INTEGER" />
< result property = " userName" column = " user_name" jdbcType = " VARCHAR" />
< result property = " age" column = " age" jdbcType = " INTEGER" />
< result property = " source" column = " source" jdbcType = " TINYINT" />
</ resultMap>
< sql id = " Base_Column_List" >
id,user_name,age,
source
</ sql>
</ mapper>
数据库操作的Mapper,继承了MyBatis Plus的BaseMapper
public interface UserInfoMapper extends BaseMapper < UserInfo > {
}
public interface BaseMapper < T > extends Mapper < T > {
int insert ( T entity) ;
int deleteById ( Serializable id) ;
int deleteByMap ( @Param ( "cm" ) Map < String , Object > columnMap) ;
int delete ( @Param ( "ew" ) Wrapper < T > queryWrapper) ;
int deleteBatchIds ( @Param ( "coll" ) Collection < ? extends Serializable > idList) ;
int updateById ( @Param ( "et" ) T entity) ;
int update ( @Param ( "et" ) T entity, @Param ( "ew" ) Wrapper < T > updateWrapper) ;
T selectById ( Serializable id) ;
List < T > selectBatchIds ( @Param ( "coll" ) Collection < ? extends Serializable > idList) ;
List < T > selectByMap ( @Param ( "cm" ) Map < String , Object > columnMap) ;
T selectOne ( @Param ( "ew" ) Wrapper < T > queryWrapper) ;
Integer selectCount ( @Param ( "ew" ) Wrapper < T > queryWrapper) ;
List < T > selectList ( @Param ( "ew" ) Wrapper < T > queryWrapper) ;
List < Map < String , Object > > selectMaps ( @Param ( "ew" ) Wrapper < T > queryWrapper) ;
List < Object > selectObjs ( @Param ( "ew" ) Wrapper < T > queryWrapper) ;
< E extends IPage < T > > E selectPage ( E page, @Param ( "ew" ) Wrapper < T > queryWrapper) ;
< E extends IPage < Map < String , Object > > > E selectMapsPage ( E page, @Param ( "ew" ) Wrapper < T > queryWrapper) ;
}
继承了MyBatisPlus的IService
,定义了众多基础的Service方法 自动生成的接口无法满足业务需求时,也可以定义接口,满足个性化需要 public interface UserInfoService extends IService < UserInfo > {
}
继承了MyBatisPlus的ServiceImpl
,ServiceImpl基于BaseMapper实现了IService定义的基础的接口 public class UserInfoServiceImpl extends ServiceImpl < UserInfoMapper , UserInfo > implements UserInfoService {
}
API 功能 描述 save 添加、保存 支持单条和批量 saveOrUpdate 添加或者修改 主键不存在就添加,否则就基于主键修改 remove 删除数据 条件删除、主键删除、批量删除 update 修改 支持单条修改、批量修改 get 查询单条记录 list 批量查询 批量查询 page 分页查询 需要分页插件的支持 count 记录数 查询总数、满足条件的记录数 chain 流式调用 让API调用更加方便简单
boolean save ( T entity) ;
boolean saveBatch ( Collection < T > entityList) ;
boolean saveBatch ( Collection < T > entityList, int batchSize) ;
@Test
void save ( ) {
UserInfo userInfo = new UserInfo ( null , "张三" , 10 , ( byte ) 1 ) ;
boolean save = userInfoService. save ( userInfo) ;
log. info ( "单条添加的结果:{}" , save) ;
}
@Test
void saveBatch ( ) {
List < UserInfo > userInfos = List . of ( new UserInfo ( null , "李四" , 10 , ( byte ) 1 ) , new UserInfo ( null , "王五" , 10 , ( byte ) 1 ) )
boolean saveBatch = userInfoService. saveBatch ( userInfos, 10 ) ;
log. info ( "批量添加的结果:{}" , saveBatch) ;
}
boolean saveOrUpdate ( T entity) ;
boolean saveOrUpdate ( T entity, Wrapper < T > updateWrapper) ;
boolean saveOrUpdateBatch ( Collection < T > entityList) ;
boolean saveOrUpdateBatch ( Collection < T > entityList, int batchSize) ;
@Test
void saveOrUpdate ( ) {
UserInfo userInfo = new UserInfo ( 1004 , "张三(改)" , 20 , ( byte ) 1 ) ;
boolean saveOrUpdate = userInfoService. saveOrUpdate ( userInfo) ;
log. info ( "单条插入(或修改)的结果:{}" , saveOrUpdate) ;
LambdaUpdateWrapper < UserInfo > updateWrapper = new LambdaUpdateWrapper < > ( ) ;
updateWrapper. eq ( UserInfo :: getSource , 1 ) ;
boolean saveOrUpdateByWrapper = userInfoService. saveOrUpdate ( userInfo, updateWrapper) ;
log. info ( "单条插入(或根据条件修改)的结果:{}" , saveOrUpdateByWrapper) ;
List < UserInfo > userInfos = List . of ( new UserInfo ( null , "李四" , 10 , ( byte ) 1 ) , new UserInfo ( null , "王五" , 10 , ( byte ) 1 ) )
boolean saveBatch = userInfoService. saveOrUpdateBatch ( userInfos, 10 ) ;
log. info ( "批量插入(或修改)的结果:{}" , saveBatch) ;
}
boolean remove ( Wrapper < T > queryWrapper) ;
boolean removeById ( Serializable id) ;
boolean removeByMap ( Map < String , Object > columnMap) ;
boolean removeByIds ( Collection < ? extends Serializable > idList) ;
@Test
void remove ( ) {
LambdaQueryWrapper < UserInfo > queryWrapper = new LambdaQueryWrapper < > ( ) ;
queryWrapper. eq ( UserInfo :: getUserName , "张三" ) ;
boolean remove = userInfoService. remove ( queryWrapper) ;
log. info ( "根据条件删除用户数据:{}" , remove) ;
}
@Test
void removeById ( ) {
boolean removeById = userInfoService. removeById ( 1006 ) ;
log. info ( "根据主键ID删除用户数据:{}" , removeById) ;
}
@Test
void removeByMap ( ) {
Map < String , Object > cms = new HashMap ( ) ;
cms. put ( "user_name" , "李四" ) ;
cms. put ( "source" , 1 ) ;
boolean removeByMap = userInfoService. removeByMap ( cms) ;
log. info ( "根据字段值删除用户数据:{}" , removeByMap) ;
}
@Test
void removeByIds ( ) {
List < Integer > ids = List . of ( 1004 , 1005 , 1006 ) ;
boolean removeByIds = userInfoService. removeByIds ( ids) ;
log. info ( "根据主键ids批量删除用户数据:" , removeByIds) ;
}
boolean update ( Wrapper < T > updateWrapper) ;
boolean update ( T updateEntity, Wrapper < T > whereWrapper) ;
boolean updateById ( T entity) ;
boolean updateBatchById ( Collection < T > entityList) ;
boolean updateBatchById ( Collection < T > entityList, int batchSize) ;
@SpringBootTest
@Slf4j
public class UpdateTest {
@Autowired
UserInfoService userInfoService;
@Test
public void update ( ) {
LambdaUpdateWrapper < UserInfo > updateWrapper = new UpdateWrapper < UserInfo > ( )
. lambda ( )
. set ( UserInfo :: getUserName , "ooxx(改1)" )
. eq ( UserInfo :: getId , 1 ) ;
boolean update = userInfoService. update ( updateWrapper) ;
log. info ( "根据UpdateWrapper修改(不推荐使用):{}" , update) ;
}
@Test
public void update2 ( ) {
LambdaUpdateWrapper < UserInfo > updateWrapper = new UpdateWrapper < UserInfo > ( )
. lambda ( )
. eq ( UserInfo :: getUserName , "ooxx(改1)" ) ;
UserInfo user = new UserInfo ( 1 , "ooxx(改2)" , 10 , ( byte ) 1 ) ;
boolean update = userInfoService. update ( user, updateWrapper) ;
log. info ( "根据UpdateWrapper修改为指定对象:{}" , update) ;
}
@Test
public void updateById ( ) {
UserInfo user = new UserInfo ( 1 , "ooxx(改2)" , 10 , ( byte ) 1 ) ;
boolean update = userInfoService. updateById ( user) ;
log. info ( "根据对象ID修改:{}" , update) ;
}
@Test
public void updateBatchById ( ) {
List < UserInfo > us = List . of ( new UserInfo ( null , "李四" , 10 , ( byte ) 1 ) , new UserInfo ( null , "王五" , 10 , ( byte ) 1 ) )
boolean update = userInfoService. updateBatchById ( us) ;
log. info ( "根据对象ID批量修改:{}" , update) ;
}
@Test
public void updateBatchById2 ( ) {
List < UserInfo > us = List . of ( new UserInfo ( null , "李四" , 10 , ( byte ) 1 ) , new UserInfo ( null , "王五" , 10 , ( byte ) 1 ) )
boolean update = userInfoService. updateBatchById ( us, 2 ) ;
log. info ( "根据对象ID批量修改:{}" , update) ;
}
}
T getById ( Serializable id) ;
T getOne ( Wrapper < T > queryWrapper) ;
T getOne ( Wrapper < T > queryWrapper, boolean throwEx) ;
Map < String , Object > getMap ( Wrapper < T > queryWrapper) ;
< V > V getObj ( Wrapper < T > queryWrapper, Function < ? super Object , V > mapper) ;
@SpringBootTest
@Slf4j
public class GetTest {
@Autowired
UserInfoService userInfoService;
@Test
void getById ( ) {
UserInfo userInfo = userInfoService. getById ( 1 ) ;
log. info ( "根据ID查询用户信息:{}" , userInfo) ;
}
@Test
void getOne ( ) {
LambdaQueryWrapper < UserInfo > lambdaQueryWrapper = new QueryWrapper < UserInfo > ( )
. lambda ( )
. eq ( UserInfo :: getId , 1 ) ;
UserInfo userInfo = userInfoService. getOne ( lambdaQueryWrapper) ;
log. info ( "根据ID查询单用户信息:{}" , userInfo) ;
}
@Test
void getOne2 ( ) {
LambdaQueryWrapper < UserInfo > lambdaQueryWrapper = new QueryWrapper < UserInfo > ( )
. lambda ( )
. eq ( UserInfo :: getUserName , "ooxx 1" )
. orderByDesc ( UserInfo :: getId ) ;
UserInfo userInfo = userInfoService. getOne ( lambdaQueryWrapper, false ) ;
log. info ( "根据ID查询单用户信息:{}" , userInfo) ;
}
@Test
void getMap ( ) {
LambdaQueryWrapper < UserInfo > lambdaQueryWrapper = new QueryWrapper < UserInfo > ( )
. lambda ( )
. eq ( UserInfo :: getId , 1 ) ;
Map < String , Object > map = userInfoService. getMap ( lambdaQueryWrapper) ;
log. info ( "根据ID查询单用户信息:{}" , map) ;
}
@Test
void getObj ( ) {
LambdaQueryWrapper < UserInfo > lambdaQueryWrapper = new QueryWrapper < UserInfo > ( )
. lambda ( )
. eq ( UserInfo :: getUserName , "ooxx 1" )
. select ( UserInfo :: getUserName ) ;
String obj = userInfoService. getObj ( lambdaQueryWrapper, ( u) -> u. toString ( ) ) ;
log. info ( "getObj:{}" , obj) ;
}
}
List < T > list ( ) ;
List < T > list ( Wrapper < T > queryWrapper) ;
Collection < T > listByIds ( Collection < ? extends Serializable > idList) ;
Collection < T > listByMap ( Map < String , Object > columnMap) ;
List < Map < String , Object > > listMaps ( ) ;
List < Map < String , Object > > listMaps ( Wrapper < T > queryWrapper) ;
List < Object > listObjs ( ) ;
< V > List < V > listObjs ( Function < ? super Object , V > mapper) ;
List < Object > listObjs ( Wrapper < T > queryWrapper) ;
< V > List < V > listObjs ( Wrapper < T > queryWrapper, Function < ? super Object , V > mapper) ;
< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> mybatis-plus-extension</ artifactId>
< version> 3.4.1</ version>
</ dependency>
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor ( ) {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor ( ) ;
interceptor. addInnerInterceptor ( new PaginationInnerInterceptor ( DbType . MYSQL ) ) ;
return interceptor;
}
@Bean
public PaginationInterceptor paginationInterceptor ( ) {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor ( ) ;
paginationInterceptor. setCountSqlParser ( new JsqlParserCountOptimize ( true ) ) ;
return paginationInterceptor;
}
IPage < T > page ( IPage < T > page) ;
IPage < T > page ( IPage < T > page, Wrapper < T > queryWrapper) ;
IPage < Map < String , Object > > pageMaps ( IPage < T > page) ;
IPage < Map < String , Object > > pageMaps ( IPage < T > page, Wrapper < T > queryWrapper) ;
@SpringBootTest
@Slf4j
public class PageTest {
@Autowired
UserInfoService userInfoService;
@Test
void page ( ) {
Page < UserInfo > page = userInfoService. page ( new Page < UserInfo > ( 2 , 5 ) ) ;
log. info ( "page:{}" , page) ;
}
@Test
void pageByWrapper ( ) {
LambdaQueryWrapper < UserInfo > lambdaQueryWrapper = new QueryWrapper < UserInfo > ( )
. lambda ( )
. ge ( UserInfo :: getId , 10 ) ;
Page < UserInfo > page = userInfoService. page ( new Page < UserInfo > ( 2 , 5 ) , lambdaQueryWrapper) ;
log. info ( "pageByWrapper:{}" , page) ;
}
@Test
void pageMaps ( ) {
Page < Map < String , Object > > page = userInfoService. pageMaps ( new Page ( 2 , 5 ) ) ;
log. info ( "pageMaps:{}" , JSON . toJSONString ( page) ) ;
}
@Test
void pageMapsByWrapper ( ) {
LambdaQueryWrapper < UserInfo > lambdaQueryWrapper = new QueryWrapper < UserInfo > ( )
. lambda ( )
. ge ( UserInfo :: getId , 10 ) ;
Page < Map < String , Object > > page = userInfoService. pageMaps ( new Page ( 2 , 5 ) , lambdaQueryWrapper) ;
log. info ( "pageMapsByWrapper:{}" , JSON . toJSONString ( page) ) ;
}
}
查询记录数
int count ( ) ;
int count ( Wrapper < T > queryWrapper) ;
@SpringBootTest
@Slf4j
public class CountTest {
@Autowired
UserInfoService userInfoService;
@Test
void count ( ) {
int count = userInfoService. count ( ) ;
log. info ( "总数:{}" , count) ;
}
@Test
void countByWrapper ( ) {
int count = userInfoService. count ( new QueryWrapper < UserInfo > ( )
. lambda ( )
. ge ( UserInfo :: getId , 100 ) ) ;
log. info ( "按条件查询总数:{}" , count) ;
}
}
QueryChainWrapper < T > query ( ) ;
LambdaQueryChainWrapper < T > lambdaQuery ( ) ;
UpdateChainWrapper < T > update ( ) ;
LambdaUpdateChainWrapper < T > lambdaUpdate ( ) ;
@SpringBootTest
@Slf4j
public class ChainTest {
@Autowired
UserInfoService userInfoService;
@Test
void chainQuery ( ) {
List < UserInfo > userInfos = userInfoService
. query ( )
. eq ( "user_name" , "ooxx 1" )
. list ( ) ;
log. info ( "流式查询:{}" , JSON . toJSONString ( userInfos) ) ;
}
@Test
void chainLambdaQuery ( ) {
List < UserInfo > userInfos = userInfoService
. lambdaQuery ( )
. eq ( UserInfo :: getUserName , "ooxx 1" )
. list ( ) ;
log. info ( "流式查询:{}" , JSON . toJSONString ( userInfos) ) ;
}
}
关键字 作用 示例 等价SQL allEq 匹配所有字段全部eq .query().allEq({id:1,user_name:"老王",age:null}).list() WHERE id =1 AND user_neme="老王" AND age IS NULL eq 等于(==) .lambdaQuery().eq(UserInfo::getId, 1) WHERE id = 1 ne 不等于(<>) .lambdaQuery().ne(UserInfo::getId, 1) WHERE id <> 1 gt 大于(>) .lambdaQuery().gt(UserInfo::getId, 1) WHERE id > 1 ge 大于等于(>=) .lambdaQuery().ge(UserInfo::getId, 1) WHERE id >= 1 lt 小于(<) .lambdaQuery().lt(UserInfo::getId, 1) WHERE id < 1 le 小于等于(<=) .lambdaQuery().le(UserInfo::getId, 1) WHERE id <= 1 between 指定区间内 .lambdaQuery().between(UserInfo::getId, 1,10) WHERE (id BETWEEN 1 AND 10) notBetween 指定区间外 .lambdaQuery().notBetween(UserInfo::getId, 5,100) WHERE (id NOT BETWEEN 5 AND 100) like 字符串匹配 .lambdaQuery().like(UserInfo::getUserName, “ooxx”) WHERE (user_name LIKE "%ooxx%") notLike 字符串不匹配 .lambdaQuery().notLike(UserInfo::getUserName, “ooxx”) WHERE (user_name NOT LIKE "%ooxx%") likeLeft 字符串左匹配 .lambdaQuery().likeLeft(UserInfo::getUserName, “ooxx”) WHERE (user_name LIKE "%ooxx") likeRight 字符串右匹配 .lambdaQuery().likeRight(UserInfo::getUserName, “ooxx”) WHERE (user_name LIKE "ooxx%") isNull 等于null .lambdaQuery().isNull(UserInfo::getUserName) WHERE (user_name IS NULL) isNotNull 不等于null .lambdaQuery().isNotNull(UserInfo::getUserName) WHERE (user_name IS NOT NULL) in 包含 .lambdaQuery().in(UserInfo::getId, 1, 2, 3) WHERE (id IN (1, 2, 3)) notIn 不包含 .lambdaQuery().notIn(UserInfo::getId, 1, 2, 3) WHERE (id NOT IN (1, 2, 3)) inSql sql方式包含 .lambdaQuery().inSql(UserInfo::getId, "1, 2, 3") WHERE (id IN (1, 2, 3)) notInSql sql方式不包含 .lambdaQuery().notInSql(UserInfo::getId, "1, 2, 3") WHERE (id NOT IN (1, 2, 3)) groupBy 分组 .select("source,count(id) as sum").groupBy("source").having("count(id) > {0}", 35); GROUP BY source HAVING count(id) > 35 orderByAsc 升序 .lambdaQuery().orderByAsc(UserInfo::getSource) ORDER BY source ASC orderByDesc 降序 .lambdaQuery().orderByDesc(UserInfo::getSource) ORDER BY source DESC orderBy 排序 .lambdaQuery().orderBy(true, true, UserInfo::getSource) ORDER BY source ASC having having子句 .select("source,count(id) as sum").groupBy("source").having("count(id) > {0}", 35); GROUP BY source HAVING count(id) > 35 func 自定义Consumer .lambdaQuery().func(i -> {if (true) {i.eq(UserInfo::getId, 10);} else {i.eq(UserInfo::getId, 100); }}) WHERE (id = 10) or 多条件满足一个 .lambdaQuery()..le(UserInfo::getId, 10) .or(i -> .eq(UserInfo::getUserName, "张三").ge(UserInfo::getId, 1005)) WHERE (id <= 10 OR (user_name = "张三" AND id >= 1005)) and 多条件同时满足 .lambdaQuery().le(UserInfo::getId, 10) .and(i -> i.eq(UserInfo::getUserName, "ooxx 1")) WHERE (id <= 10 AND (user_name = "ooxx 1")) nested 指定条件用()嵌套 .lambdaQuery().ge(UserInfo::getId, 10).nested(i -> i.eq(UserInfo::getUserName, "张三").or(m -> m.ge(UserInfo::getId, 1005))) WHERE (id >= 10 AND (user_name = "张三" OR (id >= 1005))) apply 拼接sql .lambdaQuery().apply("id < {0}", 20) WHERE (id < 20) last 拼接语句在sql最后 .lambdaQuery().apply("id < {0}", 20).last("limit 1") WHERE (id < ?) limit 1 exists 子句存在数据 .lambdaQuery().exists("select id from user_info where id > 1000") WHERE (EXISTS (select id from user_info where id > 1000)) notExists 子句不存在数据 .lambdaQuery().notExists("select id from user_info where id > 10000") WHERE (NOT EXISTS (select id from user_info where id > 10000))
condition 所有条件是否生效,默认是true;设置为false之后,设置的所有的条件都不会生效 params filter null2IsNull 是否忽略null值;默认是true,如果有需要匹配的字段是null,则会添加 is null的查询条件;如果设置为false,将会自动剔除所有值null的字段校验
@SpringBootTest
@Slf4j
public class AllEqTest {
@Autowired
UserInfoService userInfoService;
Map < String , Object > params = new HashMap ( ) ;
@BeforeEach
public void init ( ) {
params. put ( "user_name" , "ooxx 1" ) ;
params. put ( "id" , null ) ;
}
@Test
void allEq ( ) {
List < UserInfo > list = userInfoService. query ( ) . allEq ( params) . list ( ) ;
log. info ( "{}" , JSON . toJSONString ( list) ) ;
}
@Test
void allEqConditionFalse ( ) {
List < UserInfo > list = userInfoService. query ( ) . allEq ( false , params, true ) . list ( ) ;
log. info ( "{}" , JSON . toJSONString ( list) ) ;
}
@Test
void allEqNull2IsNull ( ) {
List < UserInfo > list = userInfoService. query ( ) . allEq ( params, false ) . list ( ) ;
log. info ( "{}" , JSON . toJSONString ( list) ) ;
}
@Test
void allEqFilter ( ) {
List < UserInfo > list = userInfoService. query ( ) . allEq ( ( k, v) -> ! k. equals ( "id" ) , params) . list ( ) ;
log. info ( "{}" , JSON . toJSONString ( list) ) ;
}
}
@SpringBootTest
@Slf4j
public class GroupByAndHavingTest {
@Autowired
UserInfoService userInfoService;
@Test
void groupByAndHaving ( ) {
QueryWrapper < UserInfo > userInfoQueryWrapper = new QueryWrapper < > ( ) ;
userInfoQueryWrapper. select ( "source,count(id) as sum" )
. groupBy ( "source" )
. having ( "count(id) > {0}" , 35 ) ;
List < Map < String , Object > > maps = userInfoService. listMaps ( userInfoQueryWrapper) ;
}
}
用于设置条件子句 ;不同的业务条件下,sql执行条件也有所不同;通过func
子句来进行设置 @SpringBootTest
@Slf4j
public class FuncTest {
@Autowired
UserInfoService userInfoService;
@Test
void func ( ) {
Boolean condition = true ;
List < UserInfo > userInfos = userInfoService. lambdaQuery ( )
. func ( i -> {
if ( condition) {
i. eq ( UserInfo :: getId , 10 ) ;
} else {
i. eq ( UserInfo :: getId , 100 ) ;
}
} ) . list ( ) ;
log. info ( "userInfos:{}" , userInfos) ;
}
}
@SpringBootTest
@Slf4j
public class OrAndTest {
@Autowired
UserInfoService userInfoService;
@Test
void or ( ) {
List < UserInfo > userInfos = userInfoService. lambdaQuery ( )
. le ( UserInfo :: getId , 10 )
. or ( i -> i. eq ( UserInfo :: getUserName , "张三" ) . ge ( UserInfo :: getId , 1005 ) )
. list ( ) ;
log. info ( "userInfo:{}" , userInfos) ;
}
@Test
void and ( ) {
List < UserInfo > userInfos = userInfoService. lambdaQuery ( )
. le ( UserInfo :: getId , 10 )
. and ( i -> i. eq ( UserInfo :: getUserName , "ooxx 1" ) )
. list ( ) ;
log. info ( "userInfo:{}" , userInfos) ;
}
}
nested 嵌套。eg:当条件中存在and和or组合时,就需要对or的多个条件进行嵌套,防止与and之间产生错误的组合关系 apply 拼接sql。有些特殊个性化场景下,很难用api去定义一些操作。eg:需要对时间格式化后作查询条件,此时就需要借助一段简单的sql拼接来完成 apply ( "date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'" ) ` = > `date_format ( dateColumn, '% Y - % m- % d') = ' 2008 - 08 - 08 '")
last 在sql末尾带上指定语句。eg:last("limit 1")
,就会在sql语句的末尾加上limit 1
API列表
nested ( Consumer < Param > consumer)
nested ( boolean condition, Consumer < Param > consumer)
apply ( String applySql, Object . . . params)
apply ( boolean condition, String applySql, Object . . . params)
last ( String lastSql)
last ( boolean condition, String lastSql)
@SpringBootTest
@Slf4j
public class Nested_Apply_Limit_Test {
@Autowired
UserInfoService userInfoService;
@Test
void nested ( ) {
List < UserInfo > userInfos = userInfoService. lambdaQuery ( )
. ge ( UserInfo :: getId , 10 )
. nested (
i -> i. eq ( UserInfo :: getUserName , "张三" ) . or ( m -> m. ge ( UserInfo :: getId , 1005 ) )
)
. list ( ) ;
log. info ( "userInfo:{}" , userInfos) ;
}
@Test
void apply ( ) {
List < UserInfo > userInfos = userInfoService. lambdaQuery ( )
. apply ( "id < {0}" , 20 )
. list ( ) ;
log. info ( "userInfo:{}" , userInfos) ;
}
@Test
void last ( ) {
List < UserInfo > userInfos = userInfoService. lambdaQuery ( )
. last ( "limit 1" )
. list ( ) ;
log. info ( "userInfo:{}" , userInfos) ;
}
}
create table school_info
(
id int not null primary key ,
school_name varchar ( 64 ) not null comment '学校名称' ,
school_addr varchar ( 255 ) not null comment '学校地址'
)
row_format = DYNAMIC;
insert into ` school_info` values ( 1 , 'XXX小学' , 'xx区xx街道80号' ) ;
create table class_info
(
id int not null primary key ,
class_name varchar ( 64 ) not null comment '名称' ,
class_desc varchar ( 255 ) null comment '描述' ,
school_id int not null comment '隶属的学校'
)
row_format = DYNAMIC;
insert into ` class_info` values ( 1 , '一年级1班' , NULL , 1 ) ;
insert into ` class_info` values ( 2 , '一年级2班' , NULL , 1 ) ;
create table student_info
(
id int not null primary key ,
name varchar ( 64 ) null ,
age int null ,
class_id int null ,
school_id int null
)
row_format = DYNAMIC;
insert into ` student_info` values ( 1 , '张三' , 7 , 1 , 1 ) ;
insert into ` student_info` values ( 2 , '李四' , 7 , 2 , 1 ) ;
insert into ` student_info` values ( 3 , '王五' , 8 , 1 , 1 ) ;
insert into ` student_info` values ( 4 , '赵六' , 8 , 1 , 1 ) ;
MPJBaseMapper
扩展了MyBatis Plus的 BaseMapper
接口public interface MPJBaseMapper < T > extends BaseMapper < T > {
Integer selectJoinCount ( @Param ( "ew" ) MPJBaseJoin var1) ;
< DTO> DTO selectJoinOne ( @Param ( "resultTypeClass_Eg1sG" ) Class < DTO> var1, @Param ( "ew" ) MPJBaseJoin var2) ;
Map < String , Object > selectJoinMap ( @Param ( "ew" ) MPJBaseJoin var1) ;
< DTO> List < DTO> selectJoinList ( @Param ( "resultTypeClass_Eg1sG" ) Class < DTO> var1, @Param ( "ew" ) MPJBaseJoin var2) ;
List < Map < String , Object > > selectJoinMaps ( @Param ( "ew" ) MPJBaseJoin var1) ;
< DTO, P extends IPage < ? > > IPage < DTO> selectJoinPage ( P var1, @Param ( "resultTypeClass_Eg1sG" ) Class < DTO> var2, @Param ( "ew" ) MPJBaseJoin var3) ;
< P extends IPage < ? > > IPage < Map < String , Object > > selectJoinMapsPage ( P var1, @Param ( "ew" ) MPJBaseJoin var2) ;
}
MPJBaseService
扩展了MyBatis Plus的 IService
接口public interface MPJBaseService < T > extends IService < T > {
Integer selectJoinCount ( MPJBaseJoin var1) ;
< DTO> DTO selectJoinOne ( Class < DTO> var1, MPJBaseJoin var2) ;
< DTO> List < DTO> selectJoinList ( Class < DTO> var1, MPJBaseJoin var2) ;
< DTO, P extends IPage < ? > > IPage < DTO> selectJoinListPage ( P var1, Class < DTO> var2, MPJBaseJoin var3) ;
Map < String , Object > selectJoinMap ( MPJBaseJoin var1) ;
List < Map < String , Object > > selectJoinMaps ( MPJBaseJoin var1) ;
< P extends IPage < Map < String , Object > > > IPage < Map < String , Object > > selectJoinMapsPage ( P var1, MPJBaseJoin var2) ;
}
MPJBaseServiceImpl
扩展了MyBatis Plus的 ServiceImpl
接口实现public class MPJBaseServiceImpl < M extends MPJBaseMapper < T > , T > extends ServiceImpl < M , T > implements MPJBaseService < T > {
}
public interface StudentInfoMapper extends MPJBaseMapper < StudentInfo > {
}
public interface StudentInfoService extends MPJBaseService < StudentInfo > {
}
@Service
public class StudentInfoServiceImpl extends MPJBaseServiceImpl < StudentInfoMapper , StudentInfo > implements StudentInfoService {
}
@Data
public class StudentInfoDTO {
private Integer id;
private String name;
private Integer age;
private String className;
private String schoolName;
private String scAddr;
}
@Autowired
StudentInfoService sutdentInfoService;
@Test
public void selectJoinOne ( ) {
StudentInfoDTO studentInfoDTO = sutdentInfoService. selectJoinOne ( StudentInfoDTO . class ,
new MPJLambdaWrapper < StudentInfo > ( )
. selectAll ( StudentInfo . class )
. select ( SchoolInfo :: getSchoolName )
. selectAs ( SchoolInfo :: getSchoolAddr , StudentInfoDTO :: getScAddr )
. select ( ClassInfo :: getClassName )
. leftJoin ( SchoolInfo . class , SchoolInfo :: getId , StudentInfo :: getSchoolId )
. leftJoin ( ClassInfo . class , ClassInfo :: getId , StudentInfo :: getClassId )
. eq ( StudentInfo :: getId , 1 ) ) ;
log. info ( "selectJoinOne:{}" , JSON . toJSONString ( studentInfoDTO) ) ;
}
StudentInfoDTO.class 表示resultType,用于接收联表查询之后的数据库返回 selectAll select 指定查询列,同一个select只能指明单个表的列,所以多表关联时需要使用多个select去指明不同表的列 selectAs 重命名,表现在sql层面是会给字段加上as
(别名);主要用在数据库字段名也实体对象的名称不一致 的情况; leftJoin、rightJoin、innerJoin SQL中 inner join、left join、right join、full join 到底怎么选?详解来了open in new window 参数一:参与联表的对象 参数二:on关联的指定,此属性必须是第一个对象中的值 参数三:参与连表的ON的另一个实体类属性 条件构造器 表名 默认主表别名是t
,其他的表别名以先后调用的顺序使用 t1, t2, t3 ...
需要直接apply语句的时候,就得知道对应的表名是什么再进行添加,不建议直接追加语句 SELECT t. id,
t. name,
t. age,
t. class_id,
t. school_id,
t1. school_name,
t1. school_addr AS scAddr,
t2. class_name
FROM student_info t
LEFT JOIN school_info t1 ON ( t1. id = t. school_id)
LEFT JOIN class_info t2 ON ( t2. id = t. class_id)
WHERE ( t. id = ?)
@Autowired
StudentInfoService sutdentInfoService;
@Test
public void selectJoinPage ( ) {
IPage < StudentInfoDTO > studentInfoDTOIPage = sutdentInfoService. selectJoinListPage ( new Page < > ( 1 , 2 ) , StudentInfoDTO . class ,
new MPJLambdaWrapper < StudentInfo > ( )
. selectAll ( StudentInfo . class )
. select ( SchoolInfo :: getSchoolName )
. selectAs ( SchoolInfo :: getSchoolAddr , StudentInfoDTO :: getScAddr )
. select ( ClassInfo :: getClassName )
. leftJoin ( SchoolInfo . class , SchoolInfo :: getId , StudentInfo :: getSchoolId )
. leftJoin ( ClassInfo . class , ClassInfo :: getId , StudentInfo :: getClassId )
. orderByAsc ( StudentInfo :: getId )
) ;
log. info ( "selectJoinPage:{}" , JSON . toJSONString ( studentInfoDTOIPage) ) ;
}
SELECT t. id,
t. name,
t. age,
t. class_id,
t. school_id,
t1. school_name,
t1. school_addr AS scAddr,
t2. class_name
FROM student_info t
LEFT JOIN school_info t1 ON ( t1. id = t. school_id)
LEFT JOIN class_info t2 ON ( t2. id = t. class_id)
ORDER BY t. id ASC
LIMIT 2