Mybatis-Plus

条件查询:

MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合。

 方式一:按条件查询
QueryWrapper qw = new QueryWrapper();
qw.lt("age",18);    //age小于18
List<User> userList = userDao.selectList(qw);
System.out.println(userList);

 方式二:lambda格式按条件查询
QueryWrapper<User> qw = new QueryWrapper<User>();
qw.lambda().lt(User::getAge, 10);
List<User> userList = userDao.selectList(qw);
System.out.println(userList);

 方式三:lambda格式按条件查询
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.lt(User::getAge, 10);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
并且与或者关系:
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
并且关系:10到30岁之间
    //lqw.lt(User::getAge, 30).gt(User::getAge, 10);

或者关系:小于10岁或者大于30岁
    lqw.lt(User::getAge, 10).or().gt(User::getAge, 30);
    List<User> userList = userDao.selectList(lqw);
    System.out.println(userList);
常规格式:
    qw.lt("age",65);
    qw.lt("age",18);
链式编程格式:
    qw.lt("age",65).qw.lt("age",18);
lambda格式1:
    QueryWrapper<User> qw = new QueryWrapper<User>();
    qw.lambda().lt(User::getAge, 10);
    List<User> userList = userDao.selectList(qw);
    System.out.println(userList);
lambda格式2:
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    lqw.lt(User::getAge, 10);
    List<User> userList = userDao.selectList(lqw);
    System.out.println(userList);
Null值处理:
    //模拟页面传递过来的查询数据
    UserQuery uq = new UserQuery();
    uq.setAge(10);
    uq.setAge2(30);

    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    //先判定第一个参数是否为true,如果为true连接当前条件
    lqw.lt(null != uq.getAge2(),User::getAge, uq.getAge2());
    lqw.gt(null != uq.getAge(),User::getAge, uq.getAge());
    //链式编程
    lqw.lt(null != uq.getAge2(),User::getAge, uq.getAge2())
       .gt(null != uq.getAge(),User::getAge, uq.getAge());
    List<User> userList = userDao.selectList(lqw);
    System.out.println(userList);
查询投影:
//lambda格式:
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.select(User::getId,User::getName,User::getAge);

QueryWrapper<User> lqw = new QueryWrapper<User>();
lqw.select("id","name","age","tel");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
----------------------------------------------------------------------------
QueryWrapper<User> lqw = new QueryWrapper<User>();
lqw.select("count(*) as count, tel");
lqw.groupBy("tel");
List<Map<String, Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);
----------------------------------------------------------------------------

   LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
   //等同于=
   lqw.eq(User::getName,"Jerry").eq(User::getPassword,"jerry");
   User loginUser = userDao.selectOne(lqw);
   System.out.println(loginUser);

   LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
   //范围查询 lt(<) le(<=) gt(>) ge(>=) eq(=) between
   lqw.between(User::getAge,10,30);
   List<User> userList = userDao.selectList(lqw);
   System.out.println(userList);

   LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
   //模糊匹配 like
   /*
    likeLeft:%xx
    likeRight:xx%   
   */
   lqw.likeLeft(User::getName,"J");
   List<User> userList = userDao.selectList(lqw);
   System.out.println(userList);

字段映射与表命映射:

问题一、表字段与编码属性设计不同步

​ 名称:@TableField

​ 类型:属性注解

​ 位置:模型类属性定义上方

​ 作用:设置当前属性对应的数据库表中的字段关系

​ 范例:

    public class User{
        @TableField(value="pwd")
        private String password;
    }

​ 相关属性:

​ value(默认):设置数据库表字段名称

问题二:编码中添加了数据库未定义的属性
@TableField(exist = false)
private Integer online;

​ 相关属性:

​ exist:设置属性在数据库表字段中是否存在,默认为true。此属性无法与value合并使用

问题三:采用默认查询开放了更多的字段查看权限
@TableField(value="pwd",select = false)
private String password;
问题四:表名与编码开发设计不同步
@TableName("tbl_user")
public class User{
    private Long id;
}

主键生成策略控制:

