【持久化框架MyBatis3七】MyBatis3定义typeHandler

什么是typeHandler?

typeHandler用于将某个类型的数据映射到表的某一列上,以完成MyBatis列跟某个属性的映射

 

内置typeHandler

MyBatis内置了很多typeHandler,这写typeHandler通过org.apache.ibatis.type.TypeHandlerRegistry进行注册,比如对于日期型数据的typeHandler,

 

    register(java.sql.Date.class, new SqlDateTypeHandler());
    register(java.sql.Time.class, new SqlTimeTypeHandler());
    register(java.sql.Timestamp.class, new SqlTimestampTypeHandler());

 

 SqlDateTypeHandler的定义

 

/*
 *    Copyright 2009-2012 The MyBatis Team
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.type;

import java.sql.CallableStatement;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class SqlDateTypeHandler extends BaseTypeHandler<Date> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType)
      throws SQLException {
    ps.setDate(i, parameter); //将指定类型设置到PreparedStatement
  }

  @Override
  public Date getNullableResult(ResultSet rs, String columnName)
      throws SQLException {
    return rs.getDate(columnName);//返回结果
  }

  @Override
  public Date getNullableResult(ResultSet rs, int columnIndex)
      throws SQLException {
    return rs.getDate(columnIndex);
  }

  @Override
  public Date getNullableResult(CallableStatement cs, int columnIndex)
      throws SQLException {
    return cs.getDate(columnIndex);
  }
}

 

举例:

  

package com.mybatis3.domain;

import java.io.Serializable;

/**
 * @author Siva
 *
 */
public class PhoneNumber  implements Serializable
{
	private static final long serialVersionUID = 1L;
	
	private String countryCode;
	private String stateCode;
	private String number;
	
	public PhoneNumber() {
	}

	public PhoneNumber(String countryCode, String stateCode, String number) {
		super();
		this.countryCode = countryCode;
		this.stateCode = stateCode;
		this.number = number;
	}

	public PhoneNumber(String string) {
		if(string != null){
			String[] parts = string.split("-");
			if(parts.length>0) this.countryCode=parts[0];
			if(parts.length>1) this.stateCode=parts[1];
			if(parts.length>2) this.number=parts[2];
			
		}
	}
	
	@Override
	public String toString() {
		return this.getAsString();
	}

	public String getAsString() {
		return countryCode+"-"+stateCode+"-"+number;
	}
	
	public String getCountryCode() {
		return countryCode;
	}

	public void setCountryCode(String countryCode) {
		this.countryCode = countryCode;
	}

	public String getStateCode() {
		return stateCode;
	}

	public void setStateCode(String stateCode) {
		this.stateCode = stateCode;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}
	
}

 

 

package com.mybatis3.domain;

import java.io.Serializable;

/**
 * @author Siva
 *
 */
public class Student implements Serializable
{
	private static final long serialVersionUID = 1L;
	private Integer studId;
	private String name;
	private String email;
	private PhoneNumber phone;
	private Address address;
	
	@Override
	public String toString() {
		return "Student [studId=" + studId + ", name=" + name + ", email=" + email
				+ ", phone=" + (phone==null?null:phone.getAsString()) + ", address=" + address + "]";
	}
	public Student()
	{
	}
	public Student(Integer id)
	{
		this.studId = id;
	}
	public Integer getStudId()
	{
		return studId;
	}
	public void setStudId(Integer id)
	{
		this.studId = id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	public String getEmail()
	{
		return email;
	}
	public void setEmail(String email)
	{
		this.email = email;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	public PhoneNumber getPhone() {
		return phone;
	}
	public void setPhone(PhoneNumber phone) {
		this.phone = phone;
	}
	
}

 

Student的phone属性是PhoneNumber类型,而在数据表中,phone属性对应的字段是String类型,这就需要注册一个typeHandler,实现Student对象持久化到数据库表中时,将PhoneNumber对象转换为字符串,而在读取数据库时,将String类型的phone信息反序列化为PhoneNumber对象

 

PhoneNumberTypeHandler

 

package com.mybatis3.typehandlers;

import com.mybatis3.domain.PhoneNumber;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author Siva
 *
 */
public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber>{

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i,
			PhoneNumber parameter, JdbcType jdbcType) throws SQLException {
		ps.setString(i, parameter.getAsString());//将PhoneNumber序列化为字符串,持久化到数据库中
	}

	@Override
	public PhoneNumber getNullableResult(ResultSet rs, String columnName)
			throws SQLException {
		return new PhoneNumber(rs.getString(columnName)); //根据列名,从数据库中读取字符串,反序列化为PhoneNumber对象
	}

	@Override
	public PhoneNumber getNullableResult(ResultSet rs, int columnIndex)
			throws SQLException {
		return new PhoneNumber(rs.getString(columnIndex));
	}

	@Override
	public PhoneNumber getNullableResult(CallableStatement cs, int columnIndex)
			throws SQLException {
		return new PhoneNumber(cs.getString(columnIndex));///根据列的序号,从数据库中读取字符串,反序列化为PhoneNumber对象
	}

}

 

主配置文件

	<typeHandlers>
		<typeHandler handler="com.mybatis3.typehandlers.PhoneTypeHandler" />
	</typeHandlers>

 

SQL映射

    <insert id="insertStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="studId">
  		insert into STUDENTS(name,email,addr_id, phone)
  		values(#{name},#{email},#{address.addrId},#{phone})<!--#{phone}是字符串类型,根据typeHandler的转换规则,提供符合规则的phone字符串-->
    </insert>

 

测试代码

 

	public void testCreateStudentWithMap() 
	{
		Map<String, Object> studMap = new HashMap<String, Object>();
		long ts = System.currentTimeMillis();
		studMap.put("name","stud_"+ts);
		studMap.put("email","stud_"+ts+"@gmail.com");
		studMap.put("phone","123-456-789");
		studentService.createStudentWithMap(studMap);
	}

 

 

你可能感兴趣的:(TypeHandler)