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 implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 

* 插入(字段选择插入) *

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

* 插入 OR 更新 *

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

* 根据 ID 删除 *

* * @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)); } } /** *

* 根据主键删除 *

* * @return */ @Transactional(rollbackFor = Exception.class) public boolean deleteById() { Assert.isFalse(StringUtils.checkValNull(pkVal()), "deleteById primaryKey is null."); return deleteById(pkVal()); } /** *

* 删除记录 *

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

* 更新(字段选择更新) *

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

* 执行 SQL 更新 *

* * @param wrapper * @return */ @Transactional(rollbackFor = Exception.class) public boolean update(Wrapper wrapper) { Map 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)); } } /** *

* 查询所有 *

* * @return */ public List selectAll() { try (SqlSession session = sqlSession()) { return session.selectList(sqlStatement(SqlMethod.SELECT_LIST)); } } /** *

* 根据 ID 查询 *

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

* 根据主键查询 *

* * @return */ public T selectById() { Assert.isFalse(StringUtils.checkValNull(pkVal()), "selectById primaryKey is null."); return selectById(pkVal()); } /** *

* 查询总记录数 *

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

* 查询一条记录 *

* * @param wrapper * @return */ public T selectOne(Wrapper wrapper) { return SqlHelper.getObject(selectList(wrapper)); } /** *

* 翻页查询 *

* * @param page 翻页查询条件 * @param wrapper * @return */ public IPage selectPage(IPage page, Wrapper wrapper) { Map 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; } /** *

* 查询总数 *

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

* 执行 SQL *

*/ public SqlRunner sql() { return new SqlRunner(getClass()); } /** *

* 获取Session 默认自动提交 *

*/ 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语句。

你可能感兴趣的:(myBatis入门及源码学习,Mybatis入门及源码学习)