雪花算法:
  • Snowflake Algorithm)是 Twitter 公司开发的一个全局唯一 ID 生成算法。它可以在分布式系统环境下,生成唯一、有序、时间戳型的 ID 号码。雪花算法的核心思想是将一个 64 位的二进制整数,划分成多个部分,每个部分用来表示不同的信息。具体来说,雪花算法将 64 位的整数划分为以下几个部分:

​ 1、首位固定为 0,表示这是一个正整数。

​ 2、接着的 41 位表示毫秒级时间戳,可以用来记录生成该 ID 的时间。

​ 3、然后是 10 位的机器标识号,可以用来区分不同的机器或者节点。

​ 4、最后是 12 位序号,可以用来表示在同一毫秒内生成的不同 ID。

​ 占位符0|时间戳(41)|机器码(5+5)|序列号(12)

  • 通过以上划分,雪花算法可以在分布式环境下确保生成的 ID 具有全局唯一性,并且由于采用时间戳和序号组合的方式,可以保证 ID 生成时的有序性,同时也避免了因使用分布式算法而引入的性能瓶颈。
  • 需要注意的是,雪花算法并不能完全解决全局唯一 ID 生成问题,例如,如果机器号不唯一或者机器时间不同步等情况,都会导致生成的 ID 不唯一。此外,由于雪花算法在高并发环境下产生 ID 的时候需要锁住序号位,因此可能会存在性能瓶颈问题,在实际使用中需要根据具体情况进行权衡。
不同的表应用不同的id生成策略:

​ 日志:自增(1,2,3,4,……)

​ 购物订单:特殊规则(FQ23948AK3843)

​ 外卖单:关联地区日期等信息(10 04 20200314 34 91)

​ 关系表:可省略id

​ ……

@TableId:

​ 类型:属性注解

​ 位置:模型类中用于表示主键的属性定义上方

​ 作用:设置当前类中主键属性的生成策略

​ 范例:

public class User{
    @TableId(type = IDType.AUTO)
    private Long id;
}

​ 相关属性:

​ vlaue:设置数据库主键名称

​ type:设置主键属性的生成策略,值参照IdType枚举值

id生成策略控制:
  1. ​ AUTO(0):使用数据库id自增策略控制id生成
  2. ​ NONE(1):不设置id生成策略
  3. ​ INPUT(2):用户手工输入id
  4. ​ ASSIGN_ID(3):雪花算法生成id(可兼容数值型与字符串型)
  5. ​ ASSIGN_UUID(4):以UUID生成算法作为id生成策略

    application.yml
    mybatis-plus:
    global-config:
    db-config:
    id-type: assign_id
    等同于:
    @TableId(type = IdType.ASSING_ID)

    mybatis-plus:
    global-config:
    db-config:
    table-prefix: tbl_
    相当于:
    @TableName(“tbl_score”)
    publie class Score{
    @TableId(type = IdType.AUTO)
    private Long id;
    }

多条数据操作(删除与查询):

void testDelete(){
    List<Long> list = new ArrayList<>();
    list.add(1L);
    list.add(2L);
    list.add(3L);
    //批量删除
    userDao.deleteBatchIds(list);

    //批量查询
    List<Long> list2 = new ArrayList<>();
    list.add(11L);
    list.add(12L);
    list.add(13L);
    //批量查询
    userDao.selectBatchIds(list);
}   
按照主键删除多条记录:
List<Long> ids = Arrays.asList(new Long[]{2,3});
userDao.deleteBatchIds(ids);
根据主键查询多条记录:
List<Long> ids = Arrays.asList(new Long[]{2,3});
List<User> userList = userDao.selectBatchIds(ids);

逻辑删除:

  1. 数据库表中添加逻辑删除标记字段(别忘记给默认值)
  2. 实体类中添加对应字段,并设定当前字段为逻辑删除标记字段

    public class User{
    private Long id;
    @TableLogic
    private Integer deleted;
    }

  3. 配置逻辑删除字段值

    mybatis-plus:
    globle-config:
    db-config:
    # 逻辑删除字段名
    logic-delete-field: deleted
    # 逻辑删除字面值:未删除为0
    logic-not-delete-value: 0
    # 逻辑删除字面值:删除为1
    logic-delete-value: 1

