Jpa 重写方言dialect 使用oracle / mysql 数据库自定义函数

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

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

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

    /**
     * Create an expression for the execution of a database
     * function.
     * @param name  function name
     * @param type  expected result type
     * @param args  function arguments
     * @return expression
     */
   <T> Expression<T> function(String name, Class<T> type,
Expression<?>... args);

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

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

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

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

        Expression<String> distinct = cb.function("distinct",
                String.class, root.get("ID"));

        Expression<String> wmConcat = cb.function("wm_concat",
                String.class, distinct);

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

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

protected void registerFunctions() {
        registerFunction( "abs", new StandardSQLFunction("abs") );
        registerFunction( "sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) );

        registerFunction( "acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) );
        registerFunction( "asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) );
        registerFunction( "atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) );
        registerFunction( "bitand", new StandardSQLFunction("bitand") );
        registerFunction( "cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) );
        registerFunction( "cosh", new StandardSQLFunction("cosh", StandardBasicTypes.DOUBLE) );
        registerFunction( "exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) );
        registerFunction( "ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) );
        registerFunction( "sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) );
        registerFunction( "sinh", new StandardSQLFunction("sinh", StandardBasicTypes.DOUBLE) );
        registerFunction( "stddev", new StandardSQLFunction("stddev", StandardBasicTypes.DOUBLE) );
        registerFunction( "sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) );
        registerFunction( "tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) );
        registerFunction( "tanh", new StandardSQLFunction("tanh", StandardBasicTypes.DOUBLE) );
        registerFunction( "variance", new StandardSQLFunction("variance", StandardBasicTypes.DOUBLE) );

        registerFunction( "round", new StandardSQLFunction("round") );
        registerFunction( "trunc", new StandardSQLFunction("trunc") );
        registerFunction( "ceil", new StandardSQLFunction("ceil") );
        registerFunction( "floor", new StandardSQLFunction("floor") );

        registerFunction( "chr", new StandardSQLFunction("chr", StandardBasicTypes.CHARACTER) );
        registerFunction( "initcap", new StandardSQLFunction("initcap") );
        registerFunction( "lower", new StandardSQLFunction("lower") );
        registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
        registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
        registerFunction( "soundex", new StandardSQLFunction("soundex") );
        registerFunction( "upper", new StandardSQLFunction("upper") );
        registerFunction( "ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) );

        registerFunction( "to_char", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
        registerFunction( "to_date", new StandardSQLFunction("to_date", StandardBasicTypes.TIMESTAMP) );

        registerFunction( "current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) );
        registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIME, false) );
        registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false) );

        registerFunction( "last_day", new StandardSQLFunction("last_day", StandardBasicTypes.DATE) );
        registerFunction( "sysdate", new NoArgSQLFunction("sysdate", StandardBasicTypes.DATE, false) );
        registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", StandardBasicTypes.TIMESTAMP, false) );
        registerFunction( "uid", new NoArgSQLFunction("uid", StandardBasicTypes.INTEGER, false) );
        registerFunction( "user", new NoArgSQLFunction("user", StandardBasicTypes.STRING, false) );

        registerFunction( "rowid", new NoArgSQLFunction("rowid", StandardBasicTypes.LONG, false) );
        registerFunction( "rownum", new NoArgSQLFunction("rownum", StandardBasicTypes.LONG, false) );

        // Multi-param string dialect functions...
        registerFunction( "concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", "") );
        registerFunction( "instr", new StandardSQLFunction("instr", StandardBasicTypes.INTEGER) );
        registerFunction( "instrb", new StandardSQLFunction("instrb", StandardBasicTypes.INTEGER) );
        registerFunction( "lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING) );
        registerFunction( "replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING) );
        registerFunction( "rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING) );
        registerFunction( "substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) );
        registerFunction( "substrb", new StandardSQLFunction("substrb", StandardBasicTypes.STRING) );
        registerFunction( "translate", new StandardSQLFunction("translate", StandardBasicTypes.STRING) );

        registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
        registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "instr(?2,?1)" ) );
        registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "vsize(?1)*8" ) );
        registerFunction( "coalesce", new NvlFunction() );

        // Multi-param numeric dialect functions...
        registerFunction( "atan2", new StandardSQLFunction("atan2", StandardBasicTypes.FLOAT) );
        registerFunction( "log", new StandardSQLFunction("log", StandardBasicTypes.INTEGER) );
        registerFunction( "mod", new StandardSQLFunction("mod", StandardBasicTypes.INTEGER) );
        registerFunction( "nvl", new StandardSQLFunction("nvl") );
        registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
        registerFunction( "power", new StandardSQLFunction("power", StandardBasicTypes.FLOAT) );

        // Multi-param date dialect functions...
        registerFunction( "add_months", new StandardSQLFunction("add_months", StandardBasicTypes.DATE) );
        registerFunction( "months_between", new StandardSQLFunction("months_between", StandardBasicTypes.FLOAT) );
        registerFunction( "next_day", new StandardSQLFunction("next_day", StandardBasicTypes.DATE) );

        registerFunction( "str", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) );
    }

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

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

public class MyOracleDialect extends Oracle12cDialect {

    /**
     * 添加oracler内置函数和自定义函数
     */
    @Override
    protected void registerFunctions() {
        super.registerFunctions();
        registerFunction("wm_concat", new StandardSQLFunction("wm_concat", StandardBasicTypes.STRING));
    }

    /**
     * 解决启动时数字溢出的错误
     * @return
     */
    @Override
    public String getQuerySequencesString() {
        return "select * from user_sequences";
    }
}

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

原文地址:https://www.cnblogs.com/hankuikui/p/11734194.html

时间: 2025-01-23 02:21:33

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

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

MySql数据库--mysql_real_escape_string()函数 来自:http://www.cppblog.com/woaidongmao/archive/2009/08/13/93154.html unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length) 注意,mysql必须是有效的开放式连接.之所以需要它是因为,转义功能取决于服务器

MySQL之自定义函数与存储过程

MySQL数据库常用函数与自定义函数 1 SELECT ABS(-8);#绝对值 2 SELECT MOD(10,9); #取模 3 SELECT FLOOR(12.99); #地板 4 SELECT CEILING(10.01);#天花板 5 SELECT ROUND(12.99);#随机数,看第一个小数点数 6 SELECT CONCAT('i','love','java');#拼接 7 SELECT * FROM t_user t WHERE t.`uname` LIKE CONCAT('

数据库自定义函数

一.函数 在数据库中都有函数,这些函数属于系统函.除此之外用户也可以编写用户自定义函数.用户定义函数是存储在数据库中的代码块,可以把值返回到调用程序.调用时如同系统函数一样,如max(value)函数,其value被称为参数.函数一般功能比较简单,对于mysql函数只有传入参数,不像存储过程一样,有输入输出参数. 数据库函数特点如下: 存储函数将向调用者返回一个且仅返回一个结果值. 存储函数嵌入在sql中使用的,可以在select中调用,就像内建函数一样,比如cos().hex(). 存储函数的

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

mysql创建自定义函数与存储过程 一 创建自定义函数 在使用mysql的过程中,mysql自带的函数可能不能完成我们的业务需求,这时就需要自定义函数,例如笔者在开发过程中遇到下面这个问题 mysql表结构如下 DROP TABLE IF EXISTS `test`; CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `pic` varchar(50) NOT NULL, `hashcode` varchar

Java连接Oracle/MySQL数据库教程

导入包:import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; 声明变量:private static String USERNAMR = "lsdb"; //数据库用户名,在mysql所有数据库用户名密码是一样的,oracle各数据库的用户名

php操作mysql数据库的函数(天龙八部)

===================================    PHP_MySQL的操作===================================一.操作步骤:    1. 连接MySQL数据库    2. 判断是否连接成功    3. 选择数据库    4. 设置字符集    5. 准备SQL语句    6. 向MySQL服务发送SQL语句    7. 解析处理结果集    8. 释放结果集,关闭数据库连接    二.常用操作:   1. mysql_connect(

MySQL 数据库 password函数

在MySQL数据库中 执行下面这一句,会对字符串生成加密后的 新的字符串 .用户在数据库中存储密码. SELECT PASSWORD('aa') 生成的字符串 已 * 号开头. 比如 '*DEE59C300700AF9B586F9F2A702231C0AC373A13' SELECT OLD_PASSWORD('aa') ; OLD_PASSWORD 是旧版本的加密函数 ,生成的字符串是 16位的 如'aa' 加密后是 '077baf58491e1952' . 这种生成密码的方法 依赖数据库,而

MySQL 数据库 常用函数

一.数学函数 数学函数主要用于处理数字,包括整型.浮点数等. ABS(x) 返回x的绝对值 SELECT ABS(-1) -- 返回1 CEIL(x),CEILING(x) 返回大于或等于x的最小整数 SELECT CEIL(1.5) -- 返回2 FLOOR(x) 返回小于或等于x的最大整数 SELECT FLOOR(1.5) -- 返回1 RAND() 返回0->1的随机数 SELECT RAND() --0.93099315644334 RAND(x) 返回0->1的随机数,x值相同时返

mysql数据库创建函数过程

1.创建mysql数据库的存储过程,语句 2.选择执行创建的数据库存储过程即可