初识JDBC(Oracle)
——Javee
学习Java使用jdbc操作Oracle,需要有Oracle基础。学习jdbc之前,我们先了解关于Oracle的几个知识点:
-
本机的保留ip为127.0.0.1或者使用localhost可以访问本机
-
每一个软件都是通过一个电脑的端口对外提供服务,而Oracle默认的端口号为1521
-
Oracle的关键字不区分大小写,但是存储的内容区分大小写
话不多说,我们以Oracle自带的emp表进行实验。
实例一:使用jdbc查询emp表中的所有信息并且在控制台打印
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Date;
/**
* @Author Javee
* @Date 2019/8/29 15:21
* @Description 查询Oracle数据库中emp中的所有信息
*/
public class Test1 {
public static void main(String[] args) throws Exception {
//查询所有emp员工信息
//1. 加载orcale驱动类
Class.forName("oracle.jdbc.driver.OracleDriver");
//mysql驱动类 --> com.jdbc.mysql.driver (导入mysql的驱动jar包)
//2. 获取数据库连接对象Connection
//第一个参数:url 数据库的位置 第二个参数:user 为数据库的用户名
//第三个参数:password 为此用户的密码
//jdbc:oracle:thin:@ + 要连接的ip和端口 + : + 数据库名
//jdbc:oracle:thin:@127.0.0.1:1521:orcl
Connection conn = DriverManager.
getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "javee", "123456");
//3. 创建Statement(有安全隐患,sql注入)
//创建PreparedStatement sql语句执行器
String sql = "select * from emp";
PreparedStatement statement = conn.prepareStatement(sql);
//4. 通过statement的方法将查询sql发往数据库执行,查询结果封装到resultset返回
ResultSet rs = statement.executeQuery();
System.out.println("empno --- ename --- job --- mgr --- hiredate --- sal --- comm --- deptno");
while(rs.next()){
int empno = rs.getInt("empno");
String ename = rs.getString("ename");
String job = rs.getString("job");
int mgr = rs.getInt("mgr");
//与数据库时间类型对应的java类型
//父类
//java.util.Date 年月日,时分秒 java程序常用
//子类
//java.sql.Date 年月日
//java.sql.Time 时分秒
//java.sql.Timestamp 年月日,时分秒 与数据库相关使用最多
Date hiredate = rs.getTimestamp("hiredate");
double sal = rs.getDouble("sal");
double comm = rs.getDouble("comm");
int deptno = rs.getInt("deptno");
System.out.println(empno + " --- " + ename + " --- " +
job + " --- " + mgr + " --- " + hiredate + " --- " +
sal + " --- " + comm + " --- " + deptno);
}
//5. 释放资源 按照后开先关的原则
rs.close();
statement.close();
conn.close();
}
}
在这个案例中,有一个难点就是将数据库中的时间格式转换为Java中的时间格式,在代码的注释中我也写到了,Oracle常使用的时间格式在Java中对应的为java.sql.Timestamp,而Java中一般使用的是java.util.Date,而util包中的Date为sql包中Timestamp的父类,所以可以使用Java的特性之一多态来实现,使用父类的引用指向子类的对象,在代码中对应的就是Date hiredate = rs.getTimestamp("hiredate");
实例二:使用占位符?查询Oracle数据库中emp表中的信息
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Date;
/**
* @Author Javee
* @Date 2019/8/29 16:39
* @Description sql占位符?的使用
*/
public class Test3 {
public static void main(String[] args) throws Exception {
int num = 7369;
//1. 加载oracle驱动类
Class.forName("oracle.jdbc.driver.OracleDriver");
//2. 获取数据库连接对象Connection
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl",
"javee", "123456");
//3. 创建PreparedStatement sql语句执行器
String sql = "select * from emp where empno = ?"; //?为占位符
PreparedStatement statement = conn.prepareStatement(sql);
//第1个参数为?的下标,下标从1开始
//第2个参数为传进来的值
statement.setInt(1, num);
//4. 通过statement的方法将查询sql发往数据库执行,查询结果封装到resultset返回
ResultSet rs = statement.executeQuery();
while(rs.next()){
int empno = rs.getInt("empno");
String ename = rs.getString("ename");
String job = rs.getString("job");
int mgr = rs.getInt("mgr");
Date hiredate = rs.getTimestamp("hiredate");
double sal = rs.getDouble("sal");
double comm = rs.getDouble("comm");
int deptno = rs.getInt("deptno");
System.out.println(empno + " --- " + ename + " --- " +
job + " --- " + mgr + " --- " + hiredate + " --- " +
sal + " --- " + comm + " --- " + deptno);
}
//5. 释放资源,按照后开先关的原则
rs.close();
statement.close();
conn.close();
}
}
在这个案例中,有一个难点就是占位符?的使用,在sql语句中,占位符可以有多个,具体使用见下一个栗子,在statement.setInt()中有两个参数,第一个参数为第几个占位符(下标从1开始),第二个参数为传入的值
案例三:使用jdbc对emp表的数据进行删除、增加或者修改
package test;
import java.sql.*;
import java.util.Date;
/**
* @Author Javee
* @Date 2019/8/29 16:39
* @Description 往数据库中增加信息
*/
public class Test5 {
public static void main(String[] args) throws Exception {
//1. 加载oracle驱动类
Class.forName("oracle.jdbc.driver.OracleDriver");
//2. 获取数据库连接对象Connection
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl",
"javee", "123456");
//3. 创建PreparedStatement sql语句执行器
String sql = "insert into emp (empno, ename, job, hiredate) values (?, ?, ?, ?)";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setObject(1, 9999);
statement.setObject(2, "javee");
statement.setObject(3, "ceo");
//转换date类型
Date date = new Date();
long t = date.getTime(); //转换为毫秒数
Timestamp time = new Timestamp(t);
statement.setObject(4, time);
//4. 发送增加 删除 修改的指令
int num = statement.executeUpdate();
System.out.println("受影响行数: " + num);
//5. 释放资源,按照后开先关的原则
statement.close();
conn.close();
}
}
在这个案例中,有两个知识点,第一个就是第四步发送指令的时候,statement.executeUpdate()可以发送增加、删除、修改指令,查询指令使用statement.executeQuery()发送,所以在这个案例中sql语句就不局限于代码中的增加指令了。
第二个知识点就是将Java常用的时间格式(前者)转为数据库的存储格式(后者)进行存储,第一个案例中讲到,前者为后者的父类,我们也知道父类的引用可以接受子类的对象,但是父类不能直接强转为子类的对象。那么问题来了,怎么讲前者转为后者呢?在代码中,我们先将前者使用getTime()转换为long类型数据t,再使用Timestamp的有参构造函数将此long型数据传入,可以转换为Timestamp类型的时间再去存入数据库。