mybatis plus使用
总结
内容
- 代码生成器-逆向工程
- 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 {@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<>#{%s}等价于“属性名<>属性值”;%s是“属性名”,#{%s}是“属性值”,<>是“<>”
@TableField(condition = "%s<#{%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操作表。
怎么用:
- 继承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)
作者声明
- 文章如有问题,欢迎指正!!!
mybatis plus使用相关推荐
- mybatis查询报错:com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from string
mybatis查询报错: com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from strin ...
- MyBatis的插入后获得主键的方式
需求: 使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法: 在mapper中指定keyProperty属性,示例如下: <insert id=" ...
- mybatis使用注解开发
mybatis使用注解开发 面向接口编程 在之前我们是通过面向对象编程,但是在真正开发的时候我们会选择面向接口编程. 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的 ...
- mybatis ResultMap
ResultMap 解决属性名和字段的名称不一致的问题. 查询为null的问题 创建java实体类: public class User {private int id; //idprivate St ...
- mybatis配置文件解析
mybatis配置文件解析 mybatis核心配置文件`mybatis-config.xml文件. mybatis的配置文件包含了会深深影响mybatis行为的设置和属性信息. 能配置的内容: con ...
- mybatis CRUD操作
mybatis CRUD操作 select select标签是mybatis最常用的标签之一. select语句有很多属性可以详细的配置每一天sql语句. id 命名空间唯一的标识. 接口中的方法名与 ...
- java mybatis基础
java mybatis基础 1.1 什么是mybatis? mybatis是一个优秀的持久层框架. 避免几乎所有的JDBC代码和手动设置参数以及获取结果集的过程. 可以使用简单的xml或者注解来配置 ...
- mybatis的资源过滤错误及xml文件编码错误
mybatis 解决maven项目内资源过滤的问题 写的配置文件无法被导出或者生效的问题. 解决方案: <build><resources><resource>&l ...
- Mybatis传递多个参数的4种方式
现在大多项目都是使用Mybatis了,但也有些公司使用Hibernate.使用Mybatis最大的特性就是sql需要自己写,而写sql就需要传递多个参数.面对各种复杂的业务场景,传递参数也是一种学问. ...
- SpringBoot (五) :SpringBoot整合mybatis
说在前面 mybatis刚开始使用的时候比较麻烦,需要各种配置文件.实体类.dao层映射关联.还有一大推其它配置.初期开发了generator可以根据表结果自动生产实体类.配置文件和dao层代码,可以 ...
最新文章
- 40个迹象表明你还是PHP菜鸟
- 【工具类】JDBCUtils,数据库连接池
- 分布式锁-zk临时节点
- css设置背景图片缩小,css3 设置背景图片大小(缩略图形式缩小)
- python 字符串总结
- java在类中创建一个对象_在另一个类中创建类对象
- CloudStack4.10+GlusterFS4.10测试
- XJava程序设计专家门诊
- 程序员社区骂战:不满政治正确,LLVM元老宣布退出
- mvn compile遇到的问题:-source1.3 中不支持注释
- 进程调度算法的模拟实现
- 夜晚网速变慢与网站服务器开机数量减少有关,【网络】网速慢的原因与对策
- JS实现图片不存在时显示默认图片
- linux配置dhcp超级作用域,Linux DHCP服务器 超级作用域
- ArcEngine ISymbol效果预览
- 蚂蚁金服-微贷事业群 (北京、杭州)招前端
- 暗影精灵7安装Ubuntu双系统、RTX3060 Nvidia 驱动及搭建深度学习环境
- 网易web安全:课后问题-CSRF
- 《C语言》4小时不挂科【猴博士爱讲课】(学习笔记)
- java制作SM2证书
热门文章
- css木马式自动轮播,基于jQuery实现自动轮播旋转木马特效_jquery
- ubuntu下输入法突然崩溃(只能选择第一个预选词,选择其他预选词会变成数字)的解决办法
- kno DNS 03 Tips - DNS Cookies
- 制作一个遍历当前子目录的Makefile
- linux下 复制文件显示进度 alias cp
- springboot整合rpc远程调用_SpringBoot—-JsonRpc跨语言远程调用协议 - Java天堂
- 8plus基带电源供电线路_iPhone7显示手机无服务还有感叹号,基带通病问题,你中招了吗?...
- 相机标定-opencv
- mysql开发与运维_专业的MySQL开发规范
- php学生成绩管理系统完整源代码,PHP学生成绩管理系统