mybatis plus使用
目录总结注解常用注解排除字段查询查询方式idnullisNotBlankdate_format子查询betweenisNotNullor()orderByDesc/Asclambda括号nestedinselectOneselectCount聚集函数selectMapsselectList指定列select对象+@TableField分页sql在xml中sql在mapper中AR模式主键默认主键策
总结
内容
- 代码生成器-逆向工程
- Where条件构造:使用LambdaWrapper更好
- 将AR模式与普通模式混用
- LambdaChain链式写法:只有查询和更新有链式写法
- AR模式:对代码有一定侵入性;po类需要继承Model<User>
- 使用通用service,我们不必写dao层(Mapper)-还是不要使用通用service,一般server层需要传递dto,通用service传递的是Wrapper
- 查询-分页查询;多表查询;联结查询(一对多,多对一)
- 插入-逐条;batch;xml中foreach
- 自定义sql:在mapper中书写方法和自定义sql;在mapper中书写方法,在xml中书写自定义sql
- 一些注解:对po类有侵入性主键生成策略:默认策略雪花算法;INPUT类型-自己设置自动填充插件
- 一些配置:id生成策略(雪花算法);SQL生成策略-字段插入策略(为null为empty时生不生成sql语句)
重点
一句话:通用service(批量插入)、lambda链式语法、根据对象进行查询-防止空指针异常、联结查询、分页查询
0.ORM框架、SQL语句、联结查询、分页查询、事务
1.根据对象进行查询、防止空指针异常-SQL生成策略、
2.可用特点:通用service(批量插入)、lambda链式语法、
3.多租户、逻辑删除
4.事务
5.代码生成器
Wrapper
// 使用Wrappers工具类
LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.<User>lambdaQuery();
// new关键字
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(name), "name", name)
// 链式语法:LambdaQueryChainWrapper
List<User> userList = new LambdaQueryChainWrapper<User>(userMapper)
.like(User::getName, "雨")
.ge(User::getAge, 20).list();
常用SQL
查:
//根据对象进行查询
QueryWrapper<User> queryWrapper = new QueryWrapper<>(whereUser);
queryWrapper.like("name", "雨").lt("age", 40);
List<User> userList = userMapper.selectList(queryWrapper);
//根据id查询
User user = userMapper.selectById(1088248166370832385L);
//防止空指针异常
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.like(StringUtils.isNotBlank(name), "name", name)
.like(StringUtils.isNotBlank(email), "email", email);
List<User> userList = userMapper.selectList(queryWrapper);
//查询一个
User user = userMapper.selectOne(queryWrapper);
//计数
Integer count = userMapper.selectCount(queryWrapper);
//分页
IPage<User> iPage = userMapper.selectPage(new Page<User>(currentPage,pageSize), queryWrapper);
//分页
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age", 26);
//参数:当前页数,每页几条数据
Page<User> page = new Page<User>(1, 2);
//因为,这个查询本质上是查询两次;如果有不需要总条数的需求 例如,页面显示全部,每页往下拉;Page的最后一个参数传入false即可
//Page<User> page = new Page<User>(1, 2,false);
IPage<User> iPage = userMapper.selectPage(new Page<User>(1, 2), queryWrapper);
iPage.getPages();
iPage.getTotal();
List<User> userList = iPage.getRecords();
//增加,属性值为null时不会生成sql语句。
int rows=userMapper.insert(user);
//根据id删除
int rows = userMapper.deleteById(1087982257332887553L);
//根据条件删除
int rows = userMapper.delete(lambdaQueryWrapper);
//根据id更新
int rows = userMapper.updateById(user);
//根据条件更新
int rows = userMapper.update(user, lambdaUpdate);
通用service
//条件查询一个,返回结果为多个不报错(false)
userService.getOne(Wrappers.<User>lambdaQuery().gt(User::getAge, 45), false);
//链式查询
List<User> userList = userService.lambdaQuery().gt(User::getAge, 25).like(User::getName, "雨").list();
//分页查询
IPage<DictType> iPage=iDictTypeService.page(new Page<DictType>(currentPage,pageSize),lambda);
//批量插入,数据达到两条插入一次,默认1000条
userService.saveBatch(userList, 2);
//条件更新
Boolean flag = userService.lambdaUpdate().eq(User::getAge, 25).set(User::getAge, 20).update();
//利用更新进行删除
Boolean flag = userService.lambdaUpdate().eq(User::getAge, 25).remove();
//条件删除
Boolean flag=iRoleMenuService.remove(Wrappers.<RoleMenu>lambdaQuery().eq(RoleMenu::getRole,id));
AR模式
//概念:直接操作实体类,所以不需要注入Mapper;之前的方式,需要通过xxxMapper(Wrapper)来进行CRUD
//插入或更新
Boolean flag = admin.insertOrUpdate();
自定义SQL
- 使用注解直接写在xxxMapper类上
- 使用xml文件写在mapper.xml上
注解
常用注解
@TableName(“mp_user”)
- 指定表名和po的对应
@TableId
- 表明这个po属性是表中主键
@TableField(“real_name”)
- po属性和bc字段对应关系
排除字段
po中的属性不对应表中的字段
第1种方式:transient 关键字,不参与序列化
第2种方式:static 关键字,静态属性
第3种方式:@TableField(exist=false):标明不是数据库表中存在的字段
通用service增删改查
- 使用方法跟通用mapper差不多
使用步骤
书写service接口
public interface UserService extends IService<User> {
}
书写serviceImpl实现类
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
使用
public class ServiceTest extends BaseTest {
@Autowired
private UserService userService;
/***
* param2=false: 结果大于一个,选择第一个
* param2=true: 报错
*/
@Test
public void selectOne1() {
userService.getOne(Wrappers.<User>lambdaQuery().gt(User::getAge, 45),false);
}
}
括号-nested
SELECT id,code,name,mark,img_label,img_full,org_id,start_date,end_date FROM xcrj_info WHERE ((id = ? OR name = ?) AND org_id = ?)
xcrjInoList= xcrjService.lambdaQuery()
.nested(o -> o
.eq(XcrjInfo::getId, reqVO.getId())
.or()
.eq(XcrjInfo::getName, reqVO.getName()))
.eq(XcrjInfo::getOrgId, orgId)
.list();
插入-save
@Test
public void batch() {
User user = new User();
user.setName("xcrj1");
user.setAge(20);
userService.save(user);
//userService.saveOrUpdateBatch(userList);
}
批量插入操作-saveBatch
/***
* userService.saveBatch(userList, 2);
* param2:默认1000,数据达到多少条提交1次
*/
@Test
public void batch() {
User user1 = new User();
user1.setName("xcrj1");
user1.setAge(20);
User user2 = new User();
user2.setId(123456667L);
user2.setName("xcrj2");
user2.setAge(20);
List<User> userList = Arrays.asList(user1, user2);
userService.saveBatch(userList, 2);
//userService.saveOrUpdateBatch(userList);
}
删除-removeById
this.qrtzDrlService.removeById(1L);
删除-lambdaUpdate-remove
@Test
public void remove() {
Boolean flag = userService.lambdaUpdate()
.eq(User::getAge, 25)
.remove();
}
根据ID更新-updateById
@Test
public void updateById() {
// 根据user对象中的主键id
Boolean flag = userService.updateById(user);
}
链式更新操作-lambdaUpdate
@Test
public void chainUpdate() {
Boolean flag = userService.lambdaUpdate().eq(User::getAge, 25).set(User::getAge, 20).update();
}
更新-lambdaUpdate-setSql
public void update() {
boolean success = userService.lambdaUpdate()
.setSql("age= age+ 1")
.eq(User::getId, id)
.update();
}
查询-getById
QrtzStu stu = this.qrtzStuService.getById(id);
查询-lambdaQuery and
this.stuService.lambdaQuery()
.eq(Stu::getId,id)
.eq(Stu::getName,"xcrj").one();
分页查询-page
public TableDataInfo<QrtzStudent> page(@RequestBody StudentPageReqVO reqVO) {
if (reqVO.getPageNum() == -1) {
List<QrtzStudent> drls = this.qrtzStudentService.lambdaQuery()
.eq(StrUtil.isNotBlank(reqVO.getStudentName()), QrtzStudent::getStudentName, reqVO.getStudentName()).list();
return super.getDataTable(drls);
}
Page<QrtzStudent> page = new Page<>(reqVO.getPageNum(), reqVO.getPageSize());
IPage<QrtzStudent> ipage = this.qrtzStudentService.page(page, Wrappers.<QrtzStudent>lambdaQuery().eq(StrUtil.isNotBlank(reqVO.getStudentName()), QrtzStudent::getStudentName, reqVO.getStudentName()));
List<QrtzStudent> drls = ipage.getRecords();
return super.getDataTable(drls);
}
链式查询操作-lambdaQuery
@Test
public void chain() {
List<User> userList = userService.lambdaQuery().gt(User::getAge,25).like(User::getName, "雨").like();
}
限制查询数量-limit
@Test
public void chain() {
List<User> userList = userService.lambdaQuery().gt(User::getAge,25).like(User::getName, "雨").last("limit 1").one();
}
条件添加SQL condition
condition=true,才把后面的SQL添加
不传入对象-需要自己写condition语句
public TableDataInfo<QrtzStudent> page(@RequestBody StudentPageReqVO reqVO) {
if (reqVO.getPageNum() == -1) {
List<QrtzStudent> drls = this.qrtzStudentService.lambdaQuery()
.eq(StrUtil.isNotBlank(reqVO.getStudentName()), QrtzStudent::getStudentName, reqVO.getStudentName()).list();
return super.getDataTable(drls);
}
Page<QrtzStudent> page = new Page<>(reqVO.getPageNum(), reqVO.getPageSize());
IPage<QrtzStudent> ipage = this.qrtzStudentService.page(page, Wrappers.<QrtzStudent>lambdaQuery().eq(StrUtil.isNotBlank(reqVO.getStudentName()), QrtzStudent::getStudentName, reqVO.getStudentName()));
List<QrtzStudent> drls = ipage.getRecords();
return super.getDataTable(drls);
}
Mapper增删改查
查询方式
- Wappers:工具类
- AbstractWrapper
- QueryWrapper
- LambdaQueryWrapper:不用关心表字段名,防止误写
- LambdaQueryChainWrapper:链式写法,一气呵成
- 自定义sql:在mapper中书写自定义sql;在xml中书写自定义sql
selectById
/***
* 根据id查询
*/
@Test
public void selectById() {
User user = userMapper.selectById(1088248166370832385L);
}
对象属性为null
传入对象-对象属性为null默认不生成sql语句
不传入对象-需要自己写condition语句
condition=true,才把后面的SQL添加
/***
* 对象中属性为null则不生成sql语句
*/
@Test
public void selectByObjectWrapper() {
User whereUser = new User();
whereUser.setName("刘雨红");
whereUser.setAge(32);
QueryWrapper<User> queryWrapper = new QueryWrapper<>(whereUser);
queryWrapper.like("name", "雨").lt("age", 40);
List<User> userList = userMapper.selectList(queryWrapper);
}
对象属性为null和空
/***
* 字段判断null和空处理
* condition生成对应sql
* 利用了带condition的语句;condition=true则生成对应SQL
*/
@Test
public void selectByConditionWrapper(String name, String email) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.like(StringUtils.isNotBlank(name), "name", name)
.like(StringUtils.isNotBlank(email), "email", email);
List<User> userList = userMapper.selectList(queryWrapper);
}
date_format
/***
* 使用mysql函数date_format(字段名,格式): 格式化时间到字符串 只要是2019-02-14就可以,不管具体时间
* 使用mybatis-plus apply("={0}","") 应用函数 {0}可变参数
* 创建日期为2019年2月14日并且直属上级为名字为王姓
* date_format(create_time,'%Y-%m-%d')='2019-02-14' and manager_id in (select id from user where name like '王%')
*/
@Test
public void selectByWrapper4() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.apply("date_format(create_time,'%Y-%m-%d')={0}", "2019-02-14")
//.apply("date_format(create_time,'%Y-%m-%d')=2019-02-14 or true or true")//产生sql注入
.inSql("manager_id", "select id from user where name like '王%'");
List<User> userList = userMapper.selectList(queryWrapper);
}
子查询
/***
* 使用mysql函数date_format(字段名,格式): 格式化时间到字符串 只要是2019-02-14就可以,不管具体时间
* 使用mybatis-plus apply("={0}","") 应用函数 {0}可变参数
* 创建日期为2019年2月14日并且直属上级为名字为王姓
* date_format(create_time,'%Y-%m-%d')='2019-02-14' and manager_id in (select id from user where name like '王%')
*/
@Test
public void selectByWrapper4() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.apply("date_format(create_time,'%Y-%m-%d')={0}", "2019-02-14")
//.apply("date_format(create_time,'%Y-%m-%d')=2019-02-14 or true or true")//产生sql注入
.inSql("manager_id", "select id from user where name like '王%'");
List<User> userList = userMapper.selectList(queryWrapper);
}
between
/***
* 名字中包含雨年并且龄大于等于20且小于等于40并且email不为空
* name like '%雨%' and age between 20 and 40 and email is not null
*/
@Test
public void selectByWrapper2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "雨").between("age", 20, 40).isNotNull("email");
List<User> userList = userMapper.selectList(queryWrapper);
}
isNotNull
/***
* 名字中包含雨年并且龄大于等于20且小于等于40并且email不为空
* name like '%雨%' and age between 20 and 40 and email is not null
*/
@Test
public void selectByWrapper2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "雨").between("age", 20, 40).isNotNull("email");
List<User> userList = userMapper.selectList(queryWrapper);
}
or()
/***
* 名字为王姓或者年龄大于等于25,按照年龄降序排列,年龄相同按照id升序排列
* name like '王%' or age>=25 order by age desc,id asc likeRoght() ge >=
* 这里用or() 因为默认是and
*/
@Test
public void selectByWrapper3() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.likeRight("name", "王").or().ge("age", 25).orderByDesc("age").orderByAsc("id");
List<User> userList = userMapper.selectList(queryWrapper);
}
orderByDesc/Asc
/***
* 名字为王姓或者年龄大于等于25,按照年龄降序排列,年龄相同按照id升序排列
* name like '王%' or age>=25 order by age desc,id asc likeRoght() ge >=
* 这里用or() 因为默认是and
*/
@Test
public void selectByWrapper3() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.likeRight("name", "王").or().ge("age", 25).orderByDesc("age").orderByAsc("id");
List<User> userList = userMapper.selectList(queryWrapper);
}
lambda
/***
* 开始利用java函数表达式
* 名字为王姓并且(年龄小于40或邮箱不为空)
* name like '王%' and (age<40 or email is not null)
*/
@Test
public void selectByWrapper5() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.likeRight("name", "王").and(wq -> wq.lt("age", 40).or().isNotNull("email"));
List<User> userList = userMapper.selectList(queryWrapper);
}
括号nested
/***
* (年龄小于40或邮箱不为空)并且名字为王姓
* (age<40 or email is not null) and name like '王%'
*/
@Test
public void selectByWrapper7() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.nested(wq -> wq.lt("age", 40).or().isNotNull("email"))
.likeRight("name", "王");
List<User> userList = userMapper.selectList(queryWrapper);
}
in
/***
* 年龄为30、31、34、35
* age in (30、31、34、35)
*/
@Test
public void selectByWrapper8() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.in("age", Arrays.asList(30, 31, 34, 35));
List<User> userList = userMapper.selectList(queryWrapper);
}
selectOne
/***
* 查询结果只有一个
*/
@Test
public void selectOne1() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "刘雨红").lt("age", 40);
User user = userMapper.selectOne(queryWrapper);
}
selectCount
/***
* 查询满足条件的总记录数量
* userMapper.selectObjs()//只返回第一列的数据
* 生成的sql语句 select count(1) ...
*/
@Test
public void selectCount1() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "雨").lt("age", 40);
Integer count = userMapper.selectCount(queryWrapper);
}
聚集函数selectMaps
/***
* selectMaps适用 聚集函数使用的场景
* 11、按照直属上级分组,查询每组的平均年龄、最大年龄、最小年龄。
* 并且只取年龄总和小于500的组。
* select avg(age) avg_age,min(age) min_age,max(age) max_age
* from user
* group by manager_id
* having sum(age) <500
*/
@Test
public void selectMapsResultMap2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.select("avg(age) avg_age", "min(age) min_age", "max(age) max_age")
.groupBy("manager_id")
.having("sum(age)<{0}", 500);
//Map<String,Object> String 列名;Object 值
List<Map<String, Object>> userMapList = userMapper.selectMaps(queryWrapper);
}
selectList
/***
* 名字中包含雨并且年龄小于40(需求1加强版)
* 只需要id name 两列
* select 是选择几列
*/
@Test
public void selectByWrapper10() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id", "name").like("name", "雨").lt("age", 40);
List<User> userList = userMapper.selectList(queryWrapper);
}
指定列select
/***
* 名字中包含雨并且年龄小于40(需求1加强版)
* 只需要id name 两列
* select 是选择几列
*/
@Test
public void selectByWrapper10() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id", "name").like("name", "雨").lt("age", 40);
List<User> userList = userMapper.selectList(queryWrapper);
}
对象+@TableField
对象
User whereUser=new User();
whereUser.setName("刘雨红");
whereUser.setAge(32);
QueryWrapper<User> queryWrapper = new QueryWrapper<>(whereUser);
@TableField
//方式1:内置常量
@TableField(condition = SqlCondition.LIKE)
private String name;
//方式2:自定义
//%s<>#{%s}等价于“属性名<>属性值”;%s是“属性名”,#{%s}是“属性值”,<>是“<>”
@TableField(condition = "%s<#{%s}")
private Integer age;
分页
分页组件
@Configuration
public class MybatisplusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
使用
/***
* 书写过程:
* 1.加入插件 PaginationInterceptor
* 2.Page<User> page = new Page<User>(currentPage, pageSize);
* 2.IPage<User> iPage = userMapper.selectPage(page, queryWrapper);
* 3.根据iPage获取查询结果 total pages 结果
* 查询过程:实质是两次查询
* 先查询总记录数量 select count(1)
* 再查询 limit 0,2
*/
@Test
public void selectPage() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age", 26);
//参数:当前页数,每页几条数据
Page<User> page = new Page<User>(1, 2);
/***
* 因为,这个查询本质上是查询两次;如果有不需要总条数的需求 例如,页面显示全部,每页往下拉;Page的最后一个参数传入false即可
*/
//Page<User> page = new Page<User>(1, 2,false);
IPage<User> iPage = userMapper.selectPage(page, queryWrapper);
iPage.getPages();
iPage.getTotal();
List<User> userList = iPage.getRecords();
}
sql在xml中
application.yml
mybatis-plus:
mapper-locations:
- cn/juh/mapper/*
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="cn.juh.dao.UserMapper">
<select id="selectAllXml" resultType="cn.juh.entity.User">
select * from user ${ew.customSqlSegment}
</select>
</mapper>
userMapper extends BaseMapper<User>
public interface UserMapper extends BaseMapper<User> {
List<User> selectAllXml(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
}
使用
@Test
public void selectSelfDefineSqlXml() {
LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.<User>lambdaQuery();
lambdaQueryWrapper.like(User::getName, "雨").lt(User::getAge, 40);
List<User> userList = userMapper.selectAllXml(lambdaQueryWrapper);
}
sql在mapper中
mapper
/***
* 自定义sql
* ew就是WAPPER常量的内部值
* ${ew.customSqlSegment} 取出入参
*/
@Select("select * from user ${ew.customSqlSegment}")
List<User> selectAll(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
使用
@Test
public void selectSelfDefineSql() {
LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.<User>lambdaQuery();
lambdaQueryWrapper.like(User::getName, "雨").lt(User::getAge, 40);
List<User> userList = userMapper.selectAll(lambdaQueryWrapper);
}
AR模式
是什么:
- ActiveRecorder模式
- Model类对应于关系型数据库中的一个表;一个model类的实例对应于表中的一行记录
为什么:
- 直接通过使用实体类操作表。
- 以前是使用xxMapper操作表。
怎么用:
- 继承Model
@Data
//不根据父类的属性值来生成hashcode
@EqualsAndHashCode(callSuper = false)
public class Admin extends Model<Admin> {
private Long id;
private String name;
private Integer age;
private String email;
private Long managerId;
private LocalDateTime createTime;
}
- 继承mapper
public interface AdminMapper extends BaseMapper<User> {
}
- 直接用实体类调用CRUD方法,不用注入xxMapper
/***
* 这个model的selectOne 不会报错;查询结果有多个返回一个
*/
@Test
public void selectOne() {
Admin admin = new Admin();
LambdaQueryWrapper<Admin> lambdaQuery = Wrappers.<Admin>lambdaQuery();
lambdaQuery.eq(Admin::getName, "刘天明");
Admin adminResult = admin.selectOne(lambdaQuery);
}
主键
- 局部策略优先于全局策略
默认主键策略
-
mybatis-plus雪花算法bigint的雪花算法 19位
-
字段对应:bigint(20) 对应于java long
-
1bit不用,41bit时间戳,10bit工作机器id,12bit序列号
局部主键策略
model类
@TableId(type= IdType.AUTO)
private Long id;
IdType全部类型
/**
* 需要先设置数据库自增;数据库ID自增 ;数据库主键自增策略:插入之后会将主键值返回
*/
AUTO(0),
/**
* 默认类型-雪花算法;跟随全局;给了id会按照你给的id
*/
NONE(1),
/**
* 用户输入ID
* <p>该类型可以通过自己注册自动填充插件进行填充</p>
*/
INPUT(2),
/* 以下3种类型,设置了id不会自动填充;只有当插入对象ID 为空,才自动填充。 */
/**
* 全局唯一ID (idWorker);雪花算法
*/
ID_WORKER(3),
/**
* 字符串全局唯一ID (idWorker 的字符串表示)
*/
ID_WORKER_STR(5),
/**
* 需要先设置数据库UUID;string类型;全局唯一ID (UUID)
*/
UUID(4);
全局主键策略
application.yml
mybatis-plus:
global-config:
db-config:
id-type: uuid
配置
局部配置-insertStrategy
model
# insertStrategy为null和空都不成SQL语句
@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
private String name;
全局配置-insertStrategy
作用:
- not-empty:为null和空时都不会生成SQL
- not-null:为null时不会生成SQL
application.yml
mybatis-plus:
global-config:
db-config:
insert-strategy: not_empty
全局配置-config-location
application.yml
mybatis-plus:
config-location: classpath:/mybatis-config.xml
全局配置-type-aliases-package
作用
- resultType写包名,写包下的类名
application.yml
mybatis-plus:
type-aliases-package: cn.juh.entity
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="cn.juh.dao.UserMapper">
<select id="selectAllXml" resultType="User">
select * from user ${ew.customSqlSegment}
</select>
</mapper>
全局配置-table-prefix
作用:数据库表都加上了前缀;实体类没加驼峰前缀
mybatis-plus:
global-config:
db-config:
table-prefix: mp_
全局配置-map-underscore-to-camel-case
作用:下划线转驼峰
mybatis-plus:
map-underscore-to-camel-case: true
代码生成器
生成:
- po
- mapper类
- xml
- 通用service
- AR
- controller(只生成框架)
- 模板引擎的模板
使用:Controller、mapper类、entity、service生成位置cn.juh.generated
// 包配置
setPackageInfo(new PackageConfig()
//各种dao、service、mapper类包名
.setModuleName("generated")
// 自定义包路径
.setParent("cn.juh2")
// 这里是控制器包名,默认 controller
.setController("controller")
)
使用:xml文件位置
// 自定义输出文件目录
@Override
public String outputFile(TableInfo tableInfo) {
return projectPath + "/src/main/resources/mapper/"
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
逻辑删除
- 逻辑删除与状态不同,逻辑删除就是删除,不应该与不同状态表示删除
- Mp3.3+,如果数据库表中有专门表示逻辑删除的字段,直接配置全局策略
多租户
todo(xcrj)
事务
todo(xcrj)
作者声明
- 文章如有问题,欢迎指正!!!

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)