pl/java在postgresql 中的安装及使用

news/2024/7/9 19:34:32 标签: pl/java, postgresql

pl/java简介

pl/java是一个postgreSQL数据库插件,与pl/sql、pl/perl、pl/python类似,安装该插件之后,函数和触发器可以用java语言实现然后加载进数据库。pljava开发工作于2003年开始,2005年1月第一个正式版本发布。

pl/java下载

git clone https://github.com/tada/pljava

pl/java构建条件

1、C程序编译链接工具,gcc g++ (笔者版本为4.8.5,推荐4.3.0以上版本)
2、jdk(笔者版本为openjdk1.8,1.7以下版本可能会某些依赖下载失败)
3、安装postgre数据库,pg_config路径加入环境变量
4、pljava由maven构建,需要安装maven(不低于3.0.4版本)
note:建议不要用yum安装maven, yum安装的maven版本一般比较低,编译过程可能会由于依赖库版本问题导致编译失败,建议手动下载maven 3.6以上的版本.

 

构建 pl/java 

1、下载pl/java源码到指定目录

[qin@pcmk2 pljava-master]$ pwd
/home/qin/pljava-master

2、进入源码根目录执行命令:mvn clean install

[qin@pcmk2 pljava-master]$ ls
COPYRIGHT  docs  freenode.ver  pljava  pljava-ant  pljava-api  pljava-examples  pljava-packaging  pljava-so  pom.xml  README.md  src  target
[qin@pcmk2 pljava-master]$ mvn clean install

note: 第一次构建,有很多依赖库需要下载,构建过程可能会需要几个小时,请耐心等待,二次构建就会变快

3、构建成功后显示如下:

