概要
接上一篇MyBatis 学习笔记(一)MyBatis的简介与使用以及与其他ORM框架的比较,今天我们接着来学习MyBatis的一些常用特性,包括别名,类型处理器,动态SQL
如何使用MyBatis
在本小节,我将通过一个例子介绍MyBatis 中一些常用特性的运用,包括类型处理器,动态SQL等等。
别名
MyBatis 中有个比较好用的特性就是别名,这是为了减少在配置文件中配置实体类的全限定名的冗余。运用如下:
首先在MyBatis的配置文件中配置别名:
<!--别名处理-->
<typeAliases>
<typeAlias type="com.jay.chapter2.entity.Student" alias="Student"/>
</typeAliases>
然后,在需要使用该实体类的映射文件中进行添加即可。
<resultMap id="studentResult" type="Student">
//省略其他无关配置
</resultMap>
类型处理器的运用
在实际开发中,我们经常要对枚举类进行处理,例如,人的性别分为男,女,我们数据库中可能存的是0,1; 但是页面显示的话需要显示男,女,所以,我们在使用MyBatis时查询结果时就要通过转换器进行转换。
MyBatis 内置了很多类型处理器(typeHandlers),详细可以参考MyBatis官方文档,对枚举类的处理的是通过EnumOrdinalTypeHandler两个处理器来处理了,public enum SexEnum {
MAN,
FEMALE,
UNKNOWN;
}
对于复杂的枚举类型,则不能处理。例如:
MAN(“0”, “男”)
我们来查看源码分析下原因,我们以EnumTypeHandler为例来说明下。
public class EnumTypeHandler<E extends Enum> extends BaseTypeHandler {
private final Class type;
public EnumTypeHandler(Class type) {
if (type == null) {
throw new IllegalArgumentException(“Type argument cannot be null”);
}
this.type = type;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
if (jdbcType == null) {
ps.setString(i, parameter.name());
} else {
ps.setObject(i, parameter.name(), jdbcType.TYPE_CODE);
}
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
String s = rs.getString(columnName);
return s == null ? null : Enum.valueOf(type, s);
}
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String s = rs.getString(columnIndex);
return s == null ? null : Enum.valueOf(type, s);
}
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String s = cs.getString(columnIndex);
return s == null ? null : Enum.valueOf(type, s);
}
}
分析上述源码,setNonNullParameter方法包装PreparedStatement进行SQL插值操作,设置的值是enum.name() ,即enum的toString() ,存储的枚举值的名称,而getNullableResult 方法返回的是Enum.valueOf(type, s)。而EnumOrdinalTypeHandler转换器也只能处理Int,String 类型。故我们需要自定义转换器来处理。分析MyBatis 源码我们可以得知,各个转换器都是继承BaseTypeHandler 基类的。为了实现代码的通用性,首先我们实现了一个枚举基类,然后定义一个通用的转换器。
枚举基类:
public interface BaseEnum<E extends Enum<?>, T> {
/**
* 真正与数据库进行映射的值
* @return
*/
T getKey();
/**
* 显示的信息
* @return
*/
String getValue();
}
在枚举记录中我们定义了两个通用的获取key和value的方法,接着我们定义 一个枚举类SexEnum来实现枚举基类
public enum SexEnum implements BaseEnum<SexEnum, String> {
MAN(“0”, “男”),
WEMAN(“1”, “女”),;
private String key;
private String value;
。。。。。。。。。。。。。。。。。
版权原因,完整文章,请参考如下: