2017-12-18 6 views
0

Ich habe eine Entität mit dem Namen box.Jede Box enthält einige Parameter, die für viele eindeutige IDs identisch sein können. Eindeutige IDs sind nur Zahlen und haben keine andere Rolle. SO erstellte ich sie als Text-Array in Postgresql und in Java habe ich sie als ArrayList und zugeordnet sie mit benutzerdefinierten Benutzer Typ. Paket com.geniedoc.utils;Hibernate-Kriterien für enthält/in in Array in Postgresql

import java.io.Serializable; 
import java.sql.Array; 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Types; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Iterator; 
import java.util.List; 
import java.util.StringTokenizer; 
import org.hibernate.HibernateException; 
import org.hibernate.engine.spi.SessionImplementor; 
import org.hibernate.usertype.UserType; 

public class PostgresTextArrayType implements UserType { 

    protected static final int[] SQL_TYPES = {Types.ARRAY}; 
    public Class<String> returnedClass() { 
      return String.class; 
     } 

    public final int[] sqlTypes() { 
      return SQL_TYPES; 
     } 


     @Override 
     public Object nullSafeGet(ResultSet resultSet, String[] names, 
       SessionImplementor arg2, Object arg3) 
       throws HibernateException, SQLException { 
      List<String> list = null; 
      String nameVal = resultSet.getString(names[0]); 
      if (nameVal != null) { 
       nameVal = nameVal.substring(1,nameVal.length()-1); 
       list = new ArrayList<>(); 
       StringTokenizer tokenizer = new StringTokenizer(nameVal, ","); 
       while (tokenizer.hasMoreElements()) { 
        String val = (String) tokenizer.nextElement(); 
        list.add(val); 
       } 
      } 

      return list; 

     } 

     @Override 
     public void nullSafeSet(PreparedStatement statement, Object value, int index, 
       SessionImplementor arg3) throws HibernateException, 
       SQLException { 
      Connection connection = statement.getConnection(); 
       if (value == null) { 
        statement.setNull(index, SQL_TYPES[0]); 
       } else { 
        System.out.println("statement>>>>"+statement); 
        System.out.println("value>>>>"+ value); 
        System.out.println("index>>>>"+index); 
        @SuppressWarnings("unchecked") 
        ArrayList<String> parameter=new ArrayList<>(); 
        if(value instanceof Array) 
        { parameter=(ArrayList<String>) value; 
        }else 
        { 
         parameter.add((String) value); 
        } 
        ArrayList<String> list=parameter; 
        String[] castObject = Arrays.copyOf(list.toArray(), list.toArray().length, String[].class); 
        Array array = connection.createArrayOf("text", castObject); 
        statement.setArray(index, array); 
        System.out.println("statement>>>>"+statement); 
       } 
     } 
     @Override 
     public final Object deepCopy(final Object value) throws HibernateException { 
      return value; 
     } 

     @Override 
     public final boolean isMutable() { 
      return false; 
     } 

     @Override 
     public final Object assemble(final Serializable serializable, final Object arg1) 
       throws HibernateException { 
      return serializable; 
     } 

     @Override 
     public final Serializable disassemble(final Object o) throws HibernateException { 
      return (Serializable) o; 
     } 

     @Override 
     public final boolean equals(final Object x, final Object y) throws HibernateException { 
      if (x == y) { 
       return true; 
      } else if (x == null || y == null) { 
       return false; 
      } else { 
       return x.equals(y); 
      } 
     } 

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

     @Override 
     public final Object replace(
      final Object original, 
      final Object target, 
      final Object owner) throws HibernateException { 
      return original; 
     } 
      private String serialize(List<String> list) { 
       StringBuilder strbul = new StringBuilder(); 
       Iterator<String> iter = list.iterator(); 
       strbul.append("{"); 
       while (iter.hasNext()) { 
        strbul.append(iter.next()); 
        if (iter.hasNext()) { 
         strbul.append(","); 
        } 
       } 
       strbul.append("}"); 
       return strbul.toString(); 
      } 


} 

Dies ist meine Hibernate Kriterien: -

Session session=getSession(); 
    Criteria criteria=session.createCriteria(Box.class); 
    criteria.add(Restrictions.in("unique_id", unique_id)); 
    return (Unit)criteria.uniqueResult(); 

Ich brauche die Box zu erhalten, die eine bestimmte einzigartige id.But enthält es funktioniert nicht. Es gibt nur Ergebnisse zurück, wenn ich einen Wert im Text-Array in DB habe. Aber wenn ich mehrere Werte in DB habe, zeigt es kein Ergebnis.

Jede Hilfe wird geschätzt.

Antwort

0

Implementieren UserType ist in der Regel nicht die Mühe wert. Sie werden besser @PrePersist, @PreUpdate und @PostLoad Funktionen zu Ihrer Klasse hinzufügen, da Postgres ein Zeichenfolgenformat für Arrays akzeptiert. Da es nur Zahlen sind, ist die Transformation ziemlich einfach.

@Transient 
private long[] theids; 

@Column(name = "the_ids") 
private String therealids; 

@PrePersist 
@PreUpdate 
private void encode() { 
    therealids = "{" + java.util.Arrays.toString(theids) + "}"; 
} 

@PostLoad 
private void decode() { 
    String[] ids = therealids.split(","); 
    theids = new long[ids.length]; 
    if (ids.length == 0) { 
     return; 
    } 
    int last = ids.length - 1; 
    // remove the "{" 
    ids[0] = ids[0].substr(1); 
    // remove the "}" 
    ids[last] = ids[last].substr(0, ids[last].length() - 1); 
    for (int i = 0; i < ids.length; i++) theids[i] = Long.parseLong(ids[i]); 
} 

Es gibt mindestens 4 Optimierungen Sie in diesem Code tun kann es schneller zu machen und weniger speicherhungrig, aber das ist die kurze Version.

Wenn Sie dasselbe tun möchten, aber mit String-Arrays, müssen Sie sich der richtigen Escape-Syntax für Arrays in diesem Szenario bewusst sein, und schlimmer noch, die optionalen doppelten Anführungszeichen.

Verwandte Themen