在使用criteria api进行查询时 criteriaBuilder只提供了一个部分标准的sql函数,但当我们需要使用oracle特有的行转列函数wm_concat或

mysql特有的行转列函数group_concat时,就只能自己封装了,

criteriaBuilder提供了一个封装函数的方法:

  1. /**
  2. * Create an expression for the execution of a database
  3. * function.
  4. * @param name function name
  5. * @param type expected result type
  6. * @param args function arguments
  7. * @return expression
  8. */
  9. <T> Expression<T> function(String name, Class<T> type,
  10. Expression<?>... args);

如我们封装wm_concat函数,代码如下:

  1. Expression<String> wmConcat = cb.function("wm_concat",
  2. String.class, root.get("ID"));

生成的sql 如:select  wm_concat(id)........

如果我们想生成 select wm_concat(distinct(id))这个的形式,来去id进行去重distinct。可以用下面的代码,对function进行嵌套:

  1. Expression<String> distinct = cb.function("distinct",
  2. String.class, root.get("ID"));
  3.  
  4. Expression<String> wmConcat = cb.function("wm_concat",
  5. String.class, distinct);

当然这还没有完,生成这样的函数后,其实jpa是不认可wm_concat函数的,(distinct函数,lower函数等是认可的),这是为什么呢,因为jpa认可的oracle函数都会在OracleDialect定义。

