參考文章:https://blog.csdn.net/java_collect/article/details/80946303
最近的項目有用到mybatis和PostgreSQL,牽扯到數據類型轉換的問題,在參考了之前的ibatis做法和網上的大佬的文章之后,解決了問題。
1. typeHandler的實現
mybatis默認是沒有實現jsonb類型字段對應的TypeHandler,所以一般我們需要自定義mybatis的TypeHandler的一個簡單實現:
package com.demo.common.utils; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedTypes; import org.postgresql.util.PGobject; @MappedTypes({Object.class}) public class JsonbTypeHandler extends BaseTypeHandler{ @Override public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { if (ps != null) { PGobject ext = new PGobject(); ext.setType("jsonb"); ext.setValue(parameter.toString()); ps.setObject(i, ext); } } @Override public Object getNullableResult(ResultSet resultSet, String s) throws SQLException { return resultSet.getObject(s); } @Override public Object getNullableResult(ResultSet resultSet, int i) throws SQLException { return resultSet.getObject(i); } @Override public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return callableStatement.getObject(i); } }
json類型的TypeHandler的簡單實現:
package com.demo.common.utils; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedTypes; import org.postgresql.util.PGobject; @MappedTypes({Object.class}) public class JsonTypeHandler extends BaseTypeHandler{ @Override public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { if (ps != null) { PGobject ext = new PGobject(); ext.setType("json"); ext.setValue(parameter.toString()); ps.setObject(i, ext); } } @Override public Object getNullableResult(ResultSet resultSet, String s) throws SQLException { return resultSet.getObject(s); } @Override public Object getNullableResult(ResultSet resultSet, int i) throws SQLException { return resultSet.getObject(i); } @Override public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return callableStatement.getObject(i); } }
2.insert和update時定義的dto:
package com.demo.entity.vo; import com.demo.common.dto.BaseDto; import lombok.Getter; import lombok.Setter; import java.math.BigDecimal; @Getter @Setter public class ProductSynchronizationVo extends BaseDto { private static final long serialVersionUID = -2987872121583341460L; private String productCode; private String interestRule; private String redeemRule; }
interestRule和redeemRule都是JSON字符串
mapper.xml文件中的配置
<update id="updateProduct" parameterType="com.demo.entity.vo.ProductSynchronizationVo"> update table_test <set> <trim suffixOverrides=","> <if test="interestRule != null"> interest_rule = #{interestRule,jdbcType=OTHER,typeHandler=com.demo.common.utils.JsonbTypeHandler}, </if> <if test="redeemRule != null"> redeem_rule = #{redeemRule,jdbcType=OTHER,typeHandler=com.demo.common.utils.JsonbTypeHandler}, </if> </trim> </set> where product_code = #{productCode,jdbcType=VARCHAR} </update>
3.讀取並解析數據時dto:
package com.demo.entity.dto; import com.demo.common.dto.BaseDto; import lombok.Getter; import lombok.Setter; import java.math.BigDecimal; import java.util.Date; import java.util.List; @Getter @Setter public class ProductDetailsDto extends BaseDto{ private static final long serialVersionUID = -295788347367434359L; private Object interestRule; private Object redeemRule; }
mapper.xml文件中的配置
<resultMap id="BaseResultMap" type="com.demo.entity.dto.ProductDetailsDto"> <result column="interest_rule" jdbcType="OTHER" property="interestRule" typeHandler="com.demo.common.utils.JsonbTypeHandler"/> <result column="redeem_rule" jdbcType="OTHER" property="redeemRule" typeHandler="com.demo.common.utils.JsonbTypeHandler"/> </resultMap>
java代碼中解析轉換,會自動轉換為相應的List或者Map類型:
@Override public ProductDetailsDto getProductDetails(ProductDetailsVo productDetailsVo) { ProductDetailsDto dto = productMapper.getProductDetails(productDetailsVo); dto.setInterestRule(JSON.parse(dto.getInterestRule()+"")); dto.setRedeemRule(JSON.parse(dto.getRedeemRule()+"")); return dto; }