关于mybatis的类型处理器typeHandlers

 

  • 说在前面

 

 了解mybatis的朋友都知道,当mybatis将一个java对象作为输入参数执行SQL语句时,会先创建一个PreparedStatement对象,通过该对象的setXxx()方法,将SQL语句中占位符替换,如下XxxMapper.xml配置文件:

 


	insert into
	students(id,name,email,date)
	values(#{id},#{name},#{email},#{date})

 mybatis在执行该sql语句时的步骤为:

 

1. 创建能够代替占位符的PreparedStatement接口

 

PreparedStatement ps = conn.prepareStatement("insert into students(id,name,email,date) values(?,?,?,?)"); 

 

2. 使用PreparedStatement的setXxx()方法进行替换

 

ps.setInt(1,student.getId());
ps.setString(2,student.getName());
ps.setString(3,student.getEmail());
ps.setTimestamp(4,new Timestamp((student.getDate()).getTime()));

 

 

 这里就有一个疑问了,mybatis是如何知道什么时候应该使用setInt(),什么时候使用setString()的呢?就是通过类型处理器typeHandlers。

 

 我们知道PreparedStatement的setXXX()方法支持的数据类型有限,一般常用的数据类型,mybatis会使用内置的类型处理器来进行处理,而当我们遇到的数据类型超出了这个范围,应该怎么做呢?

 

  • 类型处理器

 

 typeHandlers一般分为内置的和自定义。内置的类型处理器,上文已经提到了。自定义的类型处理器,顾名思义就是自己定义类型处理器,接下来我会举一个栗子。

 

public class Student {
	private Integer id; 
	private String name; 
	private String email; 
	private PhoneNumber phone;
	get()/set()...
     }

 

 在该Student类中出现了一个新的java类对象PhoneNumber

 

 

public class PhoneNumber {
	private String countryCode; 
	private String stateCode; 
	private String number;
	public PhoneNumber() {
	}
	public PhoneNumber(String countryCode, String stateCode, String number) {
		this.countryCode = countryCode;
		this.stateCode = stateCode;
		this.number = number;
	}
	public String getAsString(){ return countryCode + "-" + stateCode + "-" + number;}
     }

 xml配置如下:

 

 

 
	insert into students(name,email,phone) 
	values(#{name},#{email},#{phone}) 
    

 在这里我们需要将值传给#{phone},而该占位符类型为PhoneNumber,内置的类型处理器处理不了这种类型,我们需要自定义类型处理器。mybatis提供了抽象类BaseTypeHandler,我们只需要继承该类创建自定义类型处理器即可。

 

 

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import com.briup.pojo.PhoneNumber;

public class PhoneTypeHandler extends BaseTypeHandler {
	//使用列名进行封装
	@Override
	public PhoneNumber getNullableResult(ResultSet rs, String columnName)
			throws SQLException {
		return new PhoneNumber(rs.getString(columnName));
	}
	//使用列的下标进行封装
	@Override
	public PhoneNumber getNullableResult(ResultSet rs, int i)
			throws SQLException {
		return new PhoneNumber(rs.getString(i));
	}
	//CallableStatement遇到PhoneNumber,如何设置参数
	@Override
	public PhoneNumber getNullableResult(CallableStatement cs, int i)
			throws SQLException {
		return null;
	}
	//PreparedStatement遇到PhoneNumber,如何设置参数
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i,
			PhoneNumber phoneNumber, JdbcType type) throws SQLException {
		ps.setString(i, phoneNumber.getAsString());
	}
}

 我们还需要修改配置文件mybatis-config.xml文件来注册该类型处理器,在根标签下加入以下内容:

 

 


		
     

 此时的类型处理器主要内容就是这么多。

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(边学边写-框架之mybatis)