总结

内容

- 代码生成器-逆向工程
- 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

  1. 使用注解直接写在xxxMapper类上
  2. 使用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 {@Autowiredprivate UserService userService;/**** param2=false: 结果大于一个,选择第一个* param2=true: 报错*/@Testpublic 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对象中的主键idBoolean 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&lt;&gt;#{%s}等价于“属性名<>属性值”;%s是“属性名”,#{%s}是“属性值”,&lt;&gt;是“<>”
@TableField(condition = "%s&lt;#{%s}")
private Integer age;

分页

分页组件

@Configuration
public class MybatisplusConfig {@Beanpublic 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操作表。

怎么用:

  1. 继承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;
}
  1. 继承mapper
public interface AdminMapper extends BaseMapper<User> {}
  1. 直接用实体类调用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;
}

逻辑删除

  1. 逻辑删除与状态不同,逻辑删除就是删除,不应该与不同状态表示删除
  2. Mp3.3+,如果数据库表中有专门表示逻辑删除的字段,直接配置全局策略

多租户

todo(xcrj)

事务

todo(xcrj)

作者声明

  • 文章如有问题,欢迎指正!!!

mybatis plus使用相关推荐

  1. mybatis查询报错:com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from string

    mybatis查询报错: com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from strin ...

  2. MyBatis的插入后获得主键的方式

    需求: 使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法: 在mapper中指定keyProperty属性,示例如下: <insert id=" ...

  3. mybatis使用注解开发

    mybatis使用注解开发 面向接口编程 在之前我们是通过面向对象编程,但是在真正开发的时候我们会选择面向接口编程. 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的 ...

  4. mybatis ResultMap

    ResultMap 解决属性名和字段的名称不一致的问题. 查询为null的问题 创建java实体类: public class User {private int id; //idprivate St ...

  5. mybatis配置文件解析

    mybatis配置文件解析 mybatis核心配置文件`mybatis-config.xml文件. mybatis的配置文件包含了会深深影响mybatis行为的设置和属性信息. 能配置的内容: con ...

  6. mybatis CRUD操作

    mybatis CRUD操作 select select标签是mybatis最常用的标签之一. select语句有很多属性可以详细的配置每一天sql语句. id 命名空间唯一的标识. 接口中的方法名与 ...

  7. java mybatis基础

    java mybatis基础 1.1 什么是mybatis? mybatis是一个优秀的持久层框架. 避免几乎所有的JDBC代码和手动设置参数以及获取结果集的过程. 可以使用简单的xml或者注解来配置 ...

  8. mybatis的资源过滤错误及xml文件编码错误

    mybatis 解决maven项目内资源过滤的问题 写的配置文件无法被导出或者生效的问题. 解决方案: <build><resources><resource>&l ...

  9. Mybatis传递多个参数的4种方式

    现在大多项目都是使用Mybatis了,但也有些公司使用Hibernate.使用Mybatis最大的特性就是sql需要自己写,而写sql就需要传递多个参数.面对各种复杂的业务场景,传递参数也是一种学问. ...

  10. SpringBoot (五) :SpringBoot整合mybatis

    说在前面 mybatis刚开始使用的时候比较麻烦,需要各种配置文件.实体类.dao层映射关联.还有一大推其它配置.初期开发了generator可以根据表结果自动生产实体类.配置文件和dao层代码,可以 ...

最新文章

  1. 40个迹象表明你还是PHP菜鸟
  2. 【工具类】JDBCUtils,数据库连接池
  3. 分布式锁-zk临时节点
  4. css设置背景图片缩小,css3 设置背景图片大小(缩略图形式缩小)
  5. python 字符串总结
  6. java在类中创建一个对象_在另一个类中创建类对象
  7. CloudStack4.10+GlusterFS4.10测试
  8. XJava程序设计专家门诊
  9. 程序员社区骂战:不满政治正确,LLVM元老宣布退出
  10. mvn compile遇到的问题:-source1.3 中不支持注释
  11. 进程调度算法的模拟实现
  12. 夜晚网速变慢与网站服务器开机数量减少有关,【网络】网速慢的原因与对策
  13. JS实现图片不存在时显示默认图片
  14. linux配置dhcp超级作用域,Linux DHCP服务器 超级作用域
  15. ArcEngine ISymbol效果预览
  16. 蚂蚁金服-微贷事业群 (北京、杭州)招前端
  17. 暗影精灵7安装Ubuntu双系统、RTX3060 Nvidia 驱动及搭建深度学习环境
  18. 网易web安全:课后问题-CSRF
  19. 《C语言》4小时不挂科【猴博士爱讲课】(学习笔记)
  20. java制作SM2证书

热门文章

  1. css木马式自动轮播,基于jQuery实现自动轮播旋转木马特效_jquery
  2. ubuntu下输入法突然崩溃(只能选择第一个预选词,选择其他预选词会变成数字)的解决办法
  3. kno DNS 03 Tips - DNS Cookies
  4. 制作一个遍历当前子目录的Makefile
  5. linux下 复制文件显示进度 alias cp
  6. springboot整合rpc远程调用_SpringBoot—-JsonRpc跨语言远程调用协议 - Java天堂
  7. 8plus基带电源供电线路_iPhone7显示手机无服务还有感叹号,基带通病问题,你中招了吗?...
  8. 相机标定-opencv
  9. mysql开发与运维_专业的MySQL开发规范
  10. php学生成绩管理系统完整源代码,PHP学生成绩管理系统