【问题标题】:Case sensitive Search in Hibernate CriteriaHibernate Criteria 中区分大小写的搜索
【发布时间】:2012-06-17 08:35:05
【问题描述】:

我正在使用带有 SQL Server 2008 的 Hibernate 3。我想在 Hibernate Criteria 中进行区分大小写的搜索。我无法实现它。我的代码如下:

Criteria criteria = session.createCriteria(User.class); /*line 1*/
criteria.add(Restrictions.eq("userName", userName));    /*line 2*/

我有一个类 User.java,其中包含一个 String userName

数据库条目:

id | user_name
--------------
1  | abc
2  | xyz

现在,如果我在第 2 行将 "abc" 传递为 userName,那么它应该从数据库返回第一条记录。但如果我在第 2 行将"Abc""ABC""aBC" 等作为userName 传递,则不应获取任何记录。

我已经访问过link,但这对我没有帮助,因为我不想将排序规则与 hql 或 SQL Server 一起使用。我愿意对Criteria 使用排序规则,但不知道该怎么做。

【问题讨论】:

    标签: java sql-server hibernate


    【解决方案1】:
    Criteria criteria = s.createCriteria(User.class);
    criteria.add(
        Expression.sql("userName = ? collate Latin1_General_CS_AS_KS_WS", userName, new StringType())
    );
    

    【讨论】:

    • Expression.sql 已弃用。请改用:Session session = HibernateUtil.getSession(); Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.sqlRestriction( "user_name = ? collate Latin1_General_CS_AS", userName, new StringType())); user = (User) criteria.uniqueResult(); 请注意,sqlRestriction 中的列名必须是数据库表中的原始列名(与 HQL 不同)
    【解决方案2】:

    你不能用休眠。问题出在 MS SQL 中 - 默认情况下它使用不区分大小写的排序规则。可以有两种解决方法:

    1 使用休眠选择并对结果进行程序过滤

    2 在为字段创建表时使用区分大小写的排序规则时,您需要搜索:COLLATE SQL_Latin1_General_CP850_BIN2 或为您的服务器指定的其他内容(从 SYSTEMPROPERTY 读取)。

    【讨论】:

    • 感谢您的回复,但我不想使用拼写。还有其他解决办法吗?
    • 只有一个 - 程序过滤:您收到所有结果,然后在循环中将此结果与 java String.equals(在 eq 的情况下)或 String.contains(在 %like% 的情况下)或 startWith 进行比较(在like%的情况下)等。
    • 我也想避免那个循环。无论如何,感谢您的快速回复。
    • 不幸的是没有其他方法:在创建表时调用或在查询或循环内部调用,并进行额外的区分大小写检查。好吧,或者在使用 select 进行搜索时使用其他区分大小写的数据库
    • “查询内部”是什么意思?
    【解决方案3】:

    你可以试试这个(在 Restrictions API 中使用 ilike)

    Criteria criteria = s.createCriteria(User.class);   
    criteria.add(Restrictions.ilike("userName", userName));
    

    问候

    【讨论】:

    • 目前没有这种方法。
    • 安装的是哪个版本?看到这个:docs.jboss.org/hibernate/orm/3.3/reference/es-ES/html/…
    • @esmoreno,您提供的链接不包含任何显示 enableLike() 是可与 Restrictions.
    • @RAS,你完全正确。进入文档,见 15.6 部分。你能试试这个吗?
    • @esmoreno,我试过了,但它对我不起作用。该文件还仅提供理论。你能提供一些如何使用Example的好例子吗?
    【解决方案4】:

    我添加了同样的问题,我直接在 mariadb 服务器中更改了数据库表中的排序规则类型。

    我使用“COLLATE latin1_general_cs”创建表字段

    因此,对该字段的每次搜索都将区分大小写。

    我的表格字段如下所示。

    'case_sensitive_key' varchar(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL DEFAULT '',

    希望对你们中的一些人有所帮助。

    【讨论】:

      【解决方案5】:

      如果您使用 sql 路由,那么在 HQL/Criterion 查询中引用别名时会遇到问题。所需要的只是继承 LikeExpression 或其他任何东西并提供您自己的 toSqlString() 方法。在 MySql 中测试。

      private static class CaseSensitiveLike extends LikeExpression {
      
          protected CaseSensitiveLike(final String propertyName,
                  final String value, final MatchMode mode) {
              super(propertyName, value, mode);
          }
      
          @Override
          public String toSqlString(final Criteria criteria,
                  final CriteriaQuery criteriaQuery) {
              String sql = super.toSqlString(criteria, criteriaQuery);
              return sql + " collate utf8_bin";
          }
      }
      

      然后以下调用可以互换:

      Criterion insensitive = Restrictions.like(myProperty, myValue, MatchMode.ANYWHERE);
      Criterion sensitive =  new CaseSensitiveLike(ldProperty, value, MatchMode.ANYWHERE);
      

      【讨论】:

        【解决方案6】:

        这可能不适合您,但使用 lucene/solr 进行此类查询可能会更好。除了不区分大小写的查询之外,它还会为您处理其他常见场景。

        【讨论】:

        • 一件事,如果在映射表中,如果有人手动将值从驼峰大小写编辑为小写,或者它不会显示在列表中。 SOlr 会解决搜索的问题,但是如果 sql server 发生一些变化就会发生数据不一致
        猜你喜欢
        • 2017-09-29
        • 2011-01-14
        • 2012-01-06
        • 2010-09-12
        • 1970-01-01
        • 2013-06-15
        • 2018-02-26
        • 1970-01-01
        • 2010-09-15
        相关资源
        最近更新 更多