自己做发卡网站支付接口,网站推广的优缺点,多种专业网站建设,怎么建自己的平台一、 数据库类型 二、使用Hutool工具
存储时将数据转换为JSON数据 获取时将JSON数据转换为对象 发现问题#xff1a;
原本数据对象是Address 和 Firend但是转换完成后数据变成了JSONArray和JSONObject
三、自定义TypeHandler继承Mybatis的BaseTypeHandler处理器
package …一、 数据库类型 二、使用Hutool工具
存储时将数据转换为JSON数据 获取时将JSON数据转换为对象 发现问题
原本数据对象是Address 和 Firend但是转换完成后数据变成了JSONArray和JSONObject
三、自定义TypeHandler继承Mybatis的BaseTypeHandler处理器
package com.jiusi.config;import cn.hutool.json.JSONUtil;
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;public class jsonTypeHandler01T extends BaseTypeHandler {Overridepublic void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {//将数据转换为json字符串ps.setString(i, JSONUtil.toJsonStr(parameter));}Overridepublic T getNullableResult(ResultSet rs, String columnName) throws SQLException {//将json字符串转换为任意类型if(rs.getString(columnName).charAt(0){){return (T) JSONUtil.parseObj(rs.getString(columnName));}return (T)JSONUtil.parseArray(rs.getString(columnName));}Overridepublic T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return null;}Overridepublic T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return null;}
}
在xml中使用
添加数据时在需要改变的字段后添加TypeHandler属性使用自定义的JsonTypeHandler insert idinsertinsert into msg (name, age, height, address, friend)values (#{name}, #{age}, #{height}, #{address,typeHandlercom.jiusi.config.jsonTypeHandler},#{friend,typeHandlercom.jiusi.config.jsonTypeHandler})/insert
获取数据时在ResultMap里Result上添加typeHandler属性同样使用自定义的JackonTypeHandler resultMap typecom.jiusi.model.Msg idJackonresult propertyid columnid/resultresult propertyname columnname/resultresult propertyage columnage/resultresult propertyheight columnheight/resultresult propertyaddress columnaddress typeHandlercom.jiusi.config.JackonTypeHandler /resultresult propertyfriend columnfriend typeHandlercom.jiusi.config.JackonTypeHandler/result/resultMap但是查询出来的同样是JSONArray和HJSONObject
为什么使用BaseTypeHandler 而不是 TypeHandler
BaseTypeHandlerT是一个实现了TypeHandler接口的抽象基类提供了对TypeHandler接口的一些基础实现和默认行为简化了自定义类型处理器的开发。通过继承BaseTypeHandler开发者只需要关注具体的转换逻辑而无需重复实现所有接口方法。
四、结合Redis进行转换
往数据库存储数据的同时将全类名也存入进去 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencypackage com.jiusi.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class jsonTypeHandler02T extends BaseTypeHandlerT {Jackson2JsonRedisSerializerObject serializer;// 解决序列化乱码问题public jsonTypeHandler02() { // 指定序列化输入的类型, 即输入到redis的类型serializer new Jackson2JsonRedisSerializer(Object.class);// 指定序列化输出的类型ObjectMapper objectMapper new ObjectMapper();//JsonAutoDetect.Visibility.ANY 代表所有属性或字段都可以序列化objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);//新版用法//以数组的方式存放到RedisClass Type 全类名作为为第一个元素Json字符串为第二个元素。objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);}Overridepublic void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {//将参数序列化为byts数组然后转成字符串ps.setString(i,new String( serializer.serialize(parameter)));}Overridepublic T getNullableResult(ResultSet rs, String columnName) throws SQLException {// 将字符串反序列化为对象return (T) serializer.deserialize(rs.getString(columnName).getBytes(StandardCharsets.UTF_8));}Overridepublic T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return null;}Overridepublic T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return null;}}
将xml中的typeHandler 修改成当前处理器 五、自定义序列化方式
与Redis一样将全类名同时存入数据库
package com.jiusi.config;import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;/*** 自定义序列化方式* param T*/
public class MybatisToJsonConfigT {static {DEFAULT_CHARSET StandardCharsets.UTF_8;}public static final Charset DEFAULT_CHARSET;private final JavaType javaType;private ObjectMapper objectMapper new ObjectMapper();public MybatisToJsonConfig(ClassT type) {this.javaType this.getJavaType(type);}public MybatisToJsonConfig(JavaType javaType) {this.javaType javaType;}public T deserialize(Nullable byte[] bytes) throws Exception {try {return this.objectMapper.readValue(bytes, 0, bytes.length, this.javaType);} catch (Exception ex) {throw new Exception(无法读取JSON: ex.getMessage(), ex);}}public byte[] serialize(Nullable Object t) throws Exception {try {return this.objectMapper.writeValueAsBytes(t);} catch (Exception ex) {throw new Exception(无法写入JSON: ex.getMessage(), ex);}}public void setObjectMapper(ObjectMapper objectMapper) {Assert.notNull(objectMapper, objectMapper 不能为空);this.objectMapper objectMapper;}private JavaType getJavaType(Class? clazz) {return TypeFactory.defaultInstance().constructType(clazz);}}package com.jiusi.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** 同样继承BaseTypeHandler但是序列化方式是使用自定义序列化方式* param T*/
public class JsonTypeHandler03T extends BaseTypeHandlerT {private static MybatisToJsonConfigObject serializer;static {serializer new MybatisToJsonConfig(Object.class);ObjectMapper objectMapper new ObjectMapper();//JsonAutoDetect.Visibility.ANY 代表所有属性或字段都可以序列化objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);//以数组的方式存放到RedisClass Type 全类名作为为第一个元素Json字符串为第二个元素。objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);serializer.setObjectMapper(objectMapper);}Overridepublic void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {//使用Redis的序列化将参数序列化为byts数组然后转成字符串try {ps.setString(i,new String( serializer.serialize(parameter)));} catch (Exception e) {e.printStackTrace();}}Overridepublic T getNullableResult(ResultSet rs, String columnName) throws SQLException {// 是使用自定义的Redis反序列化将字符串反序列化为对象try {return (T) serializer.deserialize(rs.getString(columnName).getBytes(StandardCharsets.UTF_8));} catch (Exception e) {e.printStackTrace();}return null;}Overridepublic T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return null;}Overridepublic T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return null;}}
将xml中的typeHandler 修改成当前处理器 六、Mybatis-Plus
使用Mybatis-Plus同样可以只需要只需要加两个注解在类上添加TableNameValue “表名” , autoResultMap true,并且在需要转换的字段上添加TableField( typeHandler 处理器)
处理器可以使用上面我们自定义的处理器