如我使用的OracleDialect版本是Oracle12cDialect,它本身没有注册自定义函数,但是它继承的类Oracle8iDialect注册了很多函数,如下:

  1. protected void registerFunctions() {
  2. registerFunction( "abs", new StandardSQLFunction("abs") );
  3. registerFunction( "sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );
  4.  
  5. registerFunction( "acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
  6. registerFunction( "asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
  7. registerFunction( "atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
  8. registerFunction( "bitand", new StandardSQLFunction("bitand") );
  9. registerFunction( "cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
  10. registerFunction( "cosh", new StandardSQLFunction("cosh", StandardBasicTypes.DOUBLE) );
  11. registerFunction( "exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
  12. registerFunction( "ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
  13. registerFunction( "sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
  14. registerFunction( "sinh", new StandardSQLFunction("sinh", StandardBasicTypes.DOUBLE) );
  15. registerFunction( "stddev", new StandardSQLFunction("stddev", StandardBasicTypes.DOUBLE) );
  16. registerFunction( "sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) );
  17. registerFunction( "tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
  18. registerFunction( "tanh", new StandardSQLFunction("tanh", StandardBasicTypes.DOUBLE) );
  19. registerFunction( "variance", new StandardSQLFunction("variance", StandardBasicTypes.DOUBLE) );
  20.  
  21. registerFunction( "round", new StandardSQLFunction("round") );
  22. registerFunction( "trunc", new StandardSQLFunction("trunc") );
  23. registerFunction( "ceil", new StandardSQLFunction("ceil") );
  24. registerFunction( "floor", new StandardSQLFunction("floor") );
  25.  
  26. registerFunction( "chr", new StandardSQLFunction("chr", StandardBasicTypes.CHARACTER) );
  27. registerFunction( "initcap", new StandardSQLFunction("initcap") );
  28. registerFunction( "lower", new StandardSQLFunction("lower") );
  29. registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
  30. registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
  31. registerFunction( "soundex", new StandardSQLFunction("soundex") );
  32. registerFunction( "upper", new StandardSQLFunction("upper") );
  33. registerFunction( "ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) );
  34.  
  35. registerFunction( "to_char", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
  36. registerFunction( "to_date", new StandardSQLFunction("to_date", StandardBasicTypes.TIMESTAMP) );
  37.  
  38. registerFunction( "current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) );
  39. registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIME, false) );
  40. registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false) );
  41.  
  42. registerFunction( "last_day", new StandardSQLFunction("last_day", StandardBasicTypes.DATE) );
  43. registerFunction( "sysdate", new NoArgSQLFunction("sysdate", StandardBasicTypes.DATE, false) );
  44. registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", StandardBasicTypes.TIMESTAMP, false) );
  45. registerFunction( "uid", new NoArgSQLFunction("uid", StandardBasicTypes.INTEGER, false) );
  46. registerFunction( "user", new NoArgSQLFunction("user", StandardBasicTypes.STRING, false) );
  47.  
  48. registerFunction( "rowid", new NoArgSQLFunction("rowid", StandardBasicTypes.LONG, false) );
  49. registerFunction( "rownum", new NoArgSQLFunction("rownum", StandardBasicTypes.LONG, false) );
  50.  
  51. // Multi-param string dialect functions...
  52. registerFunction( "concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", "") );
  53. registerFunction( "instr", new StandardSQLFunction("instr", StandardBasicTypes.INTEGER) );
  54. registerFunction( "instrb", new StandardSQLFunction("instrb", StandardBasicTypes.INTEGER) );
  55. registerFunction( "lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING) );
  56. registerFunction( "replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING) );
  57. registerFunction( "rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING) );
  58. registerFunction( "substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) );
  59. registerFunction( "substrb", new StandardSQLFunction("substrb", StandardBasicTypes.STRING) );
  60. registerFunction( "translate", new StandardSQLFunction("translate", StandardBasicTypes.STRING) );
  61.  
  62. registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
  63. registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "instr(?2,?1)" ) );
  64. registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "vsize(?1)*8" ) );
  65. registerFunction( "coalesce", new NvlFunction() );
  66.  
  67. // Multi-param numeric dialect functions...
  68. registerFunction( "atan2", new StandardSQLFunction("atan2", StandardBasicTypes.FLOAT) );
  69. registerFunction( "log", new StandardSQLFunction("log", StandardBasicTypes.INTEGER) );
  70. registerFunction( "mod", new StandardSQLFunction("mod", StandardBasicTypes.INTEGER) );
  71. registerFunction( "nvl", new StandardSQLFunction("nvl") );
  72. registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
  73. registerFunction( "power", new StandardSQLFunction("power", StandardBasicTypes.FLOAT) );
  74.  
  75. // Multi-param date dialect functions...
  76. registerFunction( "add_months", new StandardSQLFunction("add_months", StandardBasicTypes.DATE) );
  77. registerFunction( "months_between", new StandardSQLFunction("months_between", StandardBasicTypes.FLOAT) );
  78. registerFunction( "next_day", new StandardSQLFunction("next_day", StandardBasicTypes.DATE) );
  79.  
  80. registerFunction( "str", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
  81. }

通过调试代码,可以看到oracledialect共注册了80个函数。

同理,我们也可继承Oracle12cDialect,添加自己的函数:

  1. public class MyOracleDialect extends Oracle12cDialect {
  2.  
  3. /**
  4. * 添加oracler内置函数和自定义函数
  5. */
  6. @Override
  7. protected void registerFunctions() {
  8. super.registerFunctions();
  9. registerFunction("wm_concat", new StandardSQLFunction("wm_concat", StandardBasicTypes.STRING));
  10. }
  11.  
  12. /**
  13. * 解决启动时数字溢出的错误
  14. * @return
  15. */
  16. @Override
  17. public String getQuerySequencesString() {
  18. return "select * from user_sequences";
  19. }
  20. }

配置完成后,启动项目即可。

Jpa 重写方言dialect 使用oracle / mysql 数据库自定义函数的更多相关文章

  1. Hibernate根据方言dialect动态连接多数据库

    Hibernate根据方言dialect动态连接多数据库 由于最近需要在web项目中动态链接不同地址的数据库,且要链接的子数据库的信息在总数据库(即web项目的主数据库)的表中,所以动手写了一个类. ...

  2. 【转】MySql数据库--mysql_real_escape_string()函数

    MySql数据库--mysql_real_escape_string()函数 unsigned long mysql_real_escape_string(MYSQL *mysql, char *to ...

  3. MySQL数据库聚合函数

    +++++++++++++++++++++++++++++++++++++++++++标题:MySQL数据库聚合函数时间:2019年2月25日内容:MySQL数据库聚合函数重点:MySQL数据库聚合函 ...

  4. mysql数据库-定义函数-存储过程写法

    ------------- mysql  定义自定义函数写法 DELIMITER $$ USE `iwmsdb`$$ DROP FUNCTION IF EXISTS `F_WM_DBNAME`$$ C ...

  5. navicat与phpmyadmin做mysql的自定义函数和事件

    自定义函数和事件是mysql一个很方便的功能,navicat在5.1以上版本就支持了自定义函数和事件,phpmyadmim不清楚. 用这个是由于一些简单的事情,没有必要去做一个服务器计划使用 接下来我 ...

  6. Mysql - 存储过程/自定义函数

    在数据库操作中, 尤其是碰到一些复杂一些的系统, 不可避免的, 会用到函数/自定义函数, 或者存储过程. 实际项目中, 自定义函数和存储过程是越少越好, 因为这个东西多了, 也是一个非常难以维护的地方 ...

  7. mysql创建自定义函数与存储过程

    mysql创建自定义函数与存储过程 一 创建自定义函数 在使用mysql的过程中,mysql自带的函数可能不能完成我们的业务需求,这时就需要自定义函数,例如笔者在开发过程中遇到下面这个问题 mysql ...

  8. Oracle存储过程和自定义函数

    新博客文章链接,欢迎大家评论探讨 概述 存储过程和存储函数是指存储在数据库中供所有用户程序调用的子程序叫存储过程.存储函数. 异同点: 存储过程和存储函数的相同点:完成特定功能的程序. 存储过程和存储 ...

  9. Jmeter连接DB2/ORACLE/MYSQL数据库

    连接DB2 1.将db2数据库驱动db2java.jar.db2jcc.jar放入jmeter的lib/下,同时也要放入本地jdk目录下例如:C:\Program Files\Java\jdk1.7. ...

随机推荐

  1. Apicloud_(项目)网上书城02_后端数据获取

    Apicloud_(项目)网上书城01_前端页面开发 传送门 Apicloud_(项目)网上书城02_后端数据获取 传送门 Apicloud_(项目)网上书城03_拓展模块实现 传送门 ApiClou ...

  2. @Transient使用心得

    使用注解@Transient使表中没有此字段 注意,实体类中要使用org.springframework.data.annotation.Transient 在写实体类时发现有加@Transient注 ...

  3. postman 测试api接口

    安装:https://www.getpostman.com/ 谷歌插件安装需要翻墙才能访问,那么直接去官网下载pc端 代码图片: 非常简单 post: 代码图片: 剪头地方,必选

  4. 【学习】SpringBoot之简介、特点、缺点、应用场景

    Spring Boot 的介绍 SpringBoot的目的在于创建和启动新的基于Spring框架的项目.Spring Boot 会选择最合适的Spring子项目和第三方开源库进行整合.大部分Sprin ...

  5. 数据库 mysql 操作

    安装好xammp,打开阿帕奇和数据库服务: 点击右侧 shell 按钮,进入命令行: 首先,利用超级管理员权限进入数据库: mysql -uroot -p enter,再enter 把下述代码复制进命 ...

  6. watir安装——windows环境

    默认情况下,gem sources 都是https://rubygems.org/

  7. Win7、win8、win10下实现精准截获Explorer拷贝行为

    介绍了windows下对Explorer的拷贝动作的精确截获,这个在企业数据安全dlp产品系列中减少审计的噪音很有效,方便运营人员做针对性的审计. 在企业数据安全中我通常需要监测用户的拷贝行为,特别像 ...

  8. Java String.Format() 方法及参数说明

    转自:https://blueram.iteye.com/blog/441683 JDK1.5中,String类新增了一个很有用的静态方法String.format():format(Locale l ...

  9. ControlTemplate in WPF —— Window

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x ...

  10. linux 代码更新-打包-重启脚本

    #! /bin/sh base=/home/project/myblog cd $base git pull ] then echo "Error in git pull!!! Stop d ...