前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybaits-plus实战(三)

Mybaits-plus实战(三)

作者头像
老梁
发布2019-09-10 18:38:09
8250
发布2019-09-10 18:38:09
举报

1. Mybaits-plus实战(三)

1.1. 特殊使用规则

1.1.1. Model逻辑删除

  1. 数据库对应实体类,继承Model类可以实现AR模式的sql语句操作,但这里需要注意的是,对逻辑删除,官方说明需要实现如下重写方法才能生效,也就是使用实例化对象.deleteById()
代码语言:javascript
复制
    @Override
    protected Serializable pkVal() {
        /**
         * AR 模式这个必须有,否则 xxById 的方法都将失效!
         * 另外 UserMapper 也必须 AR 依赖该层注入,有可无 XML
         */
        return id;
    }
  1. 事实上,在主键字段添加@TableId(value = "id", type = IdType.AUTO)该注解,效果等同上面
  2. 还要注意的,对逻辑删除字段不要加transient修饰词,否则逻辑删除也会不生效

1.1.2. MetaObjectHandler统一数据库操作数据处理

  1. 你可以在操作数据库前打印日志,也可以对即将输入的数据做修改
  2. 重要的是,如果你只是实现了这个接口实现类,并注入了Spring,对你修改的字段,返回前端的数据是会有修改的内容,但是插入或更新数据库是不存在的;这里你需要做的是在要进行插入或修改的字段上面加上注解@TableField(fill = FieldFill.INSERT),这里FieldFill有四种选择,如下,它默认是不做处理的,所以一定要填个
代码语言:javascript
复制
public enum FieldFill {
    /**
     * 默认不处理
     */
    DEFAULT,
    /**
     * 插入填充字段
     */
    INSERT,
    /**
     * 更新填充字段
     */
    UPDATE,
    /**
     * 插入和更新填充字段
     */
    INSERT_UPDATE
}
  1. 效果如下

1.1.3. 级联操作

  1. 对自定义语句条件用wrapper包装,实现多表联合查询也可以用链式的条件查询
  2. 例子基本都在下面了
代码语言:javascript
复制
//可直接在这里定义方法列表,默认只有在类上加注解才会支持方法
@QuerySupport("selectPageByCustomWithXml")
public interface UserMapper extends BaseMapper<User> {

    String JOIN_SQL = "SELECT user.*, role.name as role_name, role.create_time as role_create_time FROM user as user LEFT JOIN role as role ON user.role_id = role.id";

    @QuerySupport
    @Select("SELECT user.*, role.name as role_name, role.create_time as role_create_time FROM user as user LEFT JOIN role as role ON user.role_id = role.id")
    List<UserRoleVO> findUserWithRoleByVoWithQueryList(@Param(Constants.WRAPPER) QueryWrapper<UserRoleVO> wrapper);

    @QuerySupport
    @Select(JOIN_SQL)
    List<User> selectListByCustom(@Param(Constants.WRAPPER) Wrapper<User> wrapper);

    /**
     * 使用mybatis-plus自定义分页查询,使用resultMap将结果解析到关联对象中
     *
     * @param page 必须为第一个参数
     * @param wrapper
     * @return
     */
    //类型优先级 (若未存在注解,当类型与mapper泛型不一致时使用其本身) @ResultType > @ResultMap > @Table(在类型一致时应用存在的resultMap)
    @ResultMap("userCascadeResult")
    @QuerySupport
    @Select({"<script>", JOIN_SQL, "</script>"})
    Page<User> selectPageByCustom(Page<User> page, @Param(Constants.WRAPPER) Wrapper<User> wrapper);

    @QuerySupport
    Page<User> selectPageByCustomWithXml(Page<User> page, @Param(Constants.WRAPPER) Wrapper<User> wrapper);

    @QuerySupport
    @Select({JOIN_SQL, "WHERE user.id = #{id}"})
    User selectCascadeById(Serializable id);


    @ResultMap("userCascadeResult")
    @Select({JOIN_SQL, "WHERE user.id = #{id}"})
    User selectCascadeById2(Serializable id);

    @QuerySupport
    @Select({"${text}"})
    List<User> selectByText(@Param("text") String text, @Param(Constants.WRAPPER) Wrapper<User> wrapper);


       /**
     * Wrapper支持select指定列的方式
     * @param wrapper
     * @return
     */
    @QuerySupport
    @Select("SELECT %s FROM user as user LEFT JOIN role as role ON user.role_id = role.id")
    List<UserRoleVO> findUserWithRoleByVoWithQueryListAndColumns(@Param(Constants.WRAPPER) Wrapper<UserRoleVO> wrapper);

    @ResultMap("userNotCascadeResult")
    @QuerySupport
    @Select("SELECT %s FROM user")
    Page<User> selectPageByCustomWithAssociationAndColumns(Page<User> page, @Param(Constants.WRAPPER) Wrapper<User> wrapper);


}
代码语言:javascript
复制
     <select id="selectPageByCustomWithXml" resultMap="userCascadeResult">
      SELECT user.*,
      role.name as role_name,
      role.create_time as role_create_time
      FROM user as user
      LEFT JOIN role as role
      ON user.role_id = role.id
    </select>

1.1.4. 增删改查技巧

  • 前提
代码语言:javascript
复制
    @Resource
    private UserMapper mapper;
代码语言:javascript
复制
mapper.insert(
                new User().setId(10086L)
                        .setName("miemie")
                        .setEmail("miemie@baomidou.com")
                        .setAge(3));
代码语言:javascript
复制
mapper.delete(new QueryWrapper<User>()
                .lambda().eq(User::getName, "Sandy"))
代码语言:javascript
复制
mapper.update(
                new User().setEmail("miemie@baomidou.com"),
                new QueryWrapper<User>()
                        .lambda().eq(User::getId, 2)
        );
代码语言:javascript
复制
User user = mapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, 10086));

List<User> users = mapper.selectList(Wrappers.<User>query().orderByAsc("age"));

1.1.5. 查询去字段技巧

  1. 之前说过一个,通过加transient,利用jackson或fastjson,在返回前端的时候对它做处理去掉对应的字段,但同时我们又遇到个问题,比如del_flag,该字段往往前端不需要,但又不能加transient,原因上面也说了会导致逻辑删除功能失效,这时,还有个办法解决
  2. 在实体字段上加上注解@TableField(select = false),表示在进行sql查询时,去掉该字段的查询,这是在sql层面去掉该字段的查询,当然,如果你明确sql要查询这个字段还是可以查的
代码语言:javascript
复制
    /**
     * 添加transient会导致逻辑删除模式失效
     */
    @ApiModelProperty(value = "是否删除:0-正常 1-软删除")
    @TableLogic
    @TableField(select = false)
    private Integer delFlag;

1.1.6. 子查询和嵌套查询

代码语言:javascript
复制
    System.out.println("----- 带子查询(sql注入) ------");
    List<User> plainUsers2 = userMapper.selectList(new QueryWrapper<User>()
            .inSql("role_id", "select id from role where id = 2"));
    List<User> lambdaUsers2 = userMapper.selectList(new QueryWrapper<User>().lambda()
            .inSql(User::getRoleId, "select id from role where id = 2"));
    Assert.assertEquals(plainUsers2.size(), lambdaUsers2.size());
    print(plainUsers2);

    System.out.println("----- 带嵌套查询 ------");
    List<User> plainUsers3 = userMapper.selectList(new QueryWrapper<User>()
            .nested(i -> i.eq("role_id", 2L).or().eq("role_id", 3L))
            .and(i -> i.ge("age", 20)));
    List<User> lambdaUsers3 = userMapper.selectList(new QueryWrapper<User>().lambda()
            .nested(i -> i.eq(User::getRoleId, 2L).or().eq(User::getRoleId, 3L))
            .and(i -> i.ge(User::getAge, 20)));
    Assert.assertEquals(plainUsers3.size(), lambdaUsers3.size());
    print(plainUsers3);
  • 查询结果的sql语句
代码语言:javascript
复制
----- 带子查询(sql注入) ------
SELECT id,name,age,email,role_id FROM user WHERE role_id IN (select id from role where id = 2) 

----- 带嵌套查询 ------
SELECT id,name,age,email,role_id FROM user WHERE ( role_id = ? OR role_id = ? ) AND ( age >= ? ) 

1.2. 其它功能点(基本都是插件)

  1. 性能分析(sql执行时间)
  2. 乐观锁
  3. 分页
  4. 主键生成器
  5. 自定义sql
  6. 多租户

1.3. 总结

  • 其它功能点不是前面已经写过例子的,就是很少使用
  • 到现在我已经把mybatis-plus的所有官方文档和sample代码例子都看了一遍,也做了一些总结和特别标注,毕竟很多功能可能暂时用不到不代表以后用不到,在总结此篇的时候也让我对此前的博客有些技术上的修正,比如MetaObjectHandler的使用,并不是只能把值放返回对象,它是可以直接插入数据库的
  • mybatis-plus的总结工作到现在结束了,知识点应该已经概括了官方文档的所有,有啥意见建议请下面提^_^
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Mybaits-plus实战(三)
    • 1.1. 特殊使用规则
      • 1.1.1. Model逻辑删除
      • 1.1.2. MetaObjectHandler统一数据库操作数据处理
      • 1.1.3. 级联操作
      • 1.1.4. 增删改查技巧
      • 1.1.5. 查询去字段技巧
      • 1.1.6. 子查询和嵌套查询
    • 1.2. 其它功能点(基本都是插件)
      • 1.3. 总结
      相关产品与服务
      数据库
      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档