java - 使用 hibernate 在 Mysql 5.7 数据库中存储/检索 Json 数据

标签 java json hibernate mysql-5.7

我将开始一个需要生成动态 google 表单的项目。这个项目的要求是我需要使用 mysql 5.7 以便我可以使用 json 数据类型来存储/检索 json 数据。我对此很好。我知道,可以使用 HQL。但我想不通的是如何使用对象关系映射在 Hibernate 中实现它?

有什么想法吗?

提前致谢!

最佳答案

最近我解决了类似的任务。我想为时已晚,但也许有人觉得这很有用。

简短回答:您应该创建必须实现 org.hibernate.usertype.UserType 的类(如“com.test.MyJsonType”) > 接口(interface),nullSafeGet 方法应将 JSON 反序列化为 java 对象(使用 Jackson),nullSafeSet 将 POJO 序列化为 JSON 和一些其他辅助方法。

那么你应该扩展 MySQLDialect 并注册新的列类型“json”。

最后,您可以通过 @Type(type = "com.test.MyJsonType") 注释实体字段,它应该映射到 MySQL json 列。

您还可以阅读@TypeDef here如果您不想使用包名称写入类型。

例如:

public class MyJsonType implements UserType {

@Override
public int[] sqlTypes() {
    return new int[] { Types.VARCHAR };
}

@Override
public Class<Characteristics> returnedClass() {
    return Characteristics.class;
}

@Override
public Object nullSafeGet(final ResultSet rs, final String[] names, final SessionImplementor session, final Object owner)
        throws HibernateException, SQLException {
    final String cellContent = rs.getString(names[0]);
    if (cellContent == null) {
        return null;
    }
    try {
        final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper.readValue(cellContent.getBytes("UTF-8"), returnedClass());
    } catch (final Exception ex) {
        throw new RuntimeException("Failed to convert String to Invoice: " + ex.getMessage(), ex);
    }
}

@Override
public void nullSafeSet(final PreparedStatement ps, final Object value, final int idx, final SessionImplementor session)
        throws HibernateException, SQLException {
    if (value == null) {
        ps.setNull(idx, Types.VARCHAR);
        return;
    }
    try {
        final ObjectMapper mapper = new ObjectMapper();
        final StringWriter w = new StringWriter();
        mapper.writeValue(w, value);
        w.flush();
        ps.setObject(idx, w.toString(), Types.VARCHAR);
    } catch (final Exception ex) {
        throw new RuntimeException("Failed to convert Invoice to String: " + ex.getMessage(), ex);
    }
}

@Override
public Object deepCopy(final Object value) throws HibernateException {
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(value);
        oos.flush();
        oos.close();
        bos.close();

        ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
        return new ObjectInputStream(bais).readObject();
    } catch (ClassNotFoundException | IOException ex) {
        throw new HibernateException(ex);
    }
}

@Override
public boolean isMutable() {
    return true;
}

@Override
public Serializable disassemble(final Object value) throws HibernateException {
    return (Serializable) this.deepCopy(value);
}

@Override
public Object assemble(final Serializable cached, final Object owner) throws HibernateException {
    return this.deepCopy(cached);
}

@Override
public Object replace(final Object original, final Object target, final Object owner) throws HibernateException {
    return this.deepCopy(original);
}

@Override
public boolean equals(Object x, Object y) throws HibernateException {
    return Objects.equals(x, y);
}

@Override
public int hashCode(Object x) throws HibernateException {
    return Objects.hashCode(x);
}

}

POJO 类:

public class Characteristics implements Serializable {

private String field;

public String getField() {
    return field;
}

public void setField(String field) {
    this.field= field;
}

@Override
public boolean equals(Object obj) {

    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    final Characteristics other = (Characteristics) obj;
    return Objects.equals(this.field, other.field);

}

@Override
public int hashCode() {

    return Objects.hash(this.field);

}
}

注册新的列类型:

public class JsonMySQLDialect extends MySQLDialect {

public JsonMySQLDialect() {
    this.registerColumnType(Types.VARCHAR, "json");
}

}

使用:

@Entity
@Table(name = "Table")
public class TableClass {
...
@Column
@Type(type = "com.test.MyJsonType")
protected Characteristics characteristics;
...
}

关于java - 使用 hibernate 在 Mysql 5.7 数据库中存储/检索 Json 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32819485/

相关文章:

java - Gson自定义序列化

java - Hibernate SQL 参数记录

java - 我如何告诉我的数据库某些更改是由 hibernate 而不是其他应用程序进行的?

java - fb 中的操作 :request form is always null

java - Redis过期不起作用

c++ - 构建 JSON 对象的算法

c# - 无法使用 C# 驱动程序过滤 MongoDB 中的日期字段

java - SQL 查询太复杂而无法在 JPA Criteria API 中表达?

java - String.matches 不匹配模式

java - 获取玩家库存,然后广播元素显示名称