使用 List 属性执行 SQL-LIKE
Execute SQL-LIKE with List attribute
我的 Dao 上有这个方法 class:
public List<E> search(String key, Object value) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
List result = entityManager.createQuery("SELECT a FROM "+clazz.getSimpleName()+" a WHERE a."+key+" LIKE '"+value+"%'").getResultList();
entityManager.getTransaction().commit();
entityManager.close();
return result;
}
当属性是 @Column
或 @OneToOne` 时,sql 工作正常,但当它是这样的时候:
@OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
@OrderColumn
private List<Titulo> nome;
其中 class Titulo
具有以下属性:
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column
private String idioma;
@Column(length=32)
private String conteudo;
导致此错误:
message: left and right hand sides of a binary logic operator were incompatible [java.util.List(org.loja.model.categoria.Categoria.nome) : string]; nested exception is org.hibernate.TypeMismatchException: left and right hand sides of a binary logic operator were incompatible [java.util.List(org.loja.model.categoria.Categoria.nome) : string]
我如何更改方法以使两种类型的属性都起作用?
我设法通过以下方法解决了这个问题,使用 java 反射来检测试图查询的字段类型,并使用适当的 sql 命令。不知道这有多有效;如果有人对此有更好的解决方案,请随时添加另一个答案。
public List<E> search(String key, Object value) throws NoSuchFieldException {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
List result;
Field field = clazz.getDeclaredField(key);
ParameterizedType listType = (ParameterizedType) field.getGenericType();
Class<?> classElement = (Class<?>) listType.getActualTypeArguments()[0];
String nome = classElement.getSimpleName();
Field field2[] = classElement.getDeclaredFields();
String attr = field2[field2.length - 1].getName();
if(field != null) {
if(field2 != null) {
result = entityManager.createQuery("SELECT a FROM "+clazz.getSimpleName()+" a, "+nome+" b WHERE b."+attr+" LIKE '"+value+"%'").getResultList();
} else {
result = entityManager.createQuery("SELECT a FROM "+clazz.getSimpleName()+" a, "+nome+" b WHERE b LIKE '"+value+"%'").getResultList();
}
} else {
result = entityManager.createQuery("SELECT a FROM "+clazz.getSimpleName()+" a WHERE a."+key+" LIKE '"+value+"%'").getResultList();
}
entityManager.getTransaction().commit();
entityManager.close();
return result;
}
更新
我在上面的代码中遇到了一个问题:在第一个查询(if/else 中的三个查询中),它总是返回 table 的所有元素,几乎如果 LIKE 被忽略。
我的 Dao 上有这个方法 class:
public List<E> search(String key, Object value) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
List result = entityManager.createQuery("SELECT a FROM "+clazz.getSimpleName()+" a WHERE a."+key+" LIKE '"+value+"%'").getResultList();
entityManager.getTransaction().commit();
entityManager.close();
return result;
}
当属性是 @Column
或 @OneToOne` 时,sql 工作正常,但当它是这样的时候:
@OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
@OrderColumn
private List<Titulo> nome;
其中 class Titulo
具有以下属性:
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column
private String idioma;
@Column(length=32)
private String conteudo;
导致此错误:
message: left and right hand sides of a binary logic operator were incompatible [java.util.List(org.loja.model.categoria.Categoria.nome) : string]; nested exception is org.hibernate.TypeMismatchException: left and right hand sides of a binary logic operator were incompatible [java.util.List(org.loja.model.categoria.Categoria.nome) : string]
我如何更改方法以使两种类型的属性都起作用?
我设法通过以下方法解决了这个问题,使用 java 反射来检测试图查询的字段类型,并使用适当的 sql 命令。不知道这有多有效;如果有人对此有更好的解决方案,请随时添加另一个答案。
public List<E> search(String key, Object value) throws NoSuchFieldException {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
List result;
Field field = clazz.getDeclaredField(key);
ParameterizedType listType = (ParameterizedType) field.getGenericType();
Class<?> classElement = (Class<?>) listType.getActualTypeArguments()[0];
String nome = classElement.getSimpleName();
Field field2[] = classElement.getDeclaredFields();
String attr = field2[field2.length - 1].getName();
if(field != null) {
if(field2 != null) {
result = entityManager.createQuery("SELECT a FROM "+clazz.getSimpleName()+" a, "+nome+" b WHERE b."+attr+" LIKE '"+value+"%'").getResultList();
} else {
result = entityManager.createQuery("SELECT a FROM "+clazz.getSimpleName()+" a, "+nome+" b WHERE b LIKE '"+value+"%'").getResultList();
}
} else {
result = entityManager.createQuery("SELECT a FROM "+clazz.getSimpleName()+" a WHERE a."+key+" LIKE '"+value+"%'").getResultList();
}
entityManager.getTransaction().commit();
entityManager.close();
return result;
}
更新 我在上面的代码中遇到了一个问题:在第一个查询(if/else 中的三个查询中),它总是返回 table 的所有元素,几乎如果 LIKE 被忽略。