使用mybatis中的自定义TypeHandler处理PostgreSQL中的Jsonb类型


参考文章: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;
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM