在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

回到顶部