```bash
[INFO] Executed tasks
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ pljava-packaging ---
[INFO] Installing /home/qin/pljava-master/pljava-packaging/pom.xml to /home/qin/.m2/repository/org/postgresql/pljava-packaging/1.6.0-SNAPSHOT/pljava-packaging-1.6.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for PostgreSQL PL/Java 1.6.0-SNAPSHOT:
[INFO] 
[INFO] PostgreSQL PL/Java ................................. SUCCESS [  2.224 s]
[INFO] PL/Java API ........................................ SUCCESS [ 14.573 s]
[INFO] PL/Java backend Java code .......................... SUCCESS [  5.684 s]
[INFO] PL/Java backend native code ........................ SUCCESS [ 22.446 s]
[INFO] PL/Java Ant tasks .................................. SUCCESS [  0.587 s]
[INFO] PL/Java examples ................................... SUCCESS [12:23 min]
[INFO] PL/Java packaging .................................. SUCCESS [15:00 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  28:11 min
[INFO] Finished at: 2020-05-02T18:48:34+08:00
[INFO] ------------------------------------------------------------------------

构建成功之后pljava-packaging/target子目录下的jar文件pljava-pg9.6-amd64-Linux-gpp.jar,包含有安装pljava所需的所有文件,java -jar命令可以把jar包所包含的文件提取出来并自动放入postgresql安装目录extension子目录下。

安装pl/java进入postgreSQL 9.6

1、build完成之后,执行以下命令,可以安装Pl/java extension进入postgresql安装目录
cd ~/pljava-master/pljava-packaging/target
java -jar pljava-pg9.6-amd64-Linux-gpp.jar

[qin@pcmk2 target]$ java -jar pljava-pg9.6-amd64-Linux-gpp.jar 
/home/qin/pg96/lib/postgresql/libpljava-so-1.6.0-SNAPSHOT.so as bytes
/home/qin/pg96/share/postgresql/pljava/pljava-1.6.0-SNAPSHOT.jar as bytes
/home/qin/pg96/share/postgresql/pljava/pljava-api-1.6.0-SNAPSHOT.jar as bytes
/home/qin/pg96/share/postgresql/pljava/pljava-examples-1.6.0-SNAPSHOT.jar as bytes
/home/qin/pg96/share/postgresql/extension/pljava.control as lines (ASCII)
/home/qin/pg96/share/postgresql/pljava/pljava--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--unpackaged--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.5--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.4--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.3--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.2--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.1--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.1-BETA3--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.1-BETA2--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.1-BETA1--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.0--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.0-BETA3--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.0-BETA2--1.6.0-SNAPSHOT.sql as lines (UTF8)
/home/qin/pg96/share/postgresql/pljava/pljava--1.5.0-BETA1--1.6.0-SNAPSHOT.sql as lines (UTF8)
[qin@pcmk2 target]$ pwd
/home/qin/pljava-master/pljava-packaging/target

2、执行完成后,进入postgresql安装目录下extension子目录,可以发现pljava库文件已经生成

在这里插入图片描述

3、在create extension之前还必须设置一个数据库环境变量pljava.libjvm_location,该变量告诉pljava使用的java库文件位置
可以在postgresql.conf中填加:
pljava.libjvm_location=’/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre/lib/amd64/server/libjvm.so’
该环境变量为会话级,也可以:
SET pljava.libjvm_location TO ‘/usr/lib/jvm/java-1.8.0/lib/…’;

4、psql登录数据库执行create exteinsion:

postgres=# CREATE EXTENSION pljava;
CREATE EXTENSION

5、插件创建成功

postgres=# \dL
                                                      List of languages
  Name   |  Owner   | Trusted |                                         Description                                          
---------+----------+---------+----------------------------------------------------------------------------------------------
 java    | postgres | t       | Trusted/sandboxed language for routines and types in Java; http://tada.github.io/pljava/
 javau   | postgres | f       | Untrusted/unsandboxed language for routines and types in Java; http://tada.github.io/pljava/
 plpgsql | postgres | t       | PL/pgSQL procedural language
(3 rows)

测试plsql 调用java程序

1、用idea写一个PL/java 代码


package com.yaogx.test;

public class Hello {

  public static String hello(Strring url,String data) {
       // 可以通过HTTPClient 远程请求 url。
    return "Hello, " + data+ "!";
  }

}

实现PL / Java代码的方法有两个简单的规则:

  • 它们必须是公共静态的
  • 如果任何参数为 ,他们必须返回null而已。

2、编写manifest.txt

Manifest-Version: 1.0
Main-Class: Hello
Specification-Title: "Hello"
Specification-Version: "1.0"
Created-By: 1.8.0_252
Build-Date: 05/02/2020 21:00

4、加载包含测试程序的Jar包至数据库
pl/java扩展安装之后,sqlj模式下有

install_jar、replace_jar、remove_jar 三个函数用于加载、替换、移除jar包到数据库中
sqlj.replace_jar(<jar_url>, <jar_name>, true)函数包函三个参数
jar_url :jar文件的URL.
jar_name:数据库中映射jar包的逻辑名.

4.1 安装 程序的Jar包

--
-- load java library
--
-- parameters:
--   url_path - where the library is located
--   url_name - how the library is referred to later
--   deploy   - should the deployment descriptor be used?
--
select sqlj.install_jar('file:///opt/pglib/cms-pljava-lib.jar', 'cmspljava', true);

4.2 映射逻辑名 cmspljava 到public模式 

-- set classpath to include new library.
--
-- parameters
--   schema    - schema (or database) name
--   classpath - colon-separated list of url_names.
--
select sqlj.set_classpath('public','cmspljava');

4.3 替换程序jar

-- reload java library
--
select sqlj.replace_jar('file:///opt/pglib/cms-pljava-lib.jar','cmspljava', true);
 

4.4 移除 程序 jar 

-- remove java library
--
-- parameters:
--   url_name - how the library is referred to later
--   undeploy - should the deployment descriptor be used?
--
select sqlj.remove_jar('cmspljava', true);

 

4.5 查询映射是否成功 


-- list classpath
--
select sqlj.get_classpath('public');
 

记住要设置类路径,这一点很重要。 库在卸载时会自动从类路径中删除,但安装后不会自动添加到类路径中。

我们还没有完全完成–我们仍然需要将新功能告诉系统。

 

创建触发器

该触发器会在 新增,删除,修改行字段时,触发该触发器。

-- 2.触发器
CREATE TRIGGER test001Trigger AFTER INSERT OR UPDATE OR DELETE ON "public"."test001"
FOR EACH ROW
EXECUTE PROCEDURE "public"."test001_trigger_fun"();

创建触发器函数

-- 2.触发器函数
CREATE OR REPLACE FUNCTION "public"."test001_trigger_fun"()
  RETURNS "pg_catalog"."trigger" AS $BODY$  
DECLARE
		V_SBSTR varchar(4000);
		V_RESULT "varchar";
		rw RECORD;
		
    BEGIN  
			rw := new;

			raise notice '变动数据拼接 is: %', rw;  -- 输出测试
			V_SBSTR := 'test001&serialno='||new.serialno || '&payintv='||new.payintv || '&operator='||new.operator
						||'&birthday='||new.birthday|| '&makedate='||new.makedate|| '&maketime='||new.maketime;

			raise notice '变动数据拼接 is: %', V_SBSTR;  -- 输出测试
	
			V_RESULT := postrequest('http://yaog', V_SBSTR);  
			raise notice '后端返回结果 V_RESULT is: %', V_RESULT;  -- 输出测试
     RETURN NEW;   
		END;
$BODY$
  LANGUAGE 'plpgsql';

创建存储过程

-- 2.存储过程
CREATE OR REPLACE FUNCTION "public"."postrequest"(varchar, varchar)
  RETURNS varchar AS
	'com.yaogx.test.hello'
LANGUAGE 'java';

 测试plsql函数功能

postgres=# select postrequest('http://xuecheng.com/api/hello','Lining');
   postrequest
----------------
 Hello,data!
(1 row)

postgres=#

 根据表名自动生成触发器及触发函数

public ApiResponse queryPGColumnByTableName(String tableName) {
        List<String> list = dataBaseOperationsDao.queryPGColumnByTableName(tableName);
        StringBuilder sb = new StringBuilder();
        sb.append("\nCREATE OR REPLACE FUNCTION ").append(tableName).append("_trigger_fun () RETURNS TRIGGER AS $$ \n" +
                "   DECLARE \n" +
                "   V_SBSTR VARCHAR (4000) ;\n" +
                "   V_RESULT varchar ;\n" +
                "   V_COLUMN varchar(4000) ;\n")
                .append("   V_OPERATION varchar;\n")
                .append("   V_TABLE_NAME varchar :=")
                .append("\'").append(tableName).append("=\';\n")
                .append("   BEGIN \n    V_SBSTR := '';\n")
                .append("   V_OPERATION := TG_OP;\n")
                .append("  \tIF (TG_OP = 'DELETE') THEN \n");

        int i = list.size();
        for (String str : list) {
            i--;
            // 删除数据时拼接语句
            sb.append("     IF OLD.").append(str).append(" IS NULL THEN \n")
                    .append("       V_COLUMN := ").append("\'&").append(str).append("=*\';\n")
                    .append("   ELSE \n V_COLUMN := ").append("\'&").append(str).append("=\'|| OLD.")
                    .append(str).append(";\n").append(" END IF;\n");
            if (i > 0) {
                sb.append(" V_SBSTR := V_SBSTR || V_COLUMN;\n");
            } else {
                sb.append(" V_SBSTR := V_TABLE_NAME || V_OPERATION || V_SBSTR || V_COLUMN;\n")
                        .append("    ELSIF (TG_OP = 'UPDATE' OR TG_OP = 'INSERT') THEN\n");
            }
        }

        int j = list.size();
        for (String str : list) {
            j--;
            // 新增,修改数据时拼接语句
            sb.append("IF NEW.").append(str).append(" IS NULL THEN \n")
                    .append(" V_COLUMN := ").append("\'&").append(str).append("=*\';\n")
                    .append("ELSE \n V_COLUMN := ").append("\'&").append(str).append("=\'|| NEW.")
                    .append(str).append(";\n").append("END IF;\n");
            if (j > 0) {
                sb.append(" V_SBSTR := V_SBSTR || V_COLUMN;\n");
            } else {
                sb.append(" V_SBSTR := V_TABLE_NAME || V_OPERATION  || V_SBSTR || V_COLUMN;\n");
            }
        }

        sb.append("END IF;\n").append("raise notice '变动数据拼接 is: %',V_SBSTR ; -- 输出测试\n" +
                "V_RESULT := postrequest('http://yaog', V_SBSTR);  \n" +
                "raise notice '后端返回结果 V_RESULT is: %'," +
                " V_RESULT ; -- 输出测试\n" +
                "RETURN NULL ;\n" +
                "END ; \n" +
                "$$ \n" +
                "LANGUAGE plpgsql; \n\n");

        /**
         * 生成触发器
         * CREATE TRIGGER ladimission_trigger AFTER INSERT OR UPDATE OR DELETE ON "public"."ladimission"
         * FOR EACH ROW
         * EXECUTE PROCEDURE "public"."ladimission_trigger_fun"();
         */
        sb.append("\n-- XXX.触发器 \n");
        sb.append("CREATE TRIGGER ").append(tableName).append("_trigger AFTER INSERT OR UPDATE OR DELETE ON \"public\".\"")
                .append(tableName).append("\" \n");
        sb.append("FOR EACH ROW \n")
                .append("EXECUTE PROCEDURE \"public\".\"").append(tableName).append("_trigger_fun\"(); \n");

        System.out.println(sb.toString());


        ApiResponse apiResponse = new ApiResponse();
        apiResponse.setStatus(ApiResponse.SUCCESS);
        apiResponse.setData(sb.toString());
        return apiResponse;
    }

 postgresql数据库,查询表中的字段 Mapper.xml 实现

    <!--根据表名查询PG库指定表的列名-->
    <select id="queryPGColumnByTableName" resultType="java.lang.String" parameterType="java.lang.String">
       select COLUMN_NAME  from information_schema.columns
        where table_schema='public' and table_name=#{tableName}
        order by ordinal_position
    </select>

 

参考博客:https://blog.csdn.net/sxqinjh/article/details/105880430

 


http://www.niftyadmin.cn/n/1537602.html

相关文章

GS7 安装使用Oracle19c 客户端的说明

1. 最近Oracle放出了 windows版本的oracle19c的安装文件(具体时间不详, 自己知道的时候比较晚了) 2. 发现文件其实比较多如图示: 3. 经过自己测试实现发现 不能使用 如下文件进行安装 WINDOWS.X64_193000_client_home.zip 4. 需要使用: WINDOWS.X64_193000_client.zip 注意:…

Java中的String、StringBuilder、StringBuffer

可以证明&#xff0c;字符串操作是计算机程序设计中最常见的行为。 一、String 首先我们要明确&#xff0c;String并不是基本数据类型&#xff0c;而是一个对象&#xff0c;并且是不可变的对象。查看源码就会发现String类为final型的&#xff08;当然也不可被继承&#xff09;&…

[转帖]微软公布2019 Q2财报 几大部门均实现增长

微软公布2019 Q2财报 几大部门均实现增长 https://baijiahao.baidu.com/s?id1624179330159140676&wfrspider&forpc 发布时间&#xff1a;01-3120微软公司今天发布了 2019 年第二财季的收益&#xff0c;其中收入 325 亿美元&#xff0c;净收入 84 亿美元以及 1.08 美元…

2.plsql的编写规范

编写规范1.注释单行注释 --select * from emp where empno7788;--取得员工信息多行注释/*....*/来划分2.标识符号的命名规范1)当定义变量时&#xff0c;建议用v_作为前缀 如&#xff1a;v_sal2)当定义常量时&#xff0c;建议用c_作为前缀 如&#xff1a;c_rate3)当定义游标时&a…

Jersey客户端配置

前言&#xff1a; Jersey是一款基于REST架构的web service框架&#xff0c; jersey-client jar包 百度云盘地址:http://pan.baidu.com/s/1nudITeD 代码&#xff1a; FormTest.class package cn.firstflag.jersey.test;import java.io.IOException;import javax.servlet.Servlet…

Java 整合 OpenCV4.4 之项目安装测试 教程 (一)

一、opencv 简介 OpenCV是一个基于BSD许可&#xff08;开源&#xff09;发行的跨平台计算机视觉库&#xff0c;可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C 类构成&#xff0c;同时提供了Java、Python、Ruby、MATLAB等…

plsql块的实例

实例1 只包括执行部分的pl/sql块set serveroutput on --打开输出选项begindbms_output.put_line(hello,world!);end;相关说明&#xff1a;dbms_output是oracle所提供的包&#xff08;类似java的开发包&#xff09;&#xff0c;该包包含一些过程&#xff0c;put_line就是dbms_o…

关于UITableview刷新笔记

今天在做项目的时候 发现调用tableview 的 reloaddata 方法的时候出现崩溃. - 具体操作是执行某个方法后将数据数组中的某条数据删除&#xff08;数组中存数组&#xff09;发现调用刷新方法后 程序崩溃,查看日志发现是数组越界 调试发现 numofsections 这个方法要慢于 cellforr…