typeHandlers type processor

To realize the conversion between java type and database type, you can use the type processor provided by the system, or you can customize the type processor. This paper introduces the implementation of the conversion between database type and java type by using the customized type processor.
For example: List - > varchar

1. Define a custom type processor

package org.zhouym.typehandlers;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class MyTypeHandler extends BaseTypeHandler<List<String>> {

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, List<String> list, JdbcType jdbcType)
			throws SQLException {
		//Handle placeholders
		StringBuilder sb = new StringBuilder();
		for (String hobby : list) {
			sb.append(hobby);
			sb.append(";");
		}
		String hobbys = sb.toString();
		//Set values for placeholders
		ps.setString(i, hobbys.substring(0, hobbys.length()-1));
	}

	@Override
	public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
		String hobby = rs.getString(columnName);
		if (hobby == null) {
			return null;
		}
		String[] split = hobby.split(";");		
		return Arrays.asList(split);
	}

	@Override
	public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		String hobby = rs.getString(columnIndex);
		if (hobby == null) {
			return null;
		}
		String[] split = hobby.split(";");		
		return Arrays.asList(split);
	}

	@Override
	public List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		return null;
	}

}

2. Processor information of configuration type in configuration file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- Profile for importing database information -->
	<properties resource="db.properties"></properties>
	<!-- Introduce type processor -->
	<typeHandlers>
		<typeHandler handler="org.zhouym.typehandlers.MyTypeHandler"></typeHandler>
	</typeHandlers>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<!-- Configure data source information -->
			<dataSource type="POOLED">
				<!-- Bring in content from configuration file -->
				<property name="driver" value="${driver}" />
				<property name="url" value="${url}" />
				<property name="username" value="${username}" />
				<property name="password" value="${password}" />
			</dataSource>
		</environment>
	</environments>
	<!-- Contact mapping file -->
	<mappers>
		<!-- Note here that the resource path is the address of the mapping file and cannot be separated by dots -->
		<mapper resource="org/zhouym/dao/IUserDao.xml" />
	</mappers>
</configuration>

Add collection properties

Mapping file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <!-- Using interfaces, namespace Must be the full path of the interface -->
<mapper namespace="org.zhouym.dao.IUserDao">
	<!-- Save the results of the database query to the object -->
  <select id="query" resultType="com.zhouym.javabean.User">
  		<!-- write sql Statement, no semicolon -->
		select * from tb_user
  </select>
  <select id="queryById" resultType="com.zhouym.javabean.User">
  		<!-- write sql Statement, no semicolon -->
		select * from tb_user where id=#{id}
  </select>
  <!-- Add data -->
  <insert id="addUser" parameterType="com.zhouym.javabean.User">
  	insert into tb_user(name,age,address,hobby) values(#{name},#{age},#{address},#{hobby})
  </insert>
  <!-- Modifying data -->
  <update id="updateUser" parameterType="com.zhouym.javabean.User">
  	update tb_user set name=#{name},age=#{age},address=#{address} where id=#{id}
  </update>
  <!-- Delete data -->
  <delete id="deleteById" parameterType="int">
  	delete from tb_user where id=#{id}
  </delete>
</mapper>


Test class

package com.zhouym.junit;

import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.zhouym.dao.IUserDao;
import org.zhouym.dbutils.DButils;

import com.zhouym.javabean.User;

public class JunitTestInterface {
	
	private static Logger logger = Logger.getLogger(JunitTestInterface.class);
	
	@Test
	public void test1() {
		SqlSessionFactory factory = DButils.getSqlSessionFactory();
		SqlSession sqlSession = factory.openSession();
		//The implementation of IUserDao obtained is actually a proxy class.
		IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);
		
		User user = new User();
		user.setName("Lao Hu");
		user.setAge(28);
		user.setAddress("Henan");
		
		List<String> list = new ArrayList<>();
		list.add("Basketball");
		list.add("Run");
		list.add("Swimming");
		user.setHobby(list);
		int result = iUserDao.addUser(user);
		if (result > 0) {
			logger.info("Add successfully!");
		}
		sqlSession.commit();
		
	}

}

test result

Query data

package com.zhouym.junit;

import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.zhouym.dao.IUserDao;
import org.zhouym.dbutils.DButils;

import com.zhouym.javabean.User;

public class JunitTestInterface {
	
	private static Logger logger = Logger.getLogger(JunitTestInterface.class);
	
	@Test
	public void test() {
		SqlSessionFactory factory = DButils.getSqlSessionFactory();
		SqlSession sqlSession = factory.openSession();
		//The implementation of IUserDao obtained is actually a proxy class.
		IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);
		//Calling methods in an interface
		List<User> list = iUserDao.query();
		for (User user : list) {
			logger.info(user);
		}
	}

}

test result