当前位置:   article > 正文

mybatis plus使用_lambdaquery limit

lambdaquery limit

总结

内容

- 代码生成器-逆向工程
- 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语句)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

重点

一句话:通用service(批量插入)、lambda链式语法、根据对象进行查询-防止空指针异常、联结查询、分页查询
0.ORM框架、SQL语句、联结查询、分页查询、事务
1.根据对象进行查询、防止空指针异常-SQL生成策略、
2.可用特点:通用service(批量插入)、lambda链式语法、
3.多租户、逻辑删除
4.事务
5.代码生成器
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

常用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); 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

通用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));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

AR模式

//概念:直接操作实体类,所以不需要注入Mapper;之前的方式,需要通过xxxMapper(Wrapper)来进行CRUD

//插入或更新
Boolean flag = admin.insertOrUpdate();
  • 1
  • 2
  • 3
  • 4

自定义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> {
}
  • 1
  • 2

书写serviceImpl实现类

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
  • 1
  • 2
  • 3

使用

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);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

括号-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 = ?)
  • 1
xcrjInoList= xcrjService.lambdaQuery()
                    .nested(o -> o
                            .eq(XcrjInfo::getId, reqVO.getId())
                            .or()
                            .eq(XcrjInfo::getName, reqVO.getName()))
                    .eq(XcrjInfo::getOrgId, orgId)
                    .list();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

插入-save

