TypeAliases
别名 类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
有2中方式
<typeAliases> <typeAlias type="java.time.LocalDateTime"alias="localDateTime"/> </typeAliases>
指定了一个名称缩写就可以在mapper.xml中使用
```xml
<resultMap id="BaseResultMap" type="user">
<result column="create_time" property="createTime" javaType="localDateTime"/>
</resultMap>
```
```xml
<typeAliases>
<package name="com.mybatis.demo.mybatis.domain"/>
</typeAliases>
```
package包下的所有的java类都会使用 类 的首字母小写的非限定类名来作为它的别名。比如说:com.mybatis.demo.mybatis.domain.User 就可以用user代表
<resultMap id="BaseResultMap" type="user"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="user_name" property="userName" jdbcType="VARCHAR" typeHandler="com.mybatis.demo.mybatis.typeHandler.MyTypeHandler"/> <result column="age" property="age" jdbcType="INTEGER"/> <result column="create_time" property="createTime" javaType="localDateTime"/> </resultMap>
TypeHandler
类型转换器。数据库类型与java类型并不是一一对应的。TypeHandler就是用来实现数据库类型与java数据类型相对应的功能。通过集成BaseHandler<Object>可以插入与查询数据库数据与返回java类型结果相对应。比如数据类型是string 转换成 java类型 List.class。
xml 配置使用
public class ListTypeHandler extends BaseTypeHandler<List<String>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, String.join(",", parameter));
}
@Override
public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String resultString = rs.getString(columnName);
if ("".equals(resultString)) {
return null;
}
return Arrays.asList(resultString.split(","));
}
}
Mybatis-config.xml
<typeHandlers>
<typeHandler handler="com.mybatis.demo.mybatis.typeHandler.ListTypeHandler" />
</typeHandlers>
Mapper.xml
<resultMap id="BaseResultMap" type="user">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="user_name" property="userName" jdbcType="VARCHAR" typeHandler="com.mybatis.demo.mybatis.typeHandler.MyTypeHandler"/>
<result column="age" property="age" jdbcType="INTEGER"/>
<result column="create_time" property="createTime" javaType="localDateTime"/>
<result column="json_list" property="jsonList" typeHandler="com.mybatis.demo.mybatis.typeHandler.ListTypeHandler"/>
</resultMap>
<select id="selectById" resultMap="BaseResultMap" parameterType="int">
select * from user where id = #{id}
</select>
<insert id="insert" parameterType="user">
insert into user (id,user_name,age,json_list) values
(
#{id},
#{userName},
#{age},
#{jsonList}
)
</insert>
注意:
如果有多个类型转换器在插入的时候需要在 insert语句上标明使用哪个转换器 比如下面的使用了**EnumOrdinalTypeHandler ** 枚举整形转换器. 如果是查询语句需要在<ResultMap> 标签中的<result> 标签中来指定转化器.
新增在insert 查询在result
<insert id="insert" parameterType="user">
insert into user (id,user_name,age,json_list,sex_state,sex_state_origin) values
(
#{id},
#{userName},
#{age},
#{jsonList},
#{sexState},
#{sexStateOrigin,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler}
);
</insert>
<resultMap id="BaseResultMap" type="user">
<result column="json_list" property="jsonList" typeHandler="com.mybatis.demo.mybatis.typeHandler.ListTypeHandler"/>
</resultMap>
EnumTypeHandler 与EnumOrdinalTypeHandler的区别
这2个处理器的本质都是把Enum对象映射到数据库中 查询数据库到Enum对象,不同的区别是一个是插入的字符串 一个插入的数字。如果不指定typeHandler则默认使用EnumTypeHandler 比如这样子:
EnumTypeHandler
@Data
public class User {
private SexEnum sexState;
}
public enum SexEnum {
MAN(1, "男"), WOMAN(2, "女"), TEST(1, "1");
private Integer id;
private String name;
SexEnum(int id, String name) {
this.id = id;
this.name = name;
}
... getDate
}
<insert id="insert" parameterType="user">
insert into user (sex_state) values
(
#{sexState}
);
</insert>
执行insert语句就会把字符串 MAN WOMAN 1 插入到数据库中
EnumOrdinalTypeHandler
@Data
public class User {
private SexEnumOrigin sexStateOrigin;
}
public enum SexEnumOrigin {
MAN(1,"男"), WOMAN(2, "女"),;
private int id;
private String name;
SexEnumOrigin(Integer id, String name) {
this.id = id;
this.name = name;
}
... getDate
}
<insert id="insert" parameterType="user">
insert into user (sex_state_origin) values
(
#{sexStateOrigin,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler}
);
</insert>
执行insert方法此时插入到数据库中的是0 1数字。 0 1 对应的是枚举对象的下标。
原理 EnumOrdinalTypeHandler源码
public class EnumOrdinalTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
//数组
private final E[] enums;
public EnumOrdinalTypeHandler(Class<E> type) {
this.enums = type.getEnumConstants();
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
//parameter.ordinal() 获取枚举的下标
ps.setInt(i, parameter.ordinal());
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
int ordinal = rs.getInt(columnName);
return enums[ordinal];
}
}
源码 EnumTypeHandler
@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); // see r3589
}
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
String s = rs.getString(columnName);
return s == null ? null : Enum.valueOf(type, s);
}
注解方式使用
实体类注释
//解析paramValue之后的列
@ColumnType(typeHandler = TemplateContentTypeHandler.class, column = "param_value", jdbcType = JdbcType.VARCHAR)
private List<String> paramValueList;
//解析paramValue之后的列 插入的时候如果此字段 与 paramPlaceholder字段同时赋值则报错
@ColumnType(typeHandler = TemplateParamPlaceholderTypeHandler.class, column = "param_placeholder", jdbcType = JdbcType.VARCHAR)
private List<String> paramPlaceholderList;
public class TemplateContentTypeHandler extends BaseTypeHandler<List> {
//当插入的时候 值为null不会执行次方法
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, StringUtils.join(parameter, "#"));
}
@Override
public List getNullableResult(ResultSet rs, String columnName) throws SQLException {
String stringResult = rs.getString(columnName);
if (!StringUtils.isEmpty(stringResult)) {
return Arrays.asList(stringResult.split("#"));
}
return null;
}
ObjectFactory
ObjectFactory 是用创建对象的工厂,用来创建查询结果对应的实体类。没有任何实际的作用。
<!-- mybatis-config.xml -->
<objectFactory type="org.mybatis.example.ExampleObjectFactory">
<property name="someProperty" value="100"/>
</objectFactory>
// ExampleObjectFactory.java
public class ExampleObjectFactory extends DefaultObjectFactory {
public Object create(Class type) {
return super.create(type);
}
public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs) {
return super.create(type, constructorArgTypes, constructorArgs);
}
public void setProperties(Properties properties) {
super.setProperties(properties);
}
public <T> boolean isCollection(Class<T> type) {
return Collection.class.isAssignableFrom(type);
}}
Mappers 映射器
我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括
file:///形式的 URL),或类名和包名(最常用)等
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>












网友评论