有一定关系型数据的操作功底,会SQL语句
熟练掌握Java如何操作Oracle数据库
到这,Oracle基本的操作基本上都讲完了,下面说下编程语言如何操作Oracle数据库,本篇以Java为例子。
使用sott 用户中的dept表/emp表作为例子
dept
编号 | 字段 | 类型 | 描述 |
---|---|---|---|
1 | DEPTNO | NUMBER(2) | 部门编号 |
2 | DNAME | VARCHAR2(14) | 部门名称 |
3 | LOC | VARCHAR2(13) | 部门位置 |
emp
编号 | 字段 | 类型 | 描述 |
---|---|---|---|
1 | EMPNO | NUMBER(4) | 雇员编号 |
2 | ENAME | VARCHAR2(10) | 表示雇员姓名 |
3 | JOB | VARCHAR2(9) | 表示工作职位 |
4 | MGR | NUMBER(4) | 表示一个雇员的领导编号 |
5 | HIREDATE | DATE | 表示雇佣日期 |
6 | SAL | NUMBER(7,2) | 表示月薪,工资 |
7 | COMM | NUMBER(7,2) | 表示奖金或佣金 |
8 | DEPTNO | NUMBER(2) | 表示部门编号 |
这里自己去搭建,如果不会,建议先学习一下maven相关知识点
这里需要注意,操作的oracle版本需要跟jdk版本对应,否则会导致兼容问题
com.oracle.database.jdbc
ojdbc10
19.10.0.0
org.projectlombok
lombok
1.18.16
provided
org.junit.jupiter
junit-jupiter
RELEASE
compile
这里需要额外注意:因为oracle安全协议,maven并不会下载对应的jar进入仓库, 需要自己额外打包
mvn install:install-file -Dfile=本地jar包所在路径\ojdbc10-19.10.0.0.jar -DgroupId=com.oracle.database.jdbc -DartifactId=ojdbc10 -Dversion=19.10.0.0 -Dpackaging=jar
-Dfile:指定本地jar所在路径
-DgroupId:包路径
-DartifactId:包名
-Dversion:包版本
注意:jar需要到oracle官网或者maven仓库去下载, 下载完成之后, 包路径,包名, 版本名必须一直,否则mvn命令执行会失败。
@Setter
@Getter
@ToString
public class Department {
private Long deptno;
private String dname;
private String loc;
}
@Test
public static void testConn() throws Exception {
String url ="jdbc:oracle:thin:@localhost:1521:ORCL";
String uname="scott";
String pwd="tiger";
Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
Connection connection = DriverManager.getConnection(url, uname, pwd);
System.out.println(connection);
connection.close();
}
如果需要id自动增长,需要提前创建一个id序列
create sequence dept_id_seq increment by 1 start with 1;
@Test
public void testAdd() throws Exception {
String url="jdbc:oracle:thin:@localhost:1521:ORCL";
String uname="scott";
String pwd="tiger";
Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
Connection connection = DriverManager.getConnection(url, uname, pwd);
String sql = "insert into dept(deptno, dname, loc) values(dept_id_seq.nextval,?,?)";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, "小卖部");
ps.setString(2, "广州");
ps.execute();
ps.close();
connection.close();
}
@Test
public void testDelete() throws Exception {
String url="jdbc:oracle:thin:@localhost:1521:ORCL";
String uname="scott";
String pwd="tiger";
Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
Connection connection = DriverManager.getConnection(url, uname, pwd);
String sql = "delete from dept where deptno = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setLong(1, 1L);
ps.execute();
ps.close();
connection.close();
}
@Test
public void testUpdate() throws Exception {
String url="jdbc:oracle:thin:@localhost:1521:ORCL";
String uname="scott";
String pwd="tiger";
Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
Connection connection = DriverManager.getConnection(url, uname, pwd);
String sql = "update dept set dname=? where deptno = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, "大卖部");
ps.setLong(2, 1L);
ps.execute();
ps.close();
connection.close();
}
@Test
public static void testQuery() throws Exception {
String url="jdbc:oracle:thin:@localhost:1521:ORCL";
String uname="scott";
String pwd="tiger";
Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
Connection connection = DriverManager.getConnection(url, uname, pwd);
PreparedStatement ps = connection.prepareStatement("select * from dept");
ResultSet rs = ps.executeQuery();
while(rs.next()){
Department department = new Department();
department.setDeptno(rs.getLong("deptno"));
department.setDname(rs.getString("dname"));
department.setLoc(rs.getString("loc"));
System.out.println(department);
}
rs.close();
ps.close();
connection.close();
}
//分页信息分组对象
@Getter
public class PageResult {
private int currentPage; //当前页
private int pageSize; //每页显示条数
private int totalCount; //总记录数
private List data; //当前页显示数据集
private int prePage; //上一页
private int nextPage; //下一页
private int totalPage; //总页数
public PageResult(int currentPage, int pageSize, int totalCount, List data){
this.currentPage = currentPage;
this.pageSize = pageSize;
this.totalCount = totalCount;
this.data = data;
if(totalCount == 0){
this.prePage = 1;
this.totalPage = 1;
this.nextPage = 1;
}
this.totalPage = totalCount % pageSize == 0? totalCount/pageSize : totalCount / pageSize + 1;
this.prePage = currentPage > 1 ? currentPage - 1 : 1;
this.nextPage = currentPage > totalPage ? currentPage + 1 : totalPage;
}
}
@Test
public void testPage() throws Exception {
String url="jdbc:oracle:thin:@localhost:1521:ORCL";
String uname="scott";
String pwd="tiger";
Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
Connection connection = DriverManager.getConnection(url, uname, pwd);
//查总数
String totalsql = "select count(1) from dept ";
PreparedStatement ps = connection.prepareStatement(totalsql);
ResultSet countRS = ps.executeQuery();
int totalCount = 0;
while (countRS.next()){
totalCount = countRS.getInt(1);
}
countRS.close();
ps.close();
//模拟页面传入:currentPage pageSize
int currentPage = 1;
int pageSize = 3;
int skip = (currentPage - 1) * pageSize;
String sql = "select * from dept offset ? rows fetch next ? rows only";
ps = connection.prepareStatement(sql);
ps.setInt(1, skip);
ps.setInt(2, pageSize);
ResultSet rs = ps.executeQuery();
List data = new ArrayList<>();
while(rs.next()){
Department department = new Department();
department.setDeptno(rs.getLong("deptno"));
department.setDname(rs.getString("dname"));
department.setLoc(rs.getString("loc"));
data.add(department);
}
//分页对象
PageResult page = new PageResult(currentPage, pageSize, totalCount, data);
System.out.println("当前页:" + page.getCurrentPage());
System.out.println("上一页:" + page.getPrePage());
System.out.println("下一页:" + page.getNextPage());
System.out.println("总页数:" + page.getTotalPage());
System.out.println("每页显示:" + page.getPageSize());
System.out.println("每页数据:" );
page.getData().forEach(System.out::println);
rs.close();
ps.execute();
ps.close();
connection.close();
}
jdbc 调用存储过程/函数有2种格式
{?= call [(,, ...)]} //包含结果参数的调用形式 如:函数(funciton)
{call [(,, ...)]} //不包含结果参数的调用形式 如:存储过程(procedure)
设置参数
in输入型
setXXX(int parameterIndex,XXX x) //主要用于设置过程调用时候需要的输入参数信息 其中XXX代表对应类型
out输出型
void registerOutParameter(int parameterIndex, int sqlType)
throws SQLException; //在调用存储过程的时候设置输出参数的类型,用于接收输出结果
其中sqlType 通过OracleTypes枚举类型指定
public abstract class OracleTypes {
public static final int BIT = -7;
public static final int TINYINT = -6;
public static final int SMALLINT = 5;
public static final int INTEGER = 4;
public static final int BIGINT = -5;
public static final int FLOAT = 6;
public static final int REAL = 7;
public static final int DOUBLE = 8;
public static final int NUMERIC = 2;
public static final int DECIMAL = 3;
public static final int CHAR = 1;
public static final int VARCHAR = 12;
public static final int LONGVARCHAR = -1;
public static final int DATE = 91;
public static final int TIME = 92;
public static final int TIMESTAMP = 93;
public static final int PLSQL_BOOLEAN = 252;
/** @deprecated */
public static final int TIMESTAMPNS = -100;
public static final int TIMESTAMPTZ = -101;
public static final int TIMESTAMPLTZ = -102;
public static final int INTERVALYM = -103;
public static final int INTERVALDS = -104;
public static final int BINARY = -2;
public static final int VARBINARY = -3;
public static final int LONGVARBINARY = -4;
public static final int ROWID = -8;
public static final int CURSOR = -10;
public static final int BLOB = 2004;
public static final int CLOB = 2005;
public static final int BFILE = -13;
public static final int STRUCT = 2002;
public static final int ARRAY = 2003;
public static final int REF = 2006;
public static final int NCHAR = -15;
public static final int NCLOB = 2011;
public static final int NVARCHAR = -9;
public static final int LONGNVARCHAR = -16;
public static final int SQLXML = 2009;
public static final int REF_CURSOR = 2012;
public static final int OPAQUE = 2007;
public static final int JAVA_STRUCT = 2008;
public static final int JAVA_OBJECT = 2000;
public static final int PLSQL_INDEX_TABLE = -14;
public static final int BINARY_FLOAT = 100;
public static final int BINARY_DOUBLE = 101;
public static final int NULL = 0;
public static final int NUMBER = 2;
public static final int RAW = -2;
public static final int OTHER = 1111;
public static final int FIXED_CHAR = 999;
public static final int DATALINK = 70;
public static final int BOOLEAN = 16;
public OracleTypes() {
}
}
返回值
getXXX(int x) //主要用于获取过程调用后返回的参数的信息
定义存储过程
-- 给指定员工加100工资
create or replace procedure addSal(v_eno in number)
is
v_sal number;
begin
update emp set sal = sal + 100 where empno = v_eno;
dbms_output.put_line('操作成功');
end;
调用存储过程
@Test
public void testPro() throws Exception {
String url="jdbc:oracle:thin:@localhost:1521:ORCL";
String uname="scott";
String pwd="tiger";
Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
Connection connection = DriverManager.getConnection(url, uname, pwd);
//调用存储过程, 指定名称
CallableStatement cs = connection.prepareCall("{call addSal(?)}");
//传入参数
cs.setLong(1,7981);
cs.execute();
cs.close();
connection.close();
}
定义函数
-- 调用函数
create or replace function findEmpYearSal(pno in number,pname out varchar2,psal out number)
return number
as
pcomm emp.comm%type;
begin
select ename,sal,comm into pname,psal,pcomm from emp where empno=pno;
return psal*12+nvl(pcomm,0);
end;
调用函数
@Test
public void testFun() throws Exception {
String url="jdbc:oracle:thin:@localhost:1521:ORCL";
String uname="scott";
String pwd="tiger";
Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
Connection connection = DriverManager.getConnection(url, uname, pwd);
//调用存储过程, 指定名称
CallableStatement cs = connection.prepareCall("{? = call findEmpYearSal(?,?,?)}");
//设置返回值类型
cs.registerOutParameter(1, OracleTypes.DOUBLE);
cs.setLong(2,7981);
cs.registerOutParameter(3, OracleTypes.VARCHAR);
cs.registerOutParameter(4, OracleTypes.NUMBER);
cs.execute();
System.out.println("年薪:" + cs.getDouble(1));
System.out.println("姓名:" + cs.getString(3));
System.out.println("月薪:" + cs.getString(4));
cs.close();
connection.close();
}