使用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