簡單類型和複雜類型
通用 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