使用mybatis拦截器做分表,mybatis与postgres josnb 数据类型映射

使用mybatis做分表很方便,即使用拦截器即可。

  • 分表步骤如下

    • 使用注解做分表标示
    • 抽取分表接口
    • 自定义分表策略实现分表接口
    • 编写拦截器
    • 使用jsqlparser 安全替换表名
  • mybatis和postgres jsonb 类型映射步骤
    • 编写JSONTypeHandler转换器
    • 注册到全局Aliase
    • 注册到TypeHandlers
    • 实体json串使用Object 对象
    • mapper.xml文件中的配置使用

分表核心代码

注解:TableSplit.java

/**
 * 
 * @author xielongwang
 *
 * 标注是否需要分表
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface TableSplit {
    // 是否分表
    public boolean split() default true;

    // 表名
    public String value();

    // 获取分表策略
    public String strategy();

    public String ShardColumn();


}

分表接口:Strategy.java

/**
 * 
 * @author xielong.wang
 * 分表接口
 */
public interface Strategy {
     /**
     * 传入原sql 返回分表后的sql
     * @param tableName    基本表名
     * @param sharedColumn 分表key的值
     * @return
     */
    String  convert2( String tableName, Object sharedColumn);
}  

分表策略:DeviceHashStrategy.java

/**
 * 
 * @author xielong.wang
 *  
 * 具体的分表策略
 */
public class DeviceHashStrategy  implements Strategy{

    /**
     * 根据分表键和算法返回相应的表名
     *
     * @param baseTableName     原表名
     * @param sharedKeyValue    分表键的值
     * @return  转换后的表名
     */
    @Override
    public String convert2(String baseTableName, Object sharedKeyValue) {
        //生成表名
        return hashTableAlgorithm(baseTableName,sharedKeyValue);
    }

    private String hashTableAlgorithm(String baseTableName, Object sharedKeyValue) {

        String hashKey = hashAlgorithm((String) sharedKeyValue);

        if (hashKey!=null){
            return  baseTableName+hashKey;
        }
        return  baseTableName;
    }


    public static String hashAlgorithm(String sharedKeyValue) {

        int last= sharedKeyValue.hashCode()%5;

        return String.valueOf(last);
    }


}

策略管理:StrategyManager.java

@Component
public class StrategyManager {

    private Map  strategies=new HashMap();

    public Map getStrategies() {
        return strategies;
    }

    public void setStrategies(Map strategies) {
        this.strategies = strategies;
    }

    public Strategy getStrategy(String strategy) {
        return this.strategies.get(strategy);
    }

}

以上为分表的核心代码。下面是postgres jsonb类型映射

类型映射器:JSONTypeHandler.java

/**
 * @author xielongwang
 * @create 2017-03-22 下午4:02
 * @email xielong.wang@nvr-china.com
 */
@MappedJdbcTypes(JdbcType.OTHER) // 可有可无
@MappedTypes(Object.class)
public class JSONTypeHandler extends BaseTypeHandler<Object> {
    private static final PGobject jsonObject = new PGobject();
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        jsonObject.setType("jsonb");
        jsonObject.setValue(parameter.toString());
        ps.setObject(i, jsonObject);
    }

    @Override
    public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getString(columnIndex);
    }

    @Override
    public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getString(columnIndex);
    }

    @Override
    public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getString(columnName);
    }

}

配置类型转换器

        sqlSessionFactoryBean.setTypeAliasesPackage("org.gpstable.domain,org.gpstable.utils");

        sqlSessionFactoryBean.setTypeHandlersPackage("org.gpstable.utils");

mapper.xml

id="deviceEntity" type="org.gpstable.domain.Device" autoMapping="true">
        <id property="id" column="id" javaType="Long"/>
        <result property="deviceNum" column="device_num" javaType="String"/>
        <result property="sensorData" column="sensor_data" javaType="Object"  jdbcType="OTHER" typeHandler="JSONTypeHandler"/>
    

id="insert2" parameterType="org.gpstable.domain.Device" >
        insert into device (id,device_num,sensor_data) values(nextval('device_share_seq'),#{deviceNum},#{sensorData,javaType=Object,jdbcType=OTHER, typeHandler=JSONTypeHandler});
    

以上为核心代码

具体参考 分表和jsonb类型映射

你可能感兴趣的:(spring,postgres)