typeHandler是类型转换器。如果你需要将一个枚举类型的数据存放到数据库,而数据库不支持枚举类型,所以需要将它保存为一个数值类型。那么,如何实现数据库类型和java枚举类型的相互转换呢?使用自定义的类型转换器即可。自定义的类型转换器需要实现typeHandler接口。
下面是一个枚举类型的定义:
public enum Role {
USER(0, "普通用户"), MANAGER(1, "管理员");
private int code;
private String text;
private Role(int code, String text) {
this.code = code;
this.text = text;
}
public int code() {
return code;
}
public String text() {
return text;
}
public static Role codeOf(int code) {
for (Role role : values()) {
if (role.code == code) {
return role;
}
}
throw new IllegalArgumentException("Invalid role code: " + code);
}
}
我们定义一个自定义的类型转换器,如下:
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
public class RoleTypeHandler implements TypeHandler<Role> {
@Override
public void setParameter(PreparedStatement ps, int i, Role parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.code());
}
@Override
public Role getResult(ResultSet rs, String columnName) throws SQLException {
return Role.codeOf(rs.getInt(columnName));
}
@Override
public Role getResult(ResultSet rs, int columnIndex) throws SQLException {
return Role.codeOf(rs.getInt(columnIndex));
}
@Override
public Role getResult(CallableStatement cs, int columnIndex) throws SQLException {
return Role.codeOf(cs.getInt(columnIndex));
}
}
接下来,需要注册自定义的类型转换器
<configuration>
<typeHandlers>
<typeHandler handler="com.mybatis.demo.RoleTypeHandler" javaType="com.mybatis.demo.Role" />
</typeHandlers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_test" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<!--省略 /-->
</mappers>
</configuration>
mapper文件如下:
<mapper namespace="account">
<select id="select"
parameterType="java.util.HashMap"
resultType="com.mybatis.demo.Account">
<![CDATA[
select
id,
name,
password,
role,
created,
last_login_time as lastLoginTime
from
account
]]>
<where>
<if test="name !=null and name != ''">
and name = #{name}
</if>
<if test="role != null">
and role=#{role}
</if>
<if test="id != null">
and id = #{id}
</if>
</where>
</select>
</mapper>
接下来编写测试类,就可以发现已经能实现java类型和数据库类型的自动换转了。测试类如下:
public class test {
public static void main(String[] args) throws IOException {
String config = "mybatis-config-standalone.xml";
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sessionFactory.openSession();
Map<String, Object> params = new LinkedHashMap<String, Object>();
params.put("name", "frank");
Account account = sqlSession.selectOne("account.select",params);
System.out.println(account);
}
}