简单类型和复杂类型
通用 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`)
);
public class AddressTypeHandler extends BaseTypeHandler {
@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
4、枚举类型处理
方式1:让通用 Mapper 把枚举类型作为简单类型处理 。Spring 配置文件中添加通用 Mapper 的配置项 enumAsSimpleType=true
。本质上使用了 org.apache.ibatis.type.EnumTypeHandler
enumAsSimpleType=true
方式2::为枚举类型配置对应的类型处理器
5、枚举类型处理器 :
内置:
org.apache.ibatis.type.EnumTypeHandler
在数据库中存储枚举值本身
org.apache.ibatis.type.EnumOrdinalTypeHandler
在数据库中仅仅存储枚举值的索引
自定义:和AddressTypeHandler操作一样
6、内置枚举类型处理器注册
内置类型处理器不能使用@ColumnType 注解
在 MyBatis 配置文件中配置 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