Mapper系列六:类型处理器TypeHandler

简单类型和复杂类型
在这里插入图片描述
通用 Mapper 默认情况下会忽略复杂类型,对复杂类型不进行“从类到表”的映射。
1、创建table_user表和数据

	CREATE TABLE `table_user` (
		`user_id` INT NOT NULL AUTO_INCREMENT,
		`user_name` VARCHAR (100) NULL,
		`address` VARCHAR (100) NULL,
		`season` VARCHAR (100) NULL,
		PRIMARY KEY (`user_id`)
	);

在这里插入图片描述
2、自定义类型转换器
在这里插入图片描述
在这里插入图片描述

public class AddressTypeHandler extends BaseTypeHandler<Address> {

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, Address address, JdbcType jdbcType)
			throws SQLException {
		//1.对address对象进行验证
		if(address == null) {
			return ;
		}
		//2.从address对象中取出具体数据
		String province = address.getProvince();
		String city = address.getCity();
		String street = address.getStreet();
		//3.拼装成一个字符串
		//规则:各个值之间使用“,”分开
		StringBuilder builder = new StringBuilder();
		builder
			.append(province)
			.append(",")
			.append(city)
			.append(",")
			.append(street);
		String parameterValue = builder.toString();
		//4.设置参数
		ps.setString(i, parameterValue);
	}

	@Override
	public Address getNullableResult(ResultSet rs, String columnName) throws SQLException {
		//1.根据字段名从rs对象中获取字段值
		String columnValue = rs.getString(columnName);
		//2.验证columnValue是否有效
		if(columnValue == null || columnValue.length() == 0 || !columnValue.contains(",")) {
			return null;
		}
		//3.根据“,”对columnValue进行拆分
		String[] split = columnValue.split(",");
		//4.从拆分结果数组中获取Address需要的具体数据
		String province = split[0];
		String city = split[1];
		String street = split[2];
		//5.根据具体对象组装一个Address对象
		Address address = new Address(province, city, street);
		return address;
	}

	@Override
	public Address getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		//1.根据字段名从rs对象中获取字段值
		String columnValue = rs.getString(columnIndex);
		//2.验证columnValue是否有效
		if(columnValue == null || columnValue.length() == 0 || !columnValue.contains(",")) {
			return null;
		}
		//3.根据“,”对columnValue进行拆分
		String[] split = columnValue.split(",");
		//4.从拆分结果数组中获取Address需要的具体数据
		String province = split[0];
		String city = split[1];
		String street = split[2];
		//5.根据具体对象组装一个Address对象
		Address address = new Address(province, city, street);
		return address;
	}

	@Override
	public Address getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		//1.根据字段名从rs对象中获取字段值
		String columnValue = cs.getString(columnIndex);
		//2.验证columnValue是否有效
		if(columnValue == null || columnValue.length() == 0 || !columnValue.contains(",")) {
			return null;
		}
		//3.根据“,”对columnValue进行拆分
		String[] split = columnValue.split(",");
		//4.从拆分结果数组中获取Address需要的具体数据
		String province = split[0];
		String city = split[1];
		String street = split[2];
		//5.根据具体对象组装一个Address对象
		Address address = new Address(province, city, street);
		return address;
	}
}

3、注册自定义类型转换器
 方式1:字段级别:@ColumnType 注解
在这里插入图片描述
 方式2:全局级别:在 MyBatis 配置文件中配置 typeHandlers

<typeHandlers>
	<!-- handler属性:指定自定义类型转换器全类名 -->
	<!-- javaType属性:指定需要使用“自定义类型转换器”进行类型处理的实体类型 -->
	<typeHandler 
		handler="com.atguigu.mapper.handlers.AddressTypeHandler"
		javaType="com.atguigu.mapper.entities.Address"/>
		
</typeHandlers>

4、枚举类型处理
 方式1:让通用 Mapper 把枚举类型作为简单类型处理 。Spring 配置文件中添加通用 Mapper 的配置项 enumAsSimpleType=true。本质上使用了 org.apache.ibatis.type.EnumTypeHandler<E>

<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
	<property name="basePackage" value="com.atguigu.mapper.mappers"/>
	<property name="properties">
		<value>
			enumAsSimpleType=true
		</value>
	</property>
</bean>

 方式2::为枚举类型配置对应的类型处理器
在这里插入图片描述
5、枚举类型处理器 :
内置:
 org.apache.ibatis.type.EnumTypeHandler
   在数据库中存储枚举值本身
 org.apache.ibatis.type.EnumOrdinalTypeHandler
   在数据库中仅仅存储枚举值的索引
自定义:和AddressTypeHandler操作一样
6、内置枚举类型处理器注册
 内置类型处理器不能使用@ColumnType 注解
在这里插入图片描述
 在 MyBatis 配置文件中配置 typeHandlers

<typeHandlers>
	<!-- handler属性:指定自定义类型转换器全类名 -->
	<!-- javaType属性:指定需要使用“自定义类型转换器”进行类型处理的实体类型 -->	
	<typeHandler 
		handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
		javaType="com.atguigu.mapper.entities.SeasonEnum"/>
		
</typeHandlers>

测试:

public class TypeHandlerTest {
	
	private UserService userService;
	
	{
		userService = new ClassPathXmlApplicationContext("spring-context.xml").getBean(UserService.class);
	}
	
	@Test
	public void testQueryUser() {
		Integer userId = 1;
		User user = userService.getUserById(userId);
		System.out.println(user);
	}
	
	@Test
	public void testSaveUser() {
		User user = new User(null, "tom08", new Address("AAA", "BBB", "CCC"), SeasonEnum.AUTUMN);
		userService.saveUser(user);
	}
}
Preparing: SELECT user_id,user_name,address,season FROM table_user WHERE user_id = ?   
Parameters: 1(Integer)  
Total: 1 
User [userId=1, userName=justin, address=Address [province=aaa, city=bbb, street=ccc], season=summer @_@]
Preparing: INSERT INTO table_user ( user_id,user_name,address,season ) VALUES( ?,?,?,? )   
Parameters: null, tom08(String), AAA,BBB,CCC(String), 2(Integer)  
Updates: 1  

猜你喜欢

转载自blog.csdn.net/lizhiqiang1217/article/details/89710109