学習要件
リレーショナル データ操作に関する一定の知識があり、SQL ステートメントを知っている
教育目標
Java と Oracle データベースの操作方法に精通している
コンセプト
ここまででOracleの基本的な操作は大体終わったので、Javaを例にOracleデータベースをプログラミング言語で操作する方法を説明します。
プロジェクトの準備
1> データベースを構築し、テーブルを作成する
例として sott ユーザーの dept テーブル/emp テーブルを使用します。
部門
シリアルナンバー | 分野 | タイプ | 説明 |
---|---|---|---|
1 | DEPTNO | 2番) | 部門番号 |
2 | DNAME | VARCHAR2(14) | 部署名 |
3 | LOC | VARCHAR2(13) | 部門の場所 |
従業員
シリアルナンバー | 分野 | タイプ | 説明 |
---|---|---|---|
1 | エンプノ | 番号(4) | 従業員番号 |
2 | エナメ | VARCHAR2(10) | 従業員名を表示 |
3 | 仕事 | VARCHAR2(9) | 役職を示す |
4 | MGR | 番号(4) | 従業員のリーダー番号を示します |
5 | ヒレダテ | 日にち | 入社日を表示 |
6 | SAL | NUMBER(7,2) | 月給、給与を示す |
7 | 通信 | NUMBER(7,2) | ボーナスまたはコミッションを示します |
8 | DEPTNO | 2番) | 部門番号を示します |
Maven プロジェクト oracle-demo-jdbc を作成します
ここでは自分でビルドします。そうでない場合は、まず Maven 関連の知識ポイントについて学習することをお勧めします。
Oracle のインポート、jdbc の操作は依存します
ここで、操作の oracle バージョンは jdk バージョンに対応する必要があることに注意してください。そうしないと、互換性の問題が発生します。
依存関係のインポート
<dependencies>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc10</artifactId>
<version>19.10.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
ここでさらに注意が必要です。オラクルのセキュリティ プロトコルのため、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: パッケージ版
注: The jar needs to be Download from the oracle official website or the maven Warehouse. ダウンロードが完了した後、パッケージ パス、パッケージ名、およびバージョン名が同じである必要があり、そうでない場合、mvn コマンドの実行は失敗します。
jdbc 接続操作コードを記述する
@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<T> {
private int currentPage; //当前页
private int pageSize; //每页显示条数
private int totalCount; //总记录数
private List<T> data; //当前页显示数据集
private int prePage; //上一页
private int nextPage; //下一页
private int totalPage; //总页数
public PageResult(int currentPage, int pageSize, int totalCount, List<T> 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<Department> 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<Department> page = new PageResult<Department>(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 <procedure-name>[(<arg1>,<arg2>, ...)]} //包含结果参数的调用形式 如:函数(funciton)
{call <procedure-name>[(<arg1>,<arg2>, ...)]} //不包含结果参数的调用形式 如:存储过程(procedure)
設定パラメータ
入力タイプで
setXXX(int parameterIndex,XXX x) //主要用于设置过程调用时候需要的输入参数信息 其中XXX代表对应类型
出力タイプ
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();
}