mybatis

作者: Wu杰语 | 来源:发表于2021-03-01 17:07 被阅读0次

mybatis是一款基于jdbc的数据库访问框架。

jdbc vs hibernate vs jdbi vs Spring jdbcTemplate

  • 最基本的都是直接使用jdbc,方便定位问题和调优,
  • 然后就是使用一些框架,都是ORM框架,Spring默认的ORM框架是Hibernate,但是Hibernate是完全黑盒的,所以现在新系统开发一般都不使用hibernate。
  • jdbi、Spring jdbcTemplate,这两款框架都是半自动框架,可以手写语句,简单易用,其中jdbi生命力旺盛,不断的迭代更新。
  • MyBatis是现在互联网最流行的框架或者说事实框架,俗称SSM的M就是Mybatis。因为流行,会的人多,所以才成为事实框架,必须掌握。

ORM框架都可以自己编写sql语句,并且提供了调优的辅助基础设施,带来方便的时候同时也带来复杂性。所以要根据情况选择,如果从表不多,效率要求比较高,用jdbc也是比较好的选择。

Mybatis框架流程原理

image.png

MyBatis基本原理就是在处理SQL语句映射和结果集映射,如上图,处理配置文件读写,然后是参数处理,这一块就完成了SQL语句的映射;在SQL语句执行完以后,需要完成结果集的映射,结果集的映射就把jdbc的查询结果转化为对象。

配置文件读取

mybatis主要涉及两个配置文件,具体可以参考官网,下面重点看一看mapper的sql语句映射,首先是mapper定义,必须有个java类,和配置文件的sql语句对应。

@Mapper
public interface MBMeMapper {
    List<Me> getAllMes();
}
<mapper namespace="com.demo1.dao.MBMeMapper">

    <!-- 可根据自己的需求,是否要使用 -->
    <resultMap type="Me" id="MeMap">
        <result column="oid" property="oid" jdbcType="INTEGER" />
        <result column="name" property="name" jdbcType="VARCHAR" />
        <result column="moc" property="moc" jdbcType="VARCHAR" />
        <result column="connectionState" property="connectionState" typeHandler="MeTypeHandler" jdbcType="INTEGER" />
    </resultMap>

    <select id="getAllMes" resultMap="MeMap">
        Select * From bnmain.me
    </select>

有几个关键对应点,一是namespace,namespace代表接口类的类名,然后是id,id是函数名,最后就是结果映射,结果映射填写resultMap标签的id。

搞明白如上几个对应关系就知道如何对应了。

Sql语句中还有动态Sql,可以参见mybatis手册,在mapper中配置动态条件。

结果映射

结果映射如上resultMap的定义,主要是对象和sql语句的返回值的对应

@Data
@Setter
@Getter
public class Me {
    private String oid;
    private String name;
    private String moc;
    private EnumState connectionState;
}

java对象和sql直接配置了映射关系,数据类型映射过程是mybatis内置代码自动映射的,如果需要映射为自定义类型就要使用到typeHandler定义,代码如下:

public enum EnumState {
    NA(-1),
    Connect(1),  // 连接
    NotConnect(0);   // 未连接


    private final int type;

    EnumState(int type) {
        this.type = type;
    }

    int getType() {
        return type;
    }

    public static EnumState int2Enum(int sexType) {
        EnumState[] types = EnumState.values();
        for (EnumState type : types) {
            if (type.getType() == sexType) {
                return type;
            }
        }
        return EnumState.NA;
    }
}

public class MeTypeHandler extends BaseTypeHandler<EnumState> {

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, EnumState enumState, JdbcType jdbcType) throws SQLException {
        preparedStatement.setInt(i, enumState.getType());
    }

    @Override
    public EnumState getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return EnumState.int2Enum(resultSet.getInt(s));
    }

    @Override
    public EnumState getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return EnumState.int2Enum(resultSet.getInt(i));
    }

    @Override
    public EnumState getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return EnumState.int2Enum(callableStatement.getInt(i));
    }
}

mybatis的结果映射组件读取到typhandler,就会调用这个handler来解析字段。

缓存

mybatis的缓存分为一级缓存和二级缓存,一级缓存是按照session的,二级缓存是按照namespace,namespace即上述mapper文件配置的namespace。

这里要思考几个问题,缓存主要是针对性能这个出发点考虑,缓存就是以空间换时间,但是由于受物理约束,空间和时间是相互制约的关系,所以空间必定有一定的考虑:

  • 空间的大小受限制,对于这个问题可以见配置文件的对于cache的默认配置就恍然大悟了,lru算,限制大小。
  • 缓存的有效性,缓存是如何更新的,在增删改时会刷新缓存。

小结

Mybatis的基本原理还是很比较简单的,但是面对复杂的工程场景,需要了解其中的扩展能力,如批量、插件等,这些都是需要逐渐积累的。

相关文章

网友评论

      本文标题:mybatis

      本文链接:https://www.haomeiwen.com/subject/fzphfltx.html