day01(後端實習技能) JDBC知識學習歸納總結
1、JDBC的簡介
JDBC全稱為java database connectivity,是sun公司指定的java資料庫連線技術的簡稱。
SUN公司提供的一種資料庫訪問規則、規範, 由於資料庫種類較多,並且java語言使用比較廣泛,sun公司就提供了一種規範,讓其他的資料庫提供商去實現底層的訪問規則。 我們的java程式只要使用sun公司提供的jdbc驅動即可。
2、JDBC常用的幾個包
我們需要熟悉包java.sql.*中定義的類(class),介面(interface),例外(expection),並且能夠靈活使用他們,就能夠發揮出JDBC強大的功能。
包java.sql.*中幾個核心的類和介面:
① java.sql.DriverManager用來載入不同資料庫廠商的JDBC驅動,併為建立新的資料庫連線提供支援
② java.sql.Driver指定資料庫的驅動入口,DriverManager將通過該類作為連線資料的引數
③ java.sql.Connection完成針對某指定資料庫的連線功能
④ java.sql.Statement在一個已經建立的連線中,作為SQL語句執行的容器,它有兩個子類:
java.sql.CallableStatement 用於執行資料庫中已經建立好的儲存過程。
java.sql.preparedStatement用於執行預編譯的SQL語句。
⑤ java.sql.ResultSet用於儲存執行特定SQL語句後返回的結果集。
3、JDBC的開發步驟
*註冊驅動(不同的資料庫驅動不一樣,具體問度娘)
Class.forName("com.mysql.jdbc.Driver");
*獲取連線
connection conn = DriverManager.getConnection(url, "root", "123456");
String url="jdbc:mysql://localhost:3306/student?";
此處解釋一下url:jdbc是協議,mysql是子協議,表示資料庫系統管理名稱,ocalhost:3306是你資料庫來源的地址和目標埠,student表示你的資料庫具體的名稱。
*建立statement語句物件
Statement stmt=conn.createStatement();
此處又對statment進行詳細的解釋與說明:
JDBC核心API提供了三種向資料庫傳送SQL語句的類:
Statement:使用createStatement()建立;
PreparedStatement:經過預編譯並存儲在PreparedStatement物件中的SQL語句,使用prepareStatement()方法建立。
CallableStatement:用於執行SQL儲存過程,使用prepareCall()方法建立。
三種不同物件的比較:
第一種:statement
Statement物件用於執行靜態SQL語句和獲得SQL產生的結果。定義了三種執行SQL語句的方法,用來處理返回不同結果的SQL命令:
executeUpdate(String sql):執行SQL INSERT,UPDATE或DELETE 語句,返回受影響行的數目或零;
返回值為int型
executeQuery(String sql):執行返回單個ResultSet的SQL語句;
返回型別ResultSet
execute(String sql):執行可以返回多個結果的SQL語句。
返回型別為boolean,如果返回的是更新的數目,則返回false,如果返回ResultSet,則返回true。
第二種: PreparedStatement語句
PreparedStatement是java.sql包下面的一個介面,用來執行SQL語句查詢,通過呼叫connection.preparedStatement(sql)方法可以獲得PreparedStatment物件。
資料庫系統會對sql語句進行預編譯處理(如果JDBC驅動支援的話),預處理語句將被預先編譯好,這條預編譯的sql查詢語句能在將來的查詢中重用,這樣一來,它比Statement物件生成的查詢速度更快。
PreparedStatement僅僅是預編譯語句。可以使用佔位符。
*執行sql並返還結束
ResultSet rs=stmt.executeQuery(querySql);
4、舉實際例子加深認識
**介紹的是
(1)簡單粗暴的例子:
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Maintest {
public static void main(String[] args) {
//定義全域性變數
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
try {
String querySql = "select * from student";
//註冊驅動
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/student?";
//獲取連線
conn = DriverManager.getConnection(url, "root", "123456");
// 建立statment語句物件
stmt = conn.createStatement();
//執行sql語句
rs = stmt.executeQuery(querySql);
//遍歷rs結果集
while (rs.next()) {
System.out.println("name:" + rs.getString("name") + "年齡:"+rs.getInt("age") +"性別:" +rs.getString("sex"));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//最後需要關閉資源,先判斷是否為空因為有可能資源未開啟,這時候會報空指標異常;不為空時候則需要關閉資源,不關閉則造成記憶體的浪費
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
(2)下面這個例子對註冊驅動和獲取連線進行簡單優化:
因為每個程式獲取連線和註冊驅動都一個樣,所以可以抽取出來作為工具類使用
抽取出來的類:
package utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Conectionfactory {
public static Connection Connection(String user, String pass) {
Connection conn = null;// 宣告連線物件
String driver = "com.mysql.jdbc.Driver";// 驅動程式類名
String url = "jdbc:mysql://localhost:3306/student?" // 資料庫URL
+ "useUnicode=true&characterEncoding=UTF8";// 防止亂碼
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, pass);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
// 關閉資料庫連線
public static void closeConnection(Connection con, Statement stmt, ResultSet rs) throws SQLException {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (con != null) {
con.close();
}
} }
呼叫這個類:
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import utils.Conectionfactory;
public class Maintest3 {
public static void main(String[] args) {
ResultSet rs=null;
Statement stmt=null;
Connection conn=null;
try{
//直接就呼叫工具類實現獲取連線
conn=Conectionfactory.Connection("root", "123456");
stmt=conn.createStatement();
String querySql="select * from student";
rs=stmt.executeQuery(querySql);
while(rs.next())
{
System.out.println("人員編號:"+rs.getString("name")+"工資:"+rs.getInt("age")+"姓名:"+rs.getInt("sex"));//使用getString()方法獲取你表裡的資料名
}
}catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try {
//呼叫連線關閉資源
Conectionfactory.closeConnection(conn, stmt, rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
}
(3)在工具類的前提下,繼續優化工具類。
此處,我們需要達到的目的是工具類自動載入”註冊驅動,載入連線“
此處,需要一個配置檔案(配置檔案需要放在src目錄下)
jdbc
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/student
name=root
password=123456
JDBCUtil工具類
package utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtil {
static String driverClass = null;
static String url = null;
static String name = null;
static String password= null;
static{
try {
//1. 建立一個屬性配置物件
Properties properties = new Properties();
// InputStream is = new FileInputStream("jdbc.properties");
//使用類載入器,去讀取src底下的資原始檔。 後面在servlet
InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
//匯入輸入流。
properties.load(is);
//讀取屬性
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
name = properties.getProperty("name");
password = properties.getProperty("password");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲取連線物件
* @return
*/
public static Connection getConn(){
Connection conn = null;
try {
Class.forName(driverClass);
//靜態程式碼塊 ---> 類載入了,就執行。 java.sql.DriverManager.registerDriver(new Driver());
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
//2. 建立連線 引數一: 協議 + 訪問的資料庫 , 引數二: 使用者名稱 , 引數三: 密碼。
conn = DriverManager.getConnection(url, name, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* 釋放資源
* @param conn
* @param st
* @param rs
*/
public static void release(Connection conn , Statement st , ResultSet rs){
closeRs(rs);
closeSt(st);
closeConn(conn);
}
private static void closeRs(ResultSet rs){
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}
private static void closeSt(Statement st){
try {
if(st != null){
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
st = null;
}
}
private static void closeConn(Connection conn){
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
} }
測試程式碼:
package test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import utils.JDBCUtil;
public class tes {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
//1. 註冊驅動
conn = JDBCUtil.getConn();
//3. 建立statement , 跟資料庫打交道,一定需要這個物件
st = conn.createStatement();
//4. 執行查詢 , 得到結果集
String sql = "select * from student";
rs = st.executeQuery(sql);
//5. 遍歷查詢每一條記錄
while(rs.next()){
System.out.println("人員編號:"+rs.getString("name")+"工資:"+rs.getInt("age")+"姓名:"+rs.getInt("sex"));//使用getString()方法獲取你表裡的資料名
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtil.release(conn, st, rs);
}
}
}
PS:如果不註冊驅動也行,原始碼好像說會”自動載入驅動“
接著的例子是增刪改查:
在原來的測試類和工具類的基礎上,在測試類變動一下:
增加的例子
//3. 執行新增
String sql = "insert into student values('ljq' , 18 , 19)";
//影響的行數, ,如果大於0 表明操作成功。 否則失敗
int result = st.executeUpdate(sql);
if(result >0 ){
System.out.println("新增成功");
}else{
System.out.println("新增失敗");
}
刪除的例子
//4. 執行刪除
String sql = "delete from student where name='ljq'";
//影響的行數, ,如果大於0 表明操作成功。 否則失敗
int result = st.executeUpdate(sql);
if(result >0 ){
System.out.println("刪除成功");
}else{
System.out.println("刪除失敗");
}
Statement的安全問題:前面先拼接sql語句, 如果變數裡面帶有了 資料庫的關鍵字,那麼一併認為是關鍵字。 不認為是普通的字串。
所以,接下來我介紹一下 PrepareStatement。
相比較以前的statement, 預先處理給定的sql語句,對其執行語法檢查。 在sql語句裡面使用 ? 佔位符來替代後續要傳遞進來的變數。 後面進來的變數值,將會被看成是字串,不會產生任何的關鍵字。
String sql = "select * from student where name=? and age=?";
ps = conn.prepareStatement(sql);
//給佔位符賦值 從左到右數過來,1 代表第一個問號, 永遠你是1開始。
ps.setString(1, "meici");
ps.setInt(2, 11);
rs = ps.executeQuery();
while(rs.next())
{
System.out.println("人員編號:"+rs.getString("name")+"工資:"+rs.getInt("age")+"姓名:"+rs.getInt("sex"));
}
JDBC的大概知識點就是這些,有更新的會繼續加進去!!!