执行SQL语句:UPDATE tbl_user SET deleted=1 WHERE id=? AND deleted=0

删除操作业务问题:业务数据从数据库中丢弃

逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中

-------------------------------------------------
@TableLogic(value = "0",delval = "1")   
//value默认逻辑未删除值(该值可无、会自动获取全局配置),delval默认逻辑删除之(该值可无、会自动获取全局配置)
private Integer deleted;

配置逻辑删除之后,执行的SQL语句就会
由原来的:delete ……
变为update ……
-------------------------------------------------
application.yml

mybatis-plus:
……
    # 逻辑删除字段名
    logic-delete-field: deleted
    # 逻辑删除字面值:未删除为0
    logic-not-delete-value: 0
    # 逻辑删除字面值:删除为1
    logic-delete-value: 1
-------------------------------------------------

乐观锁:

业务并发现象带来的问题:秒杀

-------------------------------------------------
MpConfig.java
//添加乐观锁拦截器
mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
-------------------------------------------------
void testUpdate(){
    //1.先通过要修改的数据id将当前数据查询出来
    User user = userDao.selectById(3L);     //version=3

    User user2 = userDao.selectById(3L);    //version=3

    user2.setName("Jock aaa");
    userDao.updateById(user2);              //version=>4


    user.setName("Jock bbb");
    userDao.updateById(user);               //verion=3条件不成立了,修改失败
}

执行修改前先执行查询语句:
SELECT id,name,age,tel,deleted,version FROM tbl_user WHERE id=?
执行修改时使用vwesion字段作为乐观锁检查依据:
UPDATE tbl_user SET name=?,age=?,tel=?,vwesion=? WHERE id=? AND version=?

代码生成器:

模板:MyBatisPlus提供

数据库相关配置:读取数据库获取信息

开发者自定义配置:手工配置

------------------------------------------------
    <!--代码生成器-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.4.1</version>
    </dependency>

    <!--velocity模板引擎-->
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.3</version>
    </dependency>
------------------------------------------------
Generator.java
public class Generator {
    public static void main(String[] args) {
        AutoGenerator autoGenerator = new AutoGenerator();

        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        autoGenerator.setDataSource(dataSource);

        autoGenerator.execute();
    }
}
------------------------------------------------
CodeGenerator.java

//设置全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatisplus_04_generator/src/main/java");    //设置代码生成位置
globalConfig.setOpen(false);    //设置生成完毕后是否打开生成代码所在的目录
globalConfig.setAuthor("我是作者");    //设置作者
globalConfig.setFileOverride(true);     //默认为false,设置是否覆盖原始生成的文件
globalConfig.setMapperName("%sDao");    //设置数据层接口名,%s为占位符,指代模块名称,如果不配置这项,就生成默认的名称:XXXMapper
globalConfig.setIdType(IdType.ASSIGN_ID);   //设置Id生成策略
autoGenerator.setGlobalConfig(globalConfig);
------------------------------------------------
//设置包名相关配置
PackageConfig packageInfo = new PackageConfig();
packageInfo.setParent("com.aaa");   //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
packageInfo.setEntity("domain");    //设置实体类包名
packageInfo.setMapper("dao");   //设置数据层包名
autoGenerator.setPackageInfo(packageInfo);
------------------------------------------------
//策略设置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setInclude("tbl_user");  //设置当前参与生成的表名,参数为可变参数
strategyConfig.setTablePrefix("tbl_");  //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名  例如: User = tbl_user - tbl_
strategyConfig.setRestControllerStyle(true);    //设置是否启用Rest风格
strategyConfig.setVersionFieldName("version");  //设置乐观锁字段名
strategyConfig.setLogicDeleteFieldName("deleted");  //设置逻辑删除字段名
strategyConfig.setEntityLombokModel(true);  //设置是否启用lombok
autoGenerator.setStrategy(strategyConfig);
------------------------------------------------
创作不易!转载请注明作者及文章链接或作者博客链接——
- 作者:pidanxia
- 链接:https://pidanxia.ink
(链接可为:**文章链接**或者**作者博客链接**)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