練習1
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 用來管理連接
*/
public class DBUtil {
private static String driverclass="oracle.jdbc.OracleDriver";
private static String url="jdbc:oracle:thin:@172.96.24.252:1521:orcl";
private static String user="jsd1602";
private static String password="jsd1602";
/**
* 1.加載驅動
* 調這個類就是要創建連接,創建連接首先要加載驅動,所以放在靜態塊中
*/
static{
try {
Class.forName(driverclass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("加載驅動錯誤",e);
}
}
/**
* 2.創建連接
* 如何定義一個創建連接的方法
* 返回值類型:看是否有運算結果,若有,結果的類型即爲返回值類型
* 參數列表:功能中是否有不確定的數據參與運算,若有,即爲參數
*/
public static Connection getConnection() throws SQLException{
Connection conn=DriverManager.getConnection(url,user,password);
return conn;
}
/**
* 3.關閉連接
*/
public static void close(Connection conn){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("關閉連接失敗!",e);
}
}
}
//測試該類方法是否可用
public static void main(String[] args) throws SQLException {
System.out.println(getConnection());
}
}
練習2
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
import day01.DBUtil;
/**
* junit測試類
* 可以讓滿足條件的任意方法單獨直接執行
* 條件:
* 1.該方法必須是public的
* 2.返回值類型必須爲void
* 3.無參數
* 4.方法前必須加@Test(註解)
*/
public class TestDay02 {
/**
* 使用PreparedStatement解決注入攻擊的問題
*/
@Test
public void test6(){
//假設用戶輸入的數據如下
String username="admin";
String password="a' or 'b'='b";
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="SELECT * FROM users WHERE username=? and password=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1,username);
ps.setString(2,password);
ResultSet rs=ps.executeQuery();
while(rs.next()){
System.out.println("登錄成功!");
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("查詢用戶失敗!",e);
}finally{
DBUtil.close(con);
}
}
/**
* 演示PreparedStatement的刪除
*/
@Test
public void test5(){
//假設要刪除的員工ID是
int empno=103;
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="DELETE FROM emp WHERE empno=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setInt(1,empno);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("刪除信息失敗!",e);
}finally{
DBUtil.close(con);
}
}
/**
* 演示PreparedStatement的修改
*/
@Test
public void test4(){
//假設要修改的數據是
int empno=103;
String ename="悟空";
String job="保鏢";
int mgr=103;
Date date=new Date(System.currentTimeMillis());
double sal=5000.0;
double comm=0.0;
int deptno=20;
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="UPDATE emp SET ename=?,job=?,mgr=?,hiredate=?,sal=?,comm=?,deptno=? WHERE empno=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1,ename);
ps.setString(2,job);
ps.setInt(3,mgr);
ps.setDate(4,date);
ps.setDouble(5,sal);
ps.setDouble(6,comm);
ps.setInt(7,deptno);
ps.setInt(8,empno);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("修改信息失敗!",e);
}finally{
DBUtil.close(con);
}
}
/**
* 演示PreparedStatement的增加
*/
@Test
public void test3(){
//假設用戶要傳入以下數據
String ename="唐僧";
String job="領導";
int mgr=7839;
Date date=new Date(System.currentTimeMillis());
double sal=4500.0;
double comm=500.0;
int deptno=20;
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="INSERT INTO emp VALUES(seq_emp.nextval,?,?,?,?,?,?,?)";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1,ename);
ps.setString(2,job);
ps.setInt(3,mgr);
ps.setDate(4,date);
ps.setDouble(5,sal);
ps.setDouble(6,comm);
ps.setInt(7,deptno);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("增加員工失敗!",e);
}finally{
DBUtil.close(con);
}
}
/**
* 演示PreparedStatement的查詢
* 查詢工資高於某值的所有員工
*/
@Test
public void test2(){
//假設傳入的工資是
double salary=3000.0;
//創建連接
Connection con=null;
try{
con=DBUtil.getConnection();
String sql="SELECT * FROM emp WHERE sal>=?";
//創建PreparedStatement對象,發送SQL並建立執行計劃
PreparedStatement ps=con.prepareStatement(sql);
//設置參數 ps.set類型(?的索引,?的值)
ps.setDouble(1,salary);
ResultSet rs=ps.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("empno")+","+rs.getString("ename")+","+rs.getInt("sal"));
}
}catch(SQLException e){
e.printStackTrace();
throw new RuntimeException("查詢員工失敗!",e);
}finally{
DBUtil.close(con);
}
}
/**
* 演示根據ID查詢員工
*/
@Test
public void test1(){
//假設傳入的員工ID是
int id=7900;
//加載驅動-創建連接
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="SELECT * FROM emp WHERE empno="+id;
Statement smt=con.createStatement();
//執行查詢 返回結果集
ResultSet rs=smt.executeQuery(sql);
//結果集中封裝了多行數據,需要遍歷
while(rs.next()){
//rs.get類型(字段名)或者rs.get類型(字段索引) 可以查看指定字段信息
System.out.println(rs.getInt("empno"));
System.out.println(rs.getString("ename"));
System.out.println(rs.getString("job"));
}
} catch (SQLException e) {
//1.記錄日誌
e.printStackTrace();
//2.自己能處理則自己處理(如返回默認值)
//3.處理不了則上報(向上拋給調用者)
throw new RuntimeException("查詢員工失敗!",e);
}finally{
//歸還連接
if(con!=null){
DBUtil.close(con);
}
}
}
}
練習3
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import org.junit.Test;
import dao.EmpDao;
import day01.DBUtil;
import entity.Emp;
public class TestDay03 {
/**
* 演示oracle數據庫的真分頁查詢
*/
@Test
public void test5(){
//假設需求要求每頁顯示10條數據
int size=10;
//假設用戶當前點擊了第2頁
int page=2;
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="SELECT * FROM(SELECT e.*,ROWNUM r FROM (SELECT * FROM emp ORDER BY empno) e)WHERE r BETWEEN ? AND ?";
PreparedStatement ps=con.prepareStatement(sql);
//起始行
ps.setInt(1,(page-1)*size+1);
//終止行
ps.setInt(2,page*size);
ResultSet rs=ps.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("empno")+","+rs.getString("ename"));
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("查詢失敗!",e);
}finally{
DBUtil.close(con);
}
}
/**
* 添加部門,然後向此部門內添加一些員工
*/
@Test
public void test4(){
//假設要添加的部門數據如下
String dname="財務部";
String loc="北京";
//假設要添加的員工數據如下
String ename="張三";
String job="經理";
int mgr=0;
double sal=8000.0;
double comm=2000.0;
String ename2="李四";
String job2="職員";
int mgr2=0;
double sal2=5000.0;
double comm2=500.0;
Connection con=null;
try {
con=DBUtil.getConnection();
con.setAutoCommit(false);
//先添加部門
String sql="INSERT INTO depts VALUES(depts_seq.nextval,?,?)";
//參數2是一個數組,存放的是希望被ps記住的字段名
PreparedStatement ps=con.prepareStatement(sql,new String[]{"deptno"});
ps.setString(1,dname);
ps.setString(2,loc);
ps.executeUpdate();
//從ps中獲取它之前記錄的字段的值 返回的結果集中只有一條數據,存的就是記錄的那些字段的值
ResultSet rs=ps.getGeneratedKeys();
rs.next();
int deptno=rs.getInt(1);
//再添加員工1
sql="INSERT INTO emps VALUES(emps_seq.nextval,?,?,?,?,?,?,?)";
ps=con.prepareStatement(sql);
ps.setString(1,ename);
ps.setString(2,job);
ps.setInt(3,mgr);
ps.setDate(4,null);
ps.setDouble(5,sal);
ps.setDouble(6,comm);
ps.setInt(7,deptno);
ps.executeUpdate();
//添加員工2
ps=con.prepareStatement(sql);
ps.setString(1,ename2);
ps.setString(2,job2);
ps.setInt(3,mgr2);
ps.setDate(4,null);
ps.setDouble(5,sal2);
ps.setDouble(6,comm2);
ps.setInt(7,deptno);
ps.executeUpdate();
con.commit();
} catch (SQLException e) {
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
throw new RuntimeException("添加信息失敗!",e);
}finally{
DBUtil.close(con);
}
}
/**
* 演示批量處理數據 添加員工
*/
@Test
public void test3(){
Connection con=null;
try {
con=DBUtil.getConnection();
con.setAutoCommit(false);//取消自動提交 使其控制在一個事務中
//批量處理數據的前提是他們的SQL是一樣的
String sql="INSERT INTO emp values(seq_emp.nextval,?,?,?,?,?,?,?)";
PreparedStatement ps=con.prepareStatement(sql);
for(int i=1;i<=108;i++){
ps.setString(1,"好漢"+i);
ps.setString(2,"劫匪");
ps.setInt(3,0);
ps.setDate(4,null);
ps.setDouble(5,1000.0);
ps.setDouble(6,7000.0);
ps.setInt(7,3);
//將本條數據暫存到ps內
ps.addBatch();
//每隔30次批量發送一次數據
if(i%30==0){
ps.executeBatch();
//清楚緩存的數據
ps.clearBatch();
}
}
//對於餘下的數據單獨發送一次
ps.executeBatch();
con.commit();//手動提交
}catch(SQLException e) {
try {
con.rollback(); //回滾
}catch(SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
throw new RuntimeException("批量添加失敗!",e);
}finally{
DBUtil.close(con);
}
}
/**
* 測試JDBC對事務的控制 演示模擬轉賬
* 1.驗證收款方賬號是否存在(查)
* 2.驗證付款方賬號的餘額是否充足
* 3.付款方賬號-n元
* 4.收款方賬號+n元
*/
@Test
public void test2(){
//假設用戶在ATM上輸入瞭如下信息:
String payID="00001"; //付款賬號
String recID="00002"; //收款賬號
double money=1000.0; //轉賬金額
Connection con=null;
try {
con=DBUtil.getConnection();
//1.驗證收款方賬號是否存在
String sql="SELECT * FROM accounts WHERE id=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1,recID);
ResultSet rs=ps.executeQuery();
if(!rs.next()){
System.out.println("收款賬戶不存在!");
throw new SQLException("收款賬戶不存在!");//拋異常
}
double recMoney=rs.getDouble("money"); //記錄收款方餘額
//2.驗證付款方賬號的餘額是否充足
sql="SELECT * FROM accounts WHERE id=?";
ps=con.prepareStatement(sql);
ps.setString(1,payID);
rs=ps.executeQuery();
rs.next();
double payMoney=rs.getDouble("money");
if(payMoney<money){
System.out.println("賬戶餘額不足!");
throw new SQLException("賬戶餘額不足!");
}
//設置手動管理事務(取消自動提交事務)
con.setAutoCommit(false);
//3.付款方賬號-n元
sql="UPDATE accounts SET money=? WHERE id=?";
ps=con.prepareStatement(sql);
ps.setDouble(1,payMoney-money);
ps.setString(2,payID);
ps.executeUpdate();
//Integer.valueOf("a");
//4.收款方賬號+n元
sql="UPDATE accounts SET money=? WHERE id=?";
ps=con.prepareStatement(sql);
ps.setDouble(1,recMoney+money);
ps.setString(2,recID);
ps.executeUpdate();
//當轉賬流程結束時,統一提交事務
con.commit();
}catch(SQLException e) {
//當轉賬過程發生異常時,回滾事務
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
throw new RuntimeException("回滾失敗!",e);
}
e.printStackTrace();
throw new RuntimeException("轉賬失敗!",e);
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtil.close(con);
}
}
/**
* ResultSetMetaData結果集元數據
*/
@Test
public void test1(){
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="SELECT * FROM emp";
PreparedStatement ps=con.prepareStatement(sql);
ResultSet rs=ps.executeQuery();
//獲取結果集元數據
ResultSetMetaData md=rs.getMetaData();
//元數據中存儲了描述該結果集的信息
System.out.println(md.getColumnCount());
System.out.println(md.getColumnName(1));
System.out.println(md.getColumnClassName(1));//返回的是類型名
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("查詢失敗!",e);
}finally{
DBUtil.close(con);
}
}
}