【问题标题】:String search runtime error in JPA SQL query (JPQL)JPA SQL 查询 (JPQL) 中的字符串搜索运行时错误
【发布时间】:2014-01-24 22:43:55
【问题描述】:

当尝试通过 JPA 从数据库中检索表并将其填充到 Table SWT 小部件 (org.eclipse.swt.widgets.Table) 时,执行以下 Java 代码时出现转换错误:

String SQL = String.format("select t.id, t.one, t.two from Test t where t.one like '%%s%' order by t.id",one); //variable one is defined as a parameter of the method (whole method not included here for simplicity)

//this is the code that uses the SQL variable above
EntityManager connection = DB.Connection().createEntityManager(); //the EntityManagerFactory
TypedQuery<Object[]> query = connection.createQuery(SQL, Object[].class); /*gives the same as cast (TypedQuery<Object[]>) */
List<Object[]> tablelist = query.getResultList();
connection.close();

SWTtable.removeAll(); //clears all the elements in the table

for (Object[] row : tablelist) {
    final TableItem item = new TableItem(SWTtable, SWT.None);
    item.setData(row[0]);
    item.setText(0, row[1].toString());
}

String SQL = String.format("select t.id, t.one, t.two from Test p where p.one like '%%s%' order by p.id",one); 行的运行时错误 java.util.UnknownFormatConversionException: Conversion = '''

问题接缝是'%%s%' 变量中的String SQL。我需要保留'%%s%',以便搜索使用上述查询选择的全部或其中一条记录。

  • '%%' - 返回所有记录,但没有字符串参数
  • '%s' - 如果 SQL 查询的语句是 正确

其他一切都会出现问题,字符串 '%%s%' 不是我写的,但我需要保留它或通过保持相同的结果来更改它。我想要的结果是给出所有记录,但在接收到 String 参数时返回该特定记录。

这里的问题可能超出了我的 JPA 知识范围。

【问题讨论】:

  • 你可能需要使用NameQuery 类似"select t.id, t.one, t.two from Test t where t.one like :one order by t.id 然后namedQuery.setParameter("one", "%" + s + "%");
  • 我可以尝试一个 NameQuery,但是 setParameter 方法只返回该参数指定的一个特定记录。
  • setParameter 只是将参数设置为查询.. 类似于PreparedStatement 中的?。看看我的回答,我们在查询中有:one 作为命名参数。

标签: java sql jpa runtime-error


【解决方案1】:

我刚刚检查了TypedQuery API,你可以给它设置参数。

TypedQuery<Object[]> query = connection.createQuery("select t.id, t.one, t.two from Test t where t.one like :one order by t.id", Object[].class);
query.setParamter("one", "%" + s + "%");
List<Object[]> tablelist = query.getResultList();

更新:

这两个条件似乎是分开的,就像其他答案所暗示的那样,您可以通过生成类似

的查询来完成
StringBuilder query = new StringBuilder("select t.id, t.one, t.two from Test t "); 
if (StringUtils.isNotEmpty(s)) { 
    query.append(" where t.one like :one "); 
} 
query.append(" order by t.id");
TypedQuery<Object[]> query = connection.createQuery(query.toString());

【讨论】:

  • 试过并给出了完全相同的结果,我什至不必添加我可以在查询中提供“%s%”的参数。每次搜索后,我现在必须提供一个额外的空格字符才能使其工作,因为使用了最后一个 %。
  • 以上查询为您提供了one 列中包含s 的所有行。你能说出s 可以是什么类型的值以及你对结果的期望吗?
  • 就像它说的 s 是字符串。我提供了一个字符串,即“one”,等于表 Test 中的“one”属性。由于我还想检索字符串“one”未提供的其余字符,因此我将 % 放在需要它的位置,以便获取表 Test 的所有属性并在完成参数 s 时返回特定属性名称在查询中提供。希望这很清楚。
  • 你是对的,第一个案例有效。在我将其修改为您的解决方案后,那里有一个小错误,修复它并且一切正常。很抱歉给您带来不便。如果允许的话,我会把它提高 1000 倍。 +1 并接受答案。谢谢!
【解决方案2】:

我个人会让这两个查询执行得更好。像这样的:

public List<Object[]> collectOne( String param ) {
    TypedQuery<Object[]> query = connection.createQuery("select t.id, t.one, t.two from Test t where t.one like :one order by t.id", Object[].class);
    query.setParamter("one", "%" + param + "%");
    return query.getResultList();
}

public List<Object[]> collectAll() {
    TypedQuery<Object[]> query = connection.createQuery("select t.id, t.one, t.two from Test t order by t.id", Object[].class);
    return query.getResultList();
}

那么你总是可以使用可能带参数或不带参数的怪异方法:

public List<Object[]> collectOneOrAll( String param ) {
    if ( param == null || param.isEmpty() )
        return collectAll();

    return collectOne( param );
}

【讨论】:

  • 收集所有不需要的东西,因为当我想检索所有内容时,我已经单独拥有了它,但事实并非如此。这是 collect all 和 s String 特定单词或字母的混合。当 s i 提供时,它需要检索一个或多个属性的其余字母。 s 只能是一个字母,但也可以是一个单词。该词在该查询中由 % 完成。我唯一无法弄清楚的是该错误是如何产生的以及它意味着什么。 JPA/hibernate 文档中没有提到它。
  • 你不是很清楚。您需要向我们提供失败的测试用例的代码以及您遇到的异常的堆栈跟踪。
猜你喜欢
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 2016-05-10
  • 2021-08-26
相关资源
最近更新 更多