2017-12-18 125 views
0

我有一個名爲box的實體。每個包含一些參數的參數對於許多唯一的ID都是相同的。唯一ID只是數字,並沒有任何其他角色。 所以我創建它們作爲postgresql和Java中的文本數組,我將它們作爲ArrayList並使用自定義用戶類型進行映射。 package com.geniedoc.utils;在postgresql中包含/ in文本數組的Hibernate條件

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


} 

這是我的休眠條件: -

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

我需要包含一個特定的獨特id.But它不工作的框。 僅當我在數據庫中的文本數組中有一個值時才返回結果。 但是,如果我有在數據庫中的多個值,它不顯示任何結果。

任何幫助表示讚賞。

回答

0

實施UserType通常是不值得的。由於Postgres接受數組的字符串格式,因此將類型@PrePersist,​​和@PostLoad函數添加到您的類中會更好。由於它只是數字,所以轉換非常簡單。

@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]); 
} 

至少有4個優化你可以做這個代碼,使其速度更快,更少的內存大戶,但這是短版。

如果您想要做同樣的事情,但是對於字符串數組,您必須非常瞭解該場景中陣列的正確轉義語法,更糟糕的是,可選的雙引號。

相關問題