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框架流程原理

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的基本原理还是很比较简单的,但是面对复杂的工程场景,需要了解其中的扩展能力,如批量、插件等,这些都是需要逐渐积累的。
网友评论