繁体   English   中英

如何强制休眠搜索具有不同模式的值?

[英]How to force hibernate to search for values with different patterns?

首先,问题不是关于忽略字符串开头或结尾的空格,因此它不是重复项。

我在数据库中有一个移动字段,其值采用不同的格式,例如xxx xxx xxx,xxxxxxxxx,x xxx xxx xx等,如何使休眠条件忽略字符串的模式?

例如 ,假设数据库中的数字为344555666

 344555666  is failed 
 344 555 666 is failed 
 344 is true (first three digits that do not have space in database!)

但是,毫无疑问,将提供所有数字,并且所有上述值应返回344 555 666作为结果。

另一个示例如下:

假设用户搜索了所有包含12345的电话号码; 然后DB返回以下结果12345678、12345987和12345768,现在我需要格式化DB返回的这三个数字,然后再显示给用户。

...
private String mobile;
....

过冬

.add(Restrictions.ilike("user.mobile", number); 

PVR的答案很有用,但是将来是否需要添加新格式,例如XXX-XXX-XXX或X-XXXX-XXXX-XXXX,该怎么办? 另请注意,用户仅可使用一个字段输入搜索值。

尝试使用以下方法。

criteria.add(Restrictions.ilike(
user.mobile, number, MatchMode.ANYWHERE));

编辑:

我的意思是,如果没有的格式。 数据库中的XXX只能是XXX XXX XXXX / XXXXXXXXXX中的一个,那么我们需要编写一个特定的逻辑来检查数据库中两种格式的可用性。

number1:以XXX XXX XXXX的格式number2:以XXXXXXXXXX的格式

criteria.add(Restrictions.or(Restrictions.ilike(
    user.mobile, number1, MatchMode.ANYWHERE),(Restrictions.ilike(
    user.mobile, number2, MatchMode.ANYWHERE)));

面对这样的问题,我通常会扭转它。 当前,您在数据库( mobile )的一列中具有不同格式( xxx xxx xxx,xxxxxxxxx,x xxx xxx xx等 )的值,并且很难在该列上进行搜索。

您仍然应该允许以所有这些格式输入手机号码,但是在将它们写入数据库之前,请以一种单一的格式(例如12345679仔细重写它们。 这种重新格式化的方式仅在插入新记录或更新时发生,并且我假设您将拥有比写访问更多的读访问权限。

如果您的数据库中已经有记录,则应考虑使用批处理在单个操作中转换它们。

一旦只有一种格式,就可以在该列上放置一个索引,因为一旦您有成千上万的记录,它就可以将选择查询的速度提高几个数量级。

当您要进行搜索时,请允许用户输入所需格式的任何格式,并应用与插入时相同的转换。 例如,如果用户显示123 456 789123-456-789或您接受的任何格式,则在您的搜索代码中将其转换为123456789然后使用该值进行查询(使用索引...)

从用户的角度来看,您仍然允许他根据需要呈现输入,并且响应可能会更快。 唯一的缺点是您将不会显示他输入的值,而是显示它的标准化版本。

从您(作为程序员)的角度来看,您可以编写和维护起来更简单,并且对数据库的压力较小。

您是否尝试过Projections.sqlProjection

您可以在其中使用replace REPLACE(mobile,'')

我知道这是一个可能会耗尽数据库资源的答案,您可以对其进行测试并检查其是否符合您的需求。

我之前已经做过电话号码格式化,但是,您要寻找的解决方案可能很困难,如果必须使用regex搜索,我将在代码中构造一个regex并在db中搜索。 (Oracle具有regex_like函数,您可能希望使用它代替ilike的休眠模式)

例如,来自客户的电话号码+333 555 9999,数据库中的电话号码:+3 33555 9999

根据客户端发送的内容构造以下正则表达式:

/+(\s-.)*3(\s-.)*3(\s-.)*3(\s-.)*5(\s-.)*5(\s-.)*5(\s-.)*9(\s-.)*9(\s-.)*9(\s-.)*9(\s-.\d\w)*/

您要说的是,电话号码中可能有许多(。)点可能(\\ s)个空格,而许多(-)个henhen后面跟有许多(。\\ s- \\ d \\ w)(例如:x234或ext2342)

根据您与PVR的对话,似乎电话号码的格式可以是任何格式。 Hibernate框架基于模式。 它不能自行处理任何格式。 建议不要在Hibernate中包含基于电话号码的条件。 您必须执行不带电话号码的整个条件查询,此后,您必须具有用于过滤其余结果的Java逻辑。

但是,最好的解决方案是使您的设计更牢固。 最好在电话格式上添加约束。 您可以考虑添加电话格式的验证。

您可以通过实现Criterion接口来编写自己的Criterion。 在您的toSqlString方法中,只需使用数据库的替换功能即可。 AFAIK replace(str, needle, replacement)是SQL99的标准函数,因此它应可在当今的dbms中使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM