2015-09-28 25 views
9

Tôi sẽ bắt đầu một dự án mà tôi cần để tạo các biểu mẫu google động. Yêu cầu cho dự án này là tôi cần sử dụng mysql 5.7 để tôi có thể sử dụng kiểu dữ liệu json để lưu trữ/lấy dữ liệu json. Tôi ổn với điều này. Tôi biết, có thể sử dụng HQL. Nhưng những gì tôi không thể tìm ra là làm thế nào để thực hiện nó với Hibernate bằng cách sử dụng ánh xạ đối tượng quan hệ?Lưu/Lấy dữ liệu Json đến/từ cơ sở dữ liệu MySQL Mysql bằng cách sử dụng hibernate

Bất kỳ ý tưởng nào?

Cảm ơn trước!

+0

Tôi đoán nó là có thể, tuy nhiên tôi không nghĩ rằng có một cách đơn giản, chắc chắn nó là rất nhiều công việc ... Bạn có biết 'torodb'? Họ đang làm loại điều tương tự, tuy nhiên tôi đoán họ không sử dụng 'HQL' và bên dưới họ có' postgresql' ... Chúc may mắn. – lrnzcig

+0

Cảm ơn thông tin! –

Trả lời

3

Gần đây tôi đã giải quyết được tác vụ tương tự. Tôi đoán đã quá trễ, nhưng có lẽ ai đó thấy điều này hữu ích.

Câu trả lời ngắn: bạn nên tạo đẳng cấp (như "com.test.MyJsonType") mà phải thực hiện org.hibernate.usertype.UserType giao diện nơi nullSafeGet phương pháp nên deserialize JSON để đối tượng java (sử dụng Jackson), nullSafeSet nối tiếp POJO với JSON và một số phương thức phụ trợ khác.

Sau đó, bạn nên mở rộng MySQLDialect và đăng ký loại cột mới "json".

Cuối cùng, bạn có thể chú thích trường thực thể theo @Type (type = "com.test.MyJsonType") sẽ được ánh xạ tới cột json của MySQL.

Bạn cũng có thể đọc về @TypeDef here nếu bạn không muốn viết loại có tên gói.

Ví dụ:

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 lớp:

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

} 
} 

Đăng ký mới loại cột:

public class JsonMySQLDialect extends MySQLDialect { 

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

} 

Sử dụng:

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

Liệu nó có tạo ra một cột kiểu "json" hoặc varchar? – gtiwari333

+0

Nó tạo ra loại cột "json". –

+2

Java tự động gọi super(). Nhưng nếu bạn muốn bạn có thể gọi nó một cách rõ ràng. –

Các vấn đề liên quan