springboot项目自定义mybatis TypeHandl

2021-08-11  本文已影响0人  云中小鱼

项目中需要将java对象以json的方式存储到数据库中的一个字段;最简单的方式是添加、修改时手动进行序列化,查询时再手动进行反序列化;还有一种方式就是自定义实现TypeHandler(mybatis作为持久层框架)将对象的序列与反序列化交给框架。

一、核心依赖

<!--      springboot      -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot</artifactId>
    <version>2.4.5</version>
</dependency>
<!--      lombok      -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
</dependency>
<!--      fastjson      -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.68</version>
</dependency>
<!--      数据库相关      -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.18</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.6</version>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

二、实现自定义TypeHandler

1. bean关系Order中包含User和Item如下

/**
 * 订单类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Order {
    private Long id;
    private BigDecimal price;
    /**
     * 物品信息
     */
    private Item item;
    /**
     * 用户
     */
    private User user;
}

/**
 * 物品
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Item {
    private String name;
    private BigDecimal length;
    private BigDecimal width;
    private BigDecimal weight;
}

/**
 * 用户
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class User {
    private String name;
    private Long id;
}

2. 自定义TypeHandler

// 声明数据库中对应数据类型
@MappedJdbcTypes(JdbcType.VARCHAR)
// 转化后的类型
@MappedTypes(Item.class)
// 继承BaseTypeHandler(TypeHandler接口的实现类)
public class ItemTypeHandler extends BaseTypeHandler<Item> {

    public Item delResult(String jsonSource) throws SQLException {
        if (jsonSource != null) {
            Item item = null;
            try {
                item = JSON.parseObject(jsonSource, Item.class);
            } catch (JSONException ex) {
                throw new SQLException("There is an error converting JSONObject to json format for the content:" + jsonSource);
            }
            return item;
        }
        return null;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Item parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSON.toJSONString(parameter));
    }

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

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

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

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(User.class)
public class UserTypeHandler extends BaseTypeHandler<User> {

    public User delResult(String jsonSource) throws SQLException {
        if (jsonSource != null) {
            User user = null;
            try {
                user = JSON.parseObject(jsonSource, User.class);
            } catch (JSONException ex) {
                throw new SQLException("There is an error converting JSONObject to json format for the content:" + jsonSource);
            }
            return user;
        }
        return null;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, User parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSON.toJSONString(parameter));
    }

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

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

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

3. 配置文件中配置扫描自定义TypeHandler

# 值为包名
mybatis.type-handlers-package=com.example.demo.dao.handler

三、测试

1. Controller

@RestController
public class OrderController {

    @Autowired
    private OrderDAO orderDAO;

    @PostMapping("/add")
    public Object putOne(@RequestBody Order order) {
        int insert = orderDAO.insert(order);
        return order.getId();
    }

    @GetMapping("/get")
    public Object getOne(Long id){
        Order order = orderDAO.selectByPrimaryKey(id);
        return order;
    }

}

2. 调用测试

上一篇下一篇

猜你喜欢

热点阅读