@Test
public void batch() {
    User user = new User();
    user.setName("xcrj1");
    user.setAge(20);
    userService.save(user);
   //userService.saveOrUpdateBatch(userList);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

批量插入操作-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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

删除-removeById

this.qrtzDrlService.removeById(1L);
  • 1

删除-lambdaUpdate-remove

@Test
public void remove() {
    Boolean flag = userService.lambdaUpdate()
        .eq(User::getAge, 25)
        .remove();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

根据ID更新-updateById

@Test
public void updateById() {
	// 根据user对象中的主键id
    Boolean flag = userService.updateById(user);
}
  • 1
  • 2
  • 3
  • 4
  • 5

链式更新操作-lambdaUpdate

@Test
public void chainUpdate() {
    Boolean flag = userService.lambdaUpdate().eq(User::getAge, 25).set(User::getAge, 20).update();
}
  • 1
  • 2
  • 3
  • 4

更新-lambdaUpdate-setSql

public void update() {
    boolean success = userService.lambdaUpdate()
          .setSql("age= age+ 1")
          .eq(User::getId, id)
          .update();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

查询-getById

QrtzStu stu = this.qrtzStuService.getById(id);
  • 1

查询-lambdaQuery and

this.stuService.lambdaQuery()
                .eq(Stu::getId,id)
                .eq(Stu::getName,"xcrj").one();
  • 1
  • 2
  • 3

分页查询-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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

链式查询操作-lambdaQuery

@Test
public void chain() {
    List<User> userList = userService.lambdaQuery().gt(User::getAge,25).like(User::getName, "雨").like();
}
  • 1
  • 2
  • 3
  • 4

限制查询数量-limit

@Test
public void chain() {
    List<User> userList = userService.lambdaQuery().gt(User::getAge,25).like(User::getName, "雨").last("limit 1").one();
}
  • 1
  • 2
  • 3
  • 4

条件添加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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Mapper增删改查

查询方式

  • Wappers:工具类
  • AbstractWrapper
  • QueryWrapper
  • LambdaQueryWrapper:不用关心表字段名,防止误写
  • LambdaQueryChainWrapper:链式写法,一气呵成
  • 自定义sql:在mapper中书写自定义sql;在xml中书写自定义sql

selectById

/***
 * 根据id查询
 */
@Test
public void selectById() {
    User user = userMapper.selectById(1088248166370832385L);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

对象属性为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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

对象属性为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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

子查询

/***
 * 使用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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

括号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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

selectOne

/***
 * 查询结果只有一个
 */
@Test
public void selectOne1() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.like("name", "刘雨红").lt("age", 40);
    User user = userMapper.selectOne(queryWrapper);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

聚集函数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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

指定列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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

对象+@TableField

对象

User whereUser=new User();
whereUser.setName("刘雨红");
whereUser.setAge(32);
QueryWrapper<User> queryWrapper = new QueryWrapper<>(whereUser);
  • 1
  • 2
  • 3
  • 4

@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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

分页

分页组件

@Configuration
public class MybatisplusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

使用

/***
 * 书写过程:
 *  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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

sql在xml

application.yml

mybatis-plus:
  mapper-locations:
    - cn/juh/mapper/*
  • 1
  • 2
  • 3

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

userMapper extends BaseMapper<User>

public interface UserMapper extends BaseMapper<User> {
	List<User> selectAllXml(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
}
  • 1
  • 2
  • 3

使用

@Test
public void selectSelfDefineSqlXml() {
    LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.<User>lambdaQuery();
    lambdaQueryWrapper.like(User::getName, "雨").lt(User::getAge, 40);
    List<User> userList = userMapper.selectAllXml(lambdaQueryWrapper);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

sql在mapper中

mapper

/***
 * 自定义sql
 * ew就是WAPPER常量的内部值
 * ${ew.customSqlSegment} 取出入参
 */
@Select("select * from user ${ew.customSqlSegment}")
List<User> selectAll(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

使用

@Test
public void selectSelfDefineSql() {
    LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.<User>lambdaQuery();
    lambdaQueryWrapper.like(User::getName, "雨").lt(User::getAge, 40);
    List<User> userList = userMapper.selectAll(lambdaQueryWrapper);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  1. 继承mapper
public interface AdminMapper extends BaseMapper<User> {
}
  • 1
  • 2
  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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

主键

  • 局部策略优先于全局策略

默认主键策略

  • mybatis-plus雪花算法bigint的雪花算法 19位

  • 字段对应:bigint(20) 对应于java long

  • 1bit不用,41bit时间戳,10bit工作机器id,12bit序列号

局部主键策略

model类

@TableId(type= IdType.AUTO)
private Long id;
  • 1
  • 2

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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

全局主键策略

application.yml

mybatis-plus:
  global-config: 
    db-config:
      id-type: uuid
  • 1
  • 2
  • 3
  • 4

配置

局部配置-insertStrategy

model

# insertStrategy为null和空都不成SQL语句
@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
private String name;
  • 1
  • 2
  • 3

全局配置-insertStrategy

作用:

  • not-empty:为null和空时都不会生成SQL
  • not-null:为null时不会生成SQL

application.yml

mybatis-plus:
  global-config:
    db-config:
      insert-strategy: not_empty
  • 1
  • 2
  • 3
  • 4

全局配置-config-location

application.yml

mybatis-plus:
  config-location: classpath:/mybatis-config.xml
  • 1
  • 2

全局配置-type-aliases-package

作用

  • resultType写包名,写包下的类名

application.yml

mybatis-plus:
  type-aliases-package: cn.juh.entity
  • 1
  • 2

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

全局配置-table-prefix

作用:数据库表都加上了前缀;实体类没加驼峰前缀

mybatis-plus:
  global-config: 
    db-config:
      table-prefix: mp_
  • 1
  • 2
  • 3
  • 4

全局配置-map-underscore-to-camel-case

作用:下划线转驼峰

mybatis-plus: 
  map-underscore-to-camel-case: true
  • 1
  • 2

代码生成器

生成:

  • 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")
               )
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

使用:xml文件位置

// 自定义输出文件目录
@Override
public String outputFile(TableInfo tableInfo) {
    return projectPath + "/src/main/resources/mapper/"
            + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

逻辑删除

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

多租户

todo(xcrj)

事务

todo(xcrj)

作者声明

  • 文章如有问题,欢迎指正!!!
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/282259
推荐阅读
相关标签
  

闽ICP备14008679号