CommonTestApp.java
package com.tiglle.mp;
import com.tiglle.mp.entity.Plan;
import com.tiglle.mp.mapper.PlanMapper;
import com.tiglle.mp.service.PlanService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.xml.crypto.Data;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CommonTestApp {
//service 封装了 mapper,方法名字可能不一样
@Autowired
private PlanService planService;
@Autowired
private PlanMapper planMapper;
/*
------------------------------------------------------------------------------------------排除非表字段的三种方式(实体类拥有的自断并不想与表中的自断关联)
1.加 static关键字
2.加上 transient 关键字
2.加上注解:TableField(exist=false) exist:是否要在表中存在,默认为true
*/
/*
---------------------------------------------------------------------------------------------新增,删除
*/
@Test
public void mpTest1() {
Plan plan = getPlan();
//会自动填充自增长的id
int i = planMapper.insert(plan);
System.out.println(i + "=" + plan);
//删除
Map<String, Object> attrAndField = new HashMap<>();
attrAndField.put("locno", plan.getLocno());
int i1 = planMapper.deleteByMap(attrAndField);
System.out.println("成功删除=" + i1);
}
/*
--------------------------------------------------------------------------------------------通用Service
封装了很多好用的方法
1.批量插入
Service.saveBatch(list, 2000);
2.封装特殊Lambda条件构造器
Service.lambdaUpdate();
3.等......
*/
@Test
public void mpTest4() {
List<Plan> list = new ArrayList<>();
/*批量插入,默认最大1000条执行一次,数据量太大的单挑执行sql会内存泄漏等问题*/
boolean b = planService.saveBatch(list);
//可以调用此方法设置最大执行条数
boolean b1 = planService.saveBatch(list, 2000);
/*封装特殊Lambda条件构造器*/
boolean update = planService.lambdaUpdate().set(Plan::getLocno, "102").eq(Plan::getLocno, "103").update();
}
@Test
public void test11(){
List list = new ArrayList();
for (long i = 0; i < 100000; i++) {
Plan plan = new Plan();
plan.setId(i);
plan.setLocno("fdfdsfds");
plan.setOrderNo(i+"1");
plan.setStatus("rr"+i);
plan.setCreateFlag("fd");
plan.setInitiator("fd");
plan.setServiceSource("1");
plan.setServiceReasonCode("e");
plan.setServiceDealCode("4");
plan.setExchangeSku("1");
plan.setProductQuality("4");
plan.setIsInWarehouse("1");
plan.setTaskType("33");
plan.setSourceOrderNo("fdsfdsfdsfdsfd");
plan.setPlanBoxNum(32);
plan.setPlanPiecesNum(43);
plan.setActualBoxNum(23);
plan.setActualPiecesNum(2323);
plan.setDifferenceNum(2);
plan.setProductType("1");
plan.setVerifyUserId("fdsfdsf");
plan.setVerifyTime(LocalDateTime.now());
plan.setCreateUserId("fdfsdfd");
plan.setCreateUserName("fdsfsd");
plan.setCreateTime(LocalDateTime.now());
plan.setUpdateUserId("fds");
plan.setUpdateUserName("fdsfd");
plan.setUpdateTime(LocalDateTime.now());
plan.setDelFlag(1);
plan.setTraceId("ee");
plan.setRemarks("fdsfd");
list.add(plan);
}
long l = System.currentTimeMillis();
boolean b = planService.saveBatch(list);
long l1 = System.currentTimeMillis();
System.out.println((l1-l)/1000);
}
/*
--------------------------------------------------------------------------------------------mybatis的配置:可以看官网首页右上角的配置,和文档同级
*/
@Test
public void mpTest5() {
/*mybatis的配置:可以看官网首页右上角的配置,和文档同级*/
}
public static Plan getPlan() {
Plan plan = new Plan();
plan.setLocno("1234567810");
plan.setCreateFlag("222");
plan.setOrderNo("333");
plan.setServiceDealCode("1");
plan.setCreateFlag("1");
plan.setInitiator("1");
plan.setServiceSource("1");
plan.setServiceReasonCode("444");
plan.setServiceDealCode("555");
plan.setExchangeSku("0");
plan.setProductQuality("1");
plan.setIsInWarehouse("0");
plan.setTaskType("1");
plan.setSourceOrderNo("666");
plan.setPlanBoxNum(10);
plan.setPlanPiecesNum(20);
plan.setActualPiecesNum(30);
plan.setDifferenceNum(40);
plan.setProductType("1");
plan.setVerifyUserId("777");
plan.setVerifyUserName("小明");
plan.setVerifyTime(LocalDateTime.now());
plan.setCreateUserId("999");
plan.setCreateUserName("小明");
plan.setCreateTime(LocalDateTime.now());
plan.setUpdateUserId("101");
plan.setUpdateUserName("小明");
plan.setUpdateTime(LocalDateTime.now());
plan.setDelFlag(0);
plan.setTraceId("1");
plan.setRemarks("测试小明");
return plan;
}
public Plan insertPlan() {
Plan plan = getPlan();
//会自动填充自增长的id
planMapper.insert(plan);
return plan;
}
}
SelectTestApp.java
package com.tiglle.mp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.tiglle.mp.entity.Plan;
import com.tiglle.mp.mapper.PlanMapper;
import com.tiglle.mp.service.PlanService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SelectTestApp {
//service 封装了 mapper,方法名字可能不一样
@Autowired
private PlanService planService;
@Autowired
private PlanMapper planMapper;
/*
---------------------------------------------------------------------------------------------查询所有
*/
@Test
public void mpTest() {
List<Plan> plans = planMapper.selectList(null);
System.out.println(plans.size() + "==========================");
}
/*1.
---------------------------------------------------------------------------------------------List<Map<String, Object>>查询为此结构
1.当查询的字段很少时,可以使用此方法,配合queryWrapper.select("字段1","字段2") 使用
2.当特殊查询,实体类没有字段能够对应上时使用:queryWrapper.select("avg(age) as avgAge","min(age) as minAge")
k为表字段(非实体属性),v为表值
---------------------------------------------------------------------------------------------selectObjs查询:如果查询多个,只返回第一个字段的值
因为不知道那一列的具体类型,所以用Object接收
1.当只返回一列数据的时候可以使用
*/
@Test
public void mpTest2() {
Plan plan = new CommonTestApp().insertPlan();
QueryWrapper<Plan> queryWrapper = new QueryWrapper<>();
//1.
queryWrapper.select("locno","order_no as orderNo");
queryWrapper.eq("locno", plan.getLocno());
//2.
queryWrapper.select("avg(plan_box_num) as avgPlanBoxNum","min(plan_pieces_num) as minPlanPiecesNum").groupBy("service_reason_code").having("1={0}",1);
List<Map<String, Object>> maps = planMapper.selectMaps(queryWrapper);
maps.forEach(map -> map.forEach((k, v) -> System.out.print("k=" + k + ",v=" + v + "||")));
queryWrapper.select("locno");
List<Object> objects = planMapper.selectObjs(queryWrapper);
System.out.println(objects);
}
/*
---------------------------------------------------------------------------------------------condition的用法:为true时sql拼接此条件,false时不拼接
方法:xxxxxx(boolean condition, R column, Object val)
*/
@Test
public void mpTest7() {
QueryWrapper<Plan> queryWrapper = new QueryWrapper<>();
String locno = "";
queryWrapper.eq(StringUtils.isNotEmpty(locno),"locno",locno);
List<Plan> plans = planMapper.selectList(queryWrapper);
System.out.println(plans);
}
/*
---------------------------------------------------------------------------------------------查询部分字段的方法
1.QueryWrapper的select(String... columns)方法,查询指定字段
2.QueryWrapper的select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)方法,不查询指定字段
*/
@Test
public void mpTest6() {
QueryWrapper<Plan> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id,order_no");
//不查询字段 create_time,update_time
queryWrapper.select(Plan.class,temp->!temp.getColumn().equals("create_time")&&!temp.getColumn().equals("update_time"));
List<Plan> plans = planMapper.selectList(queryWrapper);
System.out.println(plans);
}
/*
---------------------------------------------------------------------------------------------QueryWrapper(T Entity)条件构造器
1.使用public QueryWrapper(T entity)构造器,传入实体对象
2.实体有值得字段会加入sql条件拼接
3.实体字段可以使用@TableField(condition = SqlCondition.LIKE)或者手写条件:condition = "%s>#{%s}",默认eq
4.实体的条件和wrapper的条件会一起使用,如果实体和wrapper重复,会重复拼接条件
*/
@Test
public void mpTest8() {
Plan queryPlan = new Plan();
queryPlan.setOrderNo("101ZP201906060001");
queryPlan.setLocno("101");
QueryWrapper<Plan> queryWrapper = new QueryWrapper<>(queryPlan);
queryWrapper.or().eq("locno","102");
List<Plan> plans = planMapper.selectList(queryWrapper);
System.out.println(plans);
}
/*
--------------------------------------------------------------------------------------------allEq
*--------------------------------------------------------------------------------------------allEq:全部eq(或个别isNull),有很多重载方法,根据需求选择
* */
@Test
public void mpTest9() {
QueryWrapper<Plan> queryWrapper = new QueryWrapper<>();
Map<String,Object> map = new HashMap<>();
map.put("locno","101");
//默认null会拼接为 order_no is null
map.put("order_no",null);
//默认 null2IsNull 为true(拼接null为 is null),false的话,忽略null的字段
queryWrapper.allEq(map,false);
List<Plan> plans = planMapper.selectList(queryWrapper);
System.out.println(plans);
}
/*
---------------------------------------------------------------------------------------------分页查询:
必须将分页插件PaginationInterceptor注入到spring,否则查询的是所有记录(没有分页||逻辑分页):com.tiglle.mp.config.MybatisPlusConfiguration.paginationInterceptor
*/
@Test
public void mpTest3() {
/*searchCount:是否查询总条数*/
IPage<Plan> page = planMapper.selectPage(new Page(1, 10).setSearchCount(false),null);
List<Plan> records = page.getRecords();
System.out.println(page);
}
/*
--------------------------------------------------------------------------------------------自定义sql时:customSqlSegment属性:翻译后的mysql的where和后面的条件
:sqlSelect属性:需要查询的字段
*/
@Test
public void mpTest1() {
QueryWrapper<Plan> wrapper = new QueryWrapper();
wrapper.select("id");//由于
wrapper.eq("locno","101");
List<Plan> list = planMapper.customSelectList(wrapper);
list.forEach(System.out::println);
}
/*
---------------------------------------------------------------------------------------------自定义分页查询,
注意Wrapper的getCustomSqlSegment():获取所有条件
*/
@Test
public void mpTest4() {
QueryWrapper<Plan> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("locno","101");
IPage<Plan> page = planMapper.selectCustomPage(new Page(1,10),queryWrapper);
List<Plan> records = page.getRecords();
System.out.println(page);
}
/*
---------------------------------------------------------------------------------------------自定义分页关联查询:
1.xml写sql,如果只查询Plan主表部分,用Plan这个Entity接收即可,主表和次表都查询,用map接收(条件也是同理:只有主表或者次表的话,可以用QueryWrapper封装条件,都有的话用map封装条件)
2.Mapper使用@Select注解写Sql,返回主表和次表的字段,用Map接收返回*/
@Test
public void mpTest5() {
Map<String,Object> map = new HashMap<>();
map.put("locno","101");
IPage<Plan> page = planMapper.selectRelationPage(new Page(1,10),map);
List<Plan> records = page.getRecords();
System.out.println(page);
IPage<Map<String,Object>> page1 = planMapper.selectRelationPage1(new Page(1,10),map);
System.out.println(page);
}
/*
---------------------------------------------------------------------------------------------Lambda 条件构造器
and()等使用
特殊的Lambda构造器
and(),or()等
*/
@Test
public void mpTest10() {
/*3种方式*/
//1.
LambdaQueryWrapper<Object> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
//2.
LambdaQueryWrapper lambdaQueryWrapper2 = new QueryWrapper<Plan>().lambda();
//3.
LambdaQueryWrapper<Plan> lambdaQueryWrapper3 = Wrappers.<Plan>lambdaQuery();
//此时可以通过方法引用的方式,防止单词误写,例:
Function<LambdaQueryWrapper<Plan>,LambdaQueryWrapper<Plan>> f = queryWrapper -> queryWrapper.eq(Plan::getOrderNo,"");
lambdaQueryWrapper3.eq(Plan::getLocno,"101").and(f);
//上下写法相等
lambdaQueryWrapper3.eq(Plan::getLocno,"101").and(lambdaQueryWrapper->lambdaQueryWrapper.eq(Plan::getOrderNo,"123"));
//普通quertWrapper可能会写成:quertWrapper.eq("locco","101");,单词写错
List<Plan> plans = planMapper.selectList(lambdaQueryWrapper3);
/*特殊的Lambda构造器,可以直接用LambdaQueryWrapper对象调用crud方法,源码还是调用了planMapper的crud方法*/
LambdaQueryChainWrapper<Plan> planLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(planMapper);
List<Plan> list = planLambdaQueryChainWrapper.eq(Plan::getLocno, "101").list();
plans.forEach(System.out::println);
}
}
UpdateOrDeleteTestApp.java
/*
合并时需要;
1,增加方法
2.自定义sql的方法写在自定义分页查询的前面
3.可以把文件拆分一下,根据select,update,insert等拆分多个文件,或者在一个文件用下划线分开
*/
/*
* 文件名:TempAppTest
* 版权:Copyright by 启海云仓 qihaiyun.com
* 描述:
* 创建人:Administrator
* 创建时间:2019/9/21
* 修改理由:
* 修改内容:
*/
package com.tiglle.mp;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import com.tiglle.mp.entity.Plan;
import com.tiglle.mp.mapper.PlanMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* 〈一句话简述该类/接口的功能〉
* 〈功能详细描述〉
*
* @author Administrator
* @version 1.0
* @see UpdateOrDeleteTestApp
* @since JDK1.8
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class UpdateOrDeleteTestApp {
@Autowired
private PlanMapper planMapper;
/*
-----------------------------------------------------------------------------更新
1.int updateById(T entity); 默认null不会set值
2.int update(T entity, Wrapper<T> updateWrapper); entity为set后的语句,默认null不set,updateWrapper为where后的条件
3.updateWrapper.set().eq():直接包揽set后的语句和where后的语句
4.updateLambda同样适用 Lambda 条件构造器 和 特殊的Lambda构造器
*/
@Test
public void mpTest2() {
/*1.*/
Plan plan = new Plan();
plan.setId(22L);
plan.setLocno("102");
plan.setOrderNo(null);
int i = planMapper.updateById(plan);
/*2*/
UpdateWrapper<Plan> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("locno","102");
int update = planMapper.update(plan, updateWrapper);
/*3*/
UpdateWrapper<Plan> updateWrapper1 = new UpdateWrapper<>();
updateWrapper1.set("locno","102").eq("locno","103");
int update1 = planMapper.update(plan, updateWrapper);
/*4*/
LambdaUpdateChainWrapper<Plan> lambdaUpdateChainWrapper = new LambdaUpdateChainWrapper<Plan>(planMapper);
boolean update2 = lambdaUpdateChainWrapper.set(Plan::getLocno, "103").eq(Plan::getLocno, "102").update();
}
/*
-----------------------------------------------------------------------------删除
跟更新是一样的
*/
@Test
public void mpTest3() {
/*不演示*/
}
}
高级
CommonTest.java
package com.tiglle.mp.mp2_高级;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tiglle.mp.CommonTestApp;
import com.tiglle.mp.config.MybatisPlusConfiguration;
import com.tiglle.mp.entity.Plan;
import com.tiglle.mp.mapper.PlanMapper;
import com.tiglle.mp.service.PlanService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CommonTest {
//service 封装了 mapper,方法名字可能不一样
@Autowired
private PlanService planService;
@Autowired
private PlanMapper planMapper;
/*
---------------------------------------------------------------------------------------------逻辑删除
1.application.properties或yml中配置逻辑删除的值,缺省 0未删除,1已删除
2.LogicSqlInjector注入spring容器:com.tiglle.mp.config.MybatisPlusConfiguration.sqlInjector
或者在配置文件配置注入(3.0后废除此配置属性,使用@Bean的方式注入):mybatis-plus.global-config.sql-injector=com.baomidou.mybatisplus.mapper.LogicSqlInjector
3.实体类的逻辑删除字段加上@TableLogic注解,可以配置局部 未删除value 和 已删除delval 的值
4.加上逻辑删除后,查询和更新都会带上是否删除为 未删除 的条件
但是自定义查询和更新不会加
解决方法:1.在wrapper中加上 wrapper.eq("del_flag","1")
2.在自定义sql中加上 del_flag=1
5.查询时排除 删除字段
加上@TableField(select = false)注解
*/
@Test
public void test1(){
planMapper.deleteById(193);
/*
删除语句变为了更新语句
UPDATE plan SET del_flag=-1 WHERE id=? AND del_flag=1
*/
Plan plan = new Plan();
plan.setLocno("111");
List<Plan> plans = planMapper.selectList(null);
planMapper.update(plan,Wrappers.<Plan>lambdaQuery().eq(Plan::getId,10));
planMapper.customSelectList(new QueryWrapper<Plan>().select("*").eq("locno",1));
/*
加上逻辑删除后,查询和更新都会带上是否删除为 未删除 的条件,但是自定义查询和更新不会加
SELECT id,...,del_flag FROM plan WHERE del_flag=1
UPDATE plan SET locno=? WHERE del_flag=1 AND id = ?
select * from plan WHERE locno = ?
*/
}
/*
---------------------------------------------------------------------------------------------自动填充:创建时间,更新时间,创建人,更新人等...
1.在需要自动填充的字段上加上@TableField(fill = FieldFill.INSERT||INSERT_UPDATE)
2.建立填充处理器:com.tiglle.mp.component.MyMetaObjectHandler
*/
@Test
public void test2(){
Plan plan = CommonTestApp.getPlan();
plan.setUpdateTime(null);
plan.setCreateTime(null);
int insert = planMapper.insert(plan);
}
/*
---------------------------------------------------------------------------------------------乐观锁
1.乐观锁插件交给spring容器:com.tiglle.mp.config.MybatisPlusConfiguration.optimisticLockerInterceptor
2.在实体类代表version的字段上加上@Version注解,支持的数据类型:int,Integer,long,Long,Date,Timestamp,LocalDateTime
3.支持的方法:仅支持 updateById(id) 与 update(entity, wrapper) 方法,在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
*/
@Test
public void test3(){
Integer version = 1;
Plan plan1 = new Plan();
plan1.setLocno("111");
plan1.setVersionNum(version);
QueryWrapper<Plan> queryWrapper = Wrappers.query();
queryWrapper.eq("id",198);
planMapper.update(plan1,queryWrapper);
//UPDATE plan SET locno=?, update_time=?, version_num=? WHERE del_flag=1 AND id = ? AND version_num = ?
//在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
Integer version2 = 2;
Plan plan2 = new Plan();
plan2.setLocno("111");
plan2.setVersionNum(version);
queryWrapper.eq("id",198);
planMapper.update(plan2,queryWrapper);
//UPDATE plan SET locno=?, update_time=?, version_num=? WHERE del_flag=1 AND id = ? AND version_num = ? AND id = ? AND version_num = ?
//两个version_num条件,值为1
}
/*
---------------------------------------------------------------------------------------------性能分析插件
1.性能分析插件注入spring容器:com.tiglle.mp.config.MybatisPlusConfiguration.performanceInterceptor
*/
@Test
public void test4(){
List<Plan> plans = planMapper.selectList(null);
}
/*
---------------------------------------------------------------------------------------------执行sql分析打印
1.引入p6spy 依赖:完美的输出打印 SQL 及执行时长 需要mp的版本为3.1.0 以上版本
2.配置
driver-class-name 为 p6spy 提供的驱动类
url 前缀为 jdbc:p6spy 跟着冒号为对应数据库连接地址
3.增加配置文件spy.properties
*/
@Test
public void test5(){
List<Plan> plans = planMapper.selectList(Wrappers.<Plan>lambdaQuery().select(Plan::getLocno).eq(Plan::getId,198));
/*
sql日志会自动把?填充
SELECT locno FROM plan WHERE del_flag=1 AND id = 198
*/
}
/*
---------------------------------------------------------------------------------------------多租户sql解析器:多用户时自动添加区分用户的条件
1.属于sql解析部分,依赖mp的分页插件,需要在分页插件中设置解析器,但是不是只针对分页方法有效,只是因为拦截时机问题,所以在分页插件中设置
:com.tiglle.mp.config.MybatisPlusConfiguration.paginationInterceptor
2.特定sql过滤:某个方法不增加sql信息
1.方式一:分页插件中设置,缺点是对需要的每个EntityMapper都要设置:com/tiglle/mp/config/MybatisPlusConfiguration.java:78
2.方式二:方法上增加注解@SqlParser(filter = true):com.baomidou.mybatisplus.annotation.SqlParser
mp3.1.1之前的版本还需要在配置文件中加一个配置mybatis-plus.global-config.sql-parser-cache=true:application.properties:38
*/
@Test
public void test6(){
Plan plan = new Plan();
plan.setId(198L);
plan.setLocno("234");
List<Plan> palns = planMapper.selectList(Wrappers.<Plan>query().select("id"));
int i = planMapper.updateById(plan);
List<Plan> palns2 = planMapper.customSelectList(Wrappers.<Plan>query().select("id").eq("customer_no",1234));
//2.特定sql过滤:某个方法不增加sql信息
IPage<Plan> planIPage = planMapper.selectCustomPage(new Page(1L, 10L), Wrappers.<Plan>query().select("id").eq("customer_no",1234));
/*
1.查询或更新删除等,都会自动带上多租户的条件customer_no = 101
SELECT id FROM plan WHERE plan.customer_no = 101 AND del_flag = 1
UPDATE plan SET locno = '234', update_time = '2019-11-25T23:35:38.915' WHERE plan.customer_no = 101 AND id = 198 AND del_flag = 1
2.自定义sql也会带上多租户条件
SELECT id FROM plan WHERE plan.customer_no = 101
3.wrapper条件加了多租户字段时,会重复拼接条件
SELECT id FROM plan WHERE plan.customer_no = 101 AND customer_no = 1234
4.特定sql过滤:某个方法不增加sql信息
SELECT COUNT(1) FROM plan WHERE customer_no = 1234
*/
}
/*
---------------------------------------------------------------------------------------------动态表名
:Plan表的查询可以替换为自己想要的表,eg:plan ---> plan_2019
1.属于sql解析部分,依赖mp的分页插件,需要在分页插件中设置解析器:com/tiglle/mp/config/MybatisPlusConfiguration.java:83
2.注意:
1.要替换的表名eq:testDynamicTableName为null的时候,不会替换,会查询原表
2.自定义方法也会被替换,特定sql过滤会同事过滤掉 多租户 和 动态表名 :com/tiglle/mp/config/MybatisPlusConfiguration.java:107,包括@SqlParser(filter = true)注解
*/
@Test
public void test7(){
//模拟用户传入的表名,如果为null,还是查询原表plan
String tableName = "plan_2019";/*request.getPatameter("tableName")*/
MybatisPlusConfiguration.testDynamicTableName = tableName;
//如果是查询plan的,替换为plan_2019
List<Plan> plans = planMapper.selectList(Wrappers.<Plan>query().select("id"));
//自定义方法也会被处理替换
List<Plan> plans1 = planMapper.customSelectList(Wrappers.<Plan>query().select("id").eq("locno", "101"));
//特定sql过滤会同事过滤掉 多租户 和 动态表名 :com/tiglle/mp/config/MybatisPlusConfiguration.java:107,包括@SqlParser(filter = true)注解
IPage<Plan> planIPage = planMapper.selectCustomPage(new Page(1L, 10L), Wrappers.<Plan>query().select("id").eq("locno", "101"));
/*
SELECT id FROM plan_2019 WHERE plan_2019.customer_no = 101 AND del_flag = 1
//自定义方法也会被处理替换
SELECT id FROM plan_2019 WHERE plan_2019.customer_no = 101 AND locno = ?
//特定sql过滤会同事过滤掉 多租户 和 动态表名 :com/tiglle/mp/config/MybatisPlusConfiguration.java:107,包括@SqlParser(filter = true)注解
select * from plan WHERE locno = ? LIMIT ?,?
*/
}
/*
---------------------------------------------------------------------------------------------sql注入器
在mybatisplus中增加自己的通用方法
1.创建自定义方法的类:com.tiglle.mp.mysqlscriptinjector.RemoveById
2.创建注入器:com.tiglle.mp.component.MySqlinjector
3.在接口加入自定义通用方法:com.tiglle.mp.mapper.PlanMapper.removeById
注意:
1.如果每个Entity的Mapper都要写一个removeById很麻烦,可以写一个MyBaseMapper继承BaseMapper在同一继承MyBaseMapper
2.当前逻辑删除的注入和MySqlInjector的注入会冲突,解决方法:把MySqlInjector的实现类改为LogicInjector,即开启了逻辑删除,又能自定义通用方法
3.带参数的自动以通用方法还不知道怎么弄
*/
@Test
public void test8(){
int i = planMapper.removeById(1);
}
/*
---------------------------------------------------------------------------------------------mybatis选装件
看文档吧
1.InsertBatchSomeColumn:批量插入时只插入某些字段
2.LogicDeleteByIdWithFill :逻辑删除时顺便更新某些字段
3.AlwaysUpdateSomeColumnById: 更新是只更新某些字段
*/
public void test9(){}
}