简体   繁体   English

使用休眠模式将Json数据存储到Mysql 5.7数据库/从Mysql 5.7数据库获取Json数据

[英]Store/Retrieve Json data to/from Mysql 5.7 database using hibernate

I am going to start a project where I need to generate dynamic google forms. 我将开始一个需要生成动态Google表单的项目。 The requirement for this project is I need to use mysql 5.7 so that I could use json datatype to store/retrieve json data. 该项目的要求是我需要使用mysql 5.7,以便可以使用json数据类型存储/检索json数据。 I am fine with this. 我对此很好。 I know, it is possible using HQL. 我知道,可以使用HQL。 But what I couldn't figure out is how do I implement it with Hibernate using object relational mapping ? 但是我不知道是如何使用对象关系映射在Hibernate中实现它的?

Any Ideas ? 有任何想法吗 ?

Thanks in advance ! 提前致谢 !

Recently I have solved similar task. 最近,我已经解决了类似的任务。 I guess it's too late, but maybe someone finds this useful. 我想为时已晚,但是也许有人觉得这很有用。

Short answer : you should create class (like " com.test.MyJsonType ") that must implement org.hibernate.usertype.UserType interface where the nullSafeGet method should deserialize JSON to java object (using Jackson), the nullSafeSet serialize POJO to JSON and some other auxiliary methods. 简短的回答 :您应该创建必须实现org.hibernate.usertype.UserType接口的类(例如“ com.test.MyJsonType ”),在该接口中nullSafeGet方法应将JSON反序列化为Java对象(使用Jackson), nullSafeSet将POJO序列化为JSON和其他一些辅助方法。

Then you should extend MySQLDialect and register new column type "json". 然后,您应该扩展MySQLDialect并注册新的列类型“ json”。

Finally you can annotate entity fields by @Type(type = " com.test.MyJsonType ") which should be mapped to MySQL json columns. 最后,您可以通过@Type(type =“ com.test.MyJsonType ”)注释实体字段,该实体字段应映射到MySQL json列。

You may also read about @TypeDef here if you don't want write type with package name. 如果您不想用包名写类型,也可以在这里阅读有关@TypeDef的信息

For example: 例如:

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 class: 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);

}
}

Register new column type: 注册新的列类型:

public class JsonMySQLDialect extends MySQLDialect {

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

}

Using: 使用方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用休眠从MySql存储/检索JSON数据时出现UTF-8问题 - UTF-8 issue when using hibernate to store/retrieve JSON data from MySql 如何使用JPA以相反的顺序从mysql数据库中检索数据并存储在列表中? - How to retrieve data from mysql database in reverse order using JPA and store in a List? 如何使用Hibernate从数据库中检索列的Java数据类型? - How to retrieve the java data types of columns from the database using Hibernate? 源代码,用于将图像存储到MySql数据库中并检索它,并使用servlet和Hibernate技术在Jsp中显示 - source code to store image into MySql database and retrieve it and display in Jsp using technologies servlet and Hibernate 使用Hibernate将嵌套的JSON数据保存到MySQL数据库中 - Saving nested JSON data into a MySQL database using Hibernate 通过Hibernate从数据库检索数据的方法 - Ways to Retrieve Data from Database through Hibernate Hibernate-Spatial,JPA,Spring,MySQL 5.7(无法检索Point) - Hibernate-Spatial, JPA, Spring, MySQL 5.7 (unable to retrieve Point) 如何使用JDBC从两个不同的MySQL数据库中检索数据? - How to Retrieve Data from Two Different MySQL Database using JDBC? 使用Android QR扫描仪从MySQL数据库检索数据 - Retrieve data from MySQL database by using Android QR Scanner 休眠空间mysql 5.7 - hibernate spatial mysql 5.7
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM