【问题标题】:How to use the named parameters with CONTAINS如何将命名参数与 CONTAINS 一起使用
【发布时间】:2012-12-31 21:37:00
【问题描述】:

我想像这样使用带有 CONTAINS 的命名参数:

select p from person p
where CONTAINS(p.name , :myName)

String myName = "Bob Jones";
q.setString("myName", "*" + myName + "*");  

不行,报错:

org.hibernate.exception.GenericJDBCException: could not execute query
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.loader.Loader.doList(Loader.java:2536)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:316)
    at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1842)
    at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
    at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:157)
Caused by: java.sql.SQLException: Erreur de syntaxe près de 'Jones*' dans la condition de recherche en texte intégral '*Bob Jones*'.
    at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:368)
    at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2820)
    at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2258)
    at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:632)
    at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:477)
    at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:778)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
    at org.hibernate.loader.Loader.doQuery(Loader.java:802)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2533)
    ... 8 more

我使用休眠 3.6 我应该怎么办? 谢谢!

【问题讨论】:

  • q.setString("myName", myName+"%");

标签: java hibernate


【解决方案1】:

我假设您使用的是 SQL Server。那么您的查询包含与 Hibernate 或 Java 无关的问题。这只是关于 CONTAINS 运算符的语法。用任何可以直接查询数据库的工具试试吧。

如果要查询两个单词,语法为以下之一:

select * from person where contains(name, 'Bob AND Jones');
select * from person where contains(name, 'Bob OR Jones');
select * from person where contains(name, '"Bob Jones"');

如果你还想查询前缀,那就是:

select * from person where contains(name, 'Bob* AND Jones*');
select * from person where contains(name, 'Bob* OR Jones*');
select * from person where contains(name, '"Bob Jones*"');

您不能将星号放在单词或短语的前面。

我建议你看看CONTAINS operator的描述。

更新:

感谢您的评论。如果您查看旧代码,您会注意到包含在 CONTAINS 的第二个参数中的额外双引号,类似于我的第三个也是最后一个示例。这就是您当前代码中缺少的内容。所以要修复它:

String myName = "Bob Jones";
q.setString("myName", "\"*" + myName + "*\"");

【讨论】:

  • 感谢您的回答。我正在使用 SQL Server。旧查询看起来像这样: String myName = "Bob Jones"; select p from person p where CONTAINS(p.name , '\"*" + myName + "*\"') 可以,但是我必须使用命名参数来避免sql注入。
  • @user1940268:使用绑定参数来防止 SQL 注入是一件非常好的事情。请看看我更新的答案。我认为您只是缺少一对双引号。
  • 您的更新解决了我的问题。谢谢你。我的最后一个答案是另一个问题。
  • @user1940268:如果我的回答解决了您的问题,您应该通过单击答案旁边的复选标记将其从空心切换为绿色来接受它。这是对 StackOverflow 用户的重要反馈,因为它表明哪些答案是有用的。
【解决方案2】:

您可能想尝试使用 like 而不是 contains。

from Person p where p.name like :myName

那么当你执行查询时

List<User> userList = query.setParameter("myName", "%" + name+ "%").list();

【讨论】:

  • 谢谢,但我必须使用 CONTAINS
猜你喜欢
  • 2022-07-29
  • 2017-06-25
  • 1970-01-01
  • 2016-06-16
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多