mybatis-plus学习--ActiveRecord实现原理探究

       在Mybatis-Plus中提供了ActiveRecord的模式,支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作,简单来说就是一个实体类继承Model类,并通过注解与数据库的表名进行关联,这样就可以通过实体类直接进行表的简单增删改查操作,这样也确实极大的方便了开发人员。

原理理解:

       简单来说Mybatis-plus是基于Mybatis的基础之上进行开发的,其基本操作还是一个Mapper操作中对应一条sql语句,通过参数和返回值来处理sql语句的执行结果。那样我们可以理解Mybatis-Plus的ActiveRecord其实就是Mybatis-Plus给我们提供一些简单的增删改查操作SQl语句的自动生成操作,可以参考上一篇博客mybtais-plus学习--BaseMapper提供的方法及SQL语句生成,在Mybatis提供的BaseMapper中默认提供了一些简单增删改查操作,其通过自动生成sql来初始化Mybatis的一些操作,其最终实现和我们直接基于Mybatis开发是一致的。

抽象类Model

public abstract class Model<T extends Model> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * <p>
     * 插入(字段选择插入)
     * </p>
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean insert() {
        try (SqlSession session = sqlSession()) {
            return SqlHelper.retBool(session.insert(sqlStatement(SqlMethod.INSERT_ONE), this));
        }
    }

    /**
     * <p>
     * 插入 OR 更新
     * </p>
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean insertOrUpdate() {
        if (StringUtils.checkValNull(pkVal())) {
            // insert
            return insert();
        } else {
            /*
             * 更新成功直接返回,失败执行插入逻辑
             */
            return updateById() || insert();
        }
    }

    /**
     * <p>
     * 根据 ID 删除
     * </p>
     *
     * @param id 主键ID
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Serializable id) {
        try (SqlSession session = sqlSession()) {
            return SqlHelper.delBool(session.delete(sqlStatement(SqlMethod.DELETE_BY_ID), id));
        }
    }

    /**
     * <p>
     * 根据主键删除
     * </p>
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById() {
        Assert.isFalse(StringUtils.checkValNull(pkVal()), "deleteById primaryKey is null.");
        return deleteById(pkVal());
    }

    /**
     * <p>
     * 删除记录
     * </p>
     *
     * @param wrapper
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Wrapper wrapper) {
        Map<String, Object> map = new HashMap<>(1);
        map.put(Constants.WRAPPER, wrapper);
        try (SqlSession session = sqlSession()) {
            return SqlHelper.delBool(session.delete(sqlStatement(SqlMethod.DELETE), map));
        }
    }

    /**
     * <p>
     * 更新(字段选择更新)
     * </p>
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById() {
        Assert.isFalse(StringUtils.checkValNull(pkVal()), "updateById primaryKey is null.");
        // updateById
        Map<String, Object> map = new HashMap<>(1);
        map.put(Constants.ENTITY, this);
        return SqlHelper.retBool(sqlSession().update(sqlStatement(SqlMethod.UPDATE_BY_ID), map));
    }

    /**
     * <p>
     * 执行 SQL 更新
     * </p>
     *
     * @param wrapper
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean update(Wrapper wrapper) {
        Map<String, Object> map = new HashMap<>(2);
        map.put(Constants.ENTITY, this);
        map.put(Constants.WRAPPER, wrapper);
        // update
        try (SqlSession session = sqlSession()) {
            return SqlHelper.retBool(session.update(sqlStatement(SqlMethod.UPDATE), map));
        }
    }

    /**
     * <p>
     * 查询所有
     * </p>
     *
     * @return
     */
    public List<T> selectAll() {
        try (SqlSession session = sqlSession()) {
            return session.selectList(sqlStatement(SqlMethod.SELECT_LIST));
        }
    }

    /**
     * <p>
     * 根据 ID 查询
     * </p>
     *
     * @param id 主键ID
     * @return
     */
    public T selectById(Serializable id) {
        try (SqlSession session = sqlSession()) {
            return session.selectOne(sqlStatement(SqlMethod.SELECT_BY_ID), id);
        }
    }

    /**
     * <p>
     * 根据主键查询
     * </p>
     *
     * @return
     */
    public T selectById() {
        Assert.isFalse(StringUtils.checkValNull(pkVal()), "selectById primaryKey is null.");
        return selectById(pkVal());
    }

    /**
     * <p>
     * 查询总记录数
     * </p>
     *
     * @param wrapper
     * @return
     */

    public List<T> selectList(Wrapper wrapper) {
        Map<String, Object> map = new HashMap<>(1);
        map.put(Constants.WRAPPER, wrapper);
        try (SqlSession session = sqlSession()) {
            return session.selectList(sqlStatement(SqlMethod.SELECT_LIST), map);
        }
    }

    /**
     * <p>
     * 查询一条记录
     * </p>
     *
     * @param wrapper
     * @return
     */
    public T selectOne(Wrapper wrapper) {
        return SqlHelper.getObject(selectList(wrapper));
    }

    /**
     * <p>
     * 翻页查询
     * </p>
     *
     * @param page    翻页查询条件
     * @param wrapper
     * @return
     */
    public IPage<T> selectPage(IPage<T> page, Wrapper<T> wrapper) {
        Map<String, Object> map = new HashMap<>(2);
        map.put(Constants.WRAPPER, SqlHelper.fillWrapper(page, wrapper));
        map.put("page", page);
        try (SqlSession session = sqlSession()) {
            page.setRecords(session.selectList(sqlStatement(SqlMethod.SELECT_PAGE), map));
        }
        return page;
    }

    /**
     * <p>
     * 查询总数
     * </p>
     *
     * @param wrapper
     * @return
     */
    public int selectCount(Wrapper wrapper) {
        Map<String, Object> map = new HashMap<>(1);
        map.put(Constants.WRAPPER, wrapper);
        try (SqlSession session = sqlSession()) {
            return SqlHelper.retCount(session.<Integer>selectOne(sqlStatement(SqlMethod.SELECT_COUNT), map));
        }
    }

    /**
     * <p>
     * 执行 SQL
     * </p>
     */
    public SqlRunner sql() {
        return new SqlRunner(getClass());
    }

    /**
     * <p>
     * 获取Session 默认自动提交
     * <p/>
     */
    protected SqlSession sqlSession() {
        return SqlHelper.sqlSession(getClass());
    }

    /**
     * 获取SqlStatement
     *
     * @param sqlMethod
     * @return
     */
    protected String sqlStatement(SqlMethod sqlMethod) {
        return sqlStatement(sqlMethod.getMethod());
    }

    /**
     * 获取SqlStatement
     *
     * @param sqlMethod
     * @return
     */
    protected String sqlStatement(String sqlMethod) {
        return SqlHelper.table(getClass()).getSqlStatement(sqlMethod);
    }

    /**
     * 主键值
     */
    protected abstract Serializable pkVal();
}

接下来我们分析一下insert操作到底是做了什么操作

1、调用sqlStatement生成对应的mapper关系

 @Transactional(rollbackFor = Exception.class)
    public boolean insert() {
        try (SqlSession session = sqlSession()) {
            return SqlHelper.retBool(session.insert(sqlStatement(SqlMethod.INSERT_ONE), this));
        }
    }

 2、根据sqlMethod、实体类和要执行的sqlMethod生成对应的insert语句,和BaseMapper的insert方法最终的实现是一致的。

 protected String sqlStatement(String sqlMethod) {
        return SqlHelper.table(getClass()).getSqlStatement(sqlMethod);
    }

其实BaseMapper和ActiveRecord这个两个方法是类似的,我们都是要创建一个类来继承抽象类或接口,通过方法名和实体找到对应的Mapper和sql来执行sql语句。

猜你喜欢

转载自blog.csdn.net/qq924862077/article/details/81836309