Mybaits-plus實戰(三)


1. Mybaits-plus實戰(三)

1.1. 特殊使用規則

1.1.1. Model邏輯刪除

  1. 數據庫對應實體類,繼承Model類可以實現AR模式的sql語句操作,但這里需要注意的是,對邏輯刪除,官方說明需要實現如下重寫方法才能生效,也就是使用實例化對象.deleteById()
    @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有四種選擇,如下,它默認是不做處理的,所以一定要填個
public enum FieldFill {
    /**
     * 默認不處理
     */
    DEFAULT,
    /**
     * 插入填充字段
     */
    INSERT,
    /**
     * 更新填充字段
     */
    UPDATE,
    /**
     * 插入和更新填充字段
     */
    INSERT_UPDATE
}
  1. 效果如下

1.1.3. 級聯操作

  1. 對自定義語句條件用wrapper包裝,實現多表聯合查詢也可以用鏈式的條件查詢
  2. 例子基本都在下面了
//可直接在這里定義方法列表,默認只有在類上加注解才會支持方法
@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);


}
     <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. 增刪改查技巧

  • 前提
    @Resource
    private UserMapper mapper;
mapper.insert(
                new User().setId(10086L)
                        .setName("miemie")
                        .setEmail("miemie@baomidou.com")
                        .setAge(3));
mapper.delete(new QueryWrapper<User>()
                .lambda().eq(User::getName, "Sandy"))
mapper.update(
                new User().setEmail("miemie@baomidou.com"),
                new QueryWrapper<User>()
                        .lambda().eq(User::getId, 2)
        );
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要查詢這個字段還是可以查的
    /**
     * 添加transient會導致邏輯刪除模式失效
     */
    @ApiModelProperty(value = "是否刪除:0-正常 1-軟刪除")
    @TableLogic
    @TableField(select = false)
    private Integer delFlag;

1.1.6. 子查詢和嵌套查詢

	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語句
----- 帶子查詢(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的總結工作到現在結束了,知識點應該已經概括了官方文檔的所有,有啥意見建議請下面提_


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM