在postgresql中包含/ in文本数组的Hibernate条件
我有一个名为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它不工作的框。 仅当我在数据库中的文本数组中有一个值时才返回结果。 但是,如果我有在数据库中的多个值,它不显示任何结果。
任何帮助表示赞赏。
回答:
实施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个优化你可以做这个代码,使其速度更快,更少的内存大户,但这是短版。
如果您想要做同样的事情,但是对于字符串数组,您必须非常了解该场景中阵列的正确转义语法,更糟糕的是,可选的双引号。
以上是 在postgresql中包含/ in文本数组的Hibernate条件 的全部内容, 来源链接: utcz.com/qa/261501.html