赞
踩
- 代码生成器-逆向工程
- 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.代码生成器
// 使用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();
查: //根据对象进行查询 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);
//条件查询一个,返回结果为多个不报错(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));
//概念:直接操作实体类,所以不需要注入Mapper;之前的方式,需要通过xxxMapper(Wrapper)来进行CRUD
//插入或更新
Boolean flag = admin.insertOrUpdate();
@TableName(“mp_user”)
@TableId
@TableField(“real_name”)
po中的属性不对应表中的字段
第1种方式:transient 关键字,不参与序列化
第2种方式:static 关键字,静态属性
第3种方式:@TableField(exist=false):标明不是数据库表中存在的字段
书写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);
}
}
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();
@Test
public void batch() {
User user = new User();
user.setName("xcrj1");
user.setAge(20);
userService.save(user);
//userService.saveOrUpdateBatch(userList);
}
/*** * 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); }
this.qrtzDrlService.removeById(1L);
@Test
public void remove() {
Boolean flag = userService.lambdaUpdate()
.eq(User::getAge, 25)
.remove();
}
@Test
public void updateById() {
// 根据user对象中的主键id
Boolean flag = userService.updateById(user);
}
@Test
public void chainUpdate() {
Boolean flag = userService.lambdaUpdate().eq(User::getAge, 25).set(User::getAge, 20).update();
}
public void update() {
boolean success = userService.lambdaUpdate()
.setSql("age= age+ 1")
.eq(User::getId, id)
.update();
}
QrtzStu stu = this.qrtzStuService.getById(id);
this.stuService.lambdaQuery()
.eq(Stu::getId,id)
.eq(Stu::getName,"xcrj").one();
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);
}
@Test
public void chain() {
List<User> userList = userService.lambdaQuery().gt(User::getAge,25).like(User::getName, "雨").like();
}
@Test
public void chain() {
List<User> userList = userService.lambdaQuery().gt(User::getAge,25).like(User::getName, "雨").last("limit 1").one();
}
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);
}
/***
* 根据id查询
*/
@Test
public void selectById() {
User user = userMapper.selectById(1088248166370832385L);
}
传入对象-对象属性为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和空处理
* 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);
}
/***
* 使用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);
}
/***
* 名字中包含雨年并且龄大于等于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);
}
/***
* 名字中包含雨年并且龄大于等于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);
}
/***
* 名字为王姓或者年龄大于等于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);
}
/***
* 名字为王姓或者年龄大于等于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);
}
/***
* 开始利用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);
}
/***
* (年龄小于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);
}
/***
* 年龄为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);
}
/***
* 查询结果只有一个
*/
@Test
public void selectOne1() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "刘雨红").lt("age", 40);
User user = userMapper.selectOne(queryWrapper);
}
/***
* 查询满足条件的总记录数量
* 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适用 聚集函数使用的场景 * 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); }
/***
* 名字中包含雨并且年龄小于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);
}
/***
* 名字中包含雨并且年龄小于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);
}
对象
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(); }
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);
}
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);
}
是什么:
为什么:
怎么用:
@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;
}
public interface AdminMapper extends BaseMapper<User> {
}
/***
* 这个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
model
# insertStrategy为null和空都不成SQL语句
@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
private String name;
作用:
application.yml
mybatis-plus:
global-config:
db-config:
insert-strategy: not_empty
application.yml
mybatis-plus:
config-location: classpath:/mybatis-config.xml
作用
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>
作用:数据库表都加上了前缀;实体类没加驼峰前缀
mybatis-plus:
global-config:
db-config:
table-prefix: mp_
作用:下划线转驼峰
mybatis-plus:
map-underscore-to-camel-case: true
生成:
使用: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;
}
todo(xcrj)
todo(xcrj)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。