深入了解JDBC的使用
一、JDBC描述
JDBC(Java DataBase Connectivity)是Java和資料庫之間的一個橋梁,是一個規範而不是一個實作,能夠執行SQL語句。它由一組用Java語言編寫的類和接口組成。各種不同類型的資料庫都有相應的實作。
二、JDBC架構分類
雙層:
作用:此架構中,Java Applet 或應用直接通路資料源。
條件:要求 Driver 能與通路的資料庫互動。
機制:使用者指令傳給資料庫或其他資料源,随之結果被傳回。
部署:資料源可以在另一台機器上,使用者通過網絡連接配接,稱為 C/S配置(可以是内聯網或網際網路)。
三層:
側架構特殊之處在于,引入中間層服務。
流程:指令和結構都會經過該層。
吸引:可以增加企業資料的通路控制,以及多種類型的更新;另外,也可簡化應用的部署,并在多數情況下有性能優勢。
曆史趨勢: 以往,因性能問題,中間層都用 C 或 C++ 編寫,随着優化編譯器(将 Java 位元組碼 轉為 高效的 特定機器碼)和技術的發展,如EJB,Java 開始用于中間層的開發這也讓 Java 的優勢突顯出現出來,使用 Java 作為伺服器代碼語言,JDBC随之被重視。
三、JDBC程式設計步驟
(1)加載驅動程式
Class.forName(driverClass)
//加載MySql驅動
Class.forName("com.mysql.jdbc.Driver")
//加載Oracle驅動
Class.forName("oracle.jdbc.driver.OracleDriver")
(2)獲得資料庫連接配接
(3)建立Statement\PreparedStatement對象
conn.createStatement();
conn.prepareStatement(sql);
四、JDBC增删改查執行個體
JDBC連接配接工具類:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DbUtil {
public static final String URL = "jdbc:mysql://localhost:3306/imooc";
public static final String USER = "root";
public static final String PASSWORD = "123";
private static Connection conn = null;
static{
try {
//1.加載驅動程式
Class.forName("com.mysql.jdbc.Driver");
//2. 獲得資料庫連接配接
conn = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
return conn;
}
//關閉Connection
public static void close(Connection conn){
//避免出現空指針異常
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
//關閉Statement或PreparedStatement
public static void close(PreparedStatement pstmt){
//避免出現空指針異常
if(pstmt != null){
try{
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
//關閉ResultSet
public static void close(ResultSet rs){
//避免出現空指針異常
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
Model層:
package lanshen.model;
import java.util.Date;
public class Goddess {
private Integer id;
private String user_name;
private Integer sex;
private Integer age;
private Date birthday; //注意用的是java.util.Date
private String email;
private String mobile;
private String create_user;
private String update_user;
private Date create_date;
private Date update_date;
private Integer isDel;
//getter setter方法。。。
}
Dao層:
package lanshen.dao;
import lanshen.db.DbUtil;
import lanshen.model.Goddess;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class GoddessDao {
//增加
public void addGoddess(Goddess g) throws SQLException {
//和資料庫取得連接配接
Connection conn = null;
//建立statement
PreparedStatement pstmt = null;
//sql
String sql = "INSERT INTO imooc_goddess(user_name, sex, age, birthday, email, mobile,"+
"create_user, create_date, update_user, update_date, isdel)"
+"values("+"?,?,?,?,?,?,?,CURRENT_DATE(),?,CURRENT_DATE(),?)";
try{
//擷取連接配接
conn = DbUtil.getConnection();
//預編譯
pstmt = (PreparedStatement) conn.prepareStatement(sql);
//傳參
ptmt.setString(1, g.getUser_name());
ptmt.setInt(2, g.getSex());
ptmt.setInt(3, g.getAge());
ptmt.setDate(4, new Date(g.getBirthday().getTime()));
ptmt.setString(5, g.getEmail());
ptmt.setString(6, g.getMobile());
ptmt.setString(7, g.getCreate_user());
ptmt.setString(8, g.getUpdate_user());
ptmt.setInt(9, g.getIsDel());
//執行
ptmt.execute();
}catch(SQLException e){
e.printStackTrace();
}
finally{
DbUtil.close(pstmt);
DbUtil.close(conn); //必須關閉
}
}
//修改
public void updateGoddess(){
//和資料庫取得連接配接
Connection conn = null;
//建立statement
PreparedStatement pstmt = null;
//sql, 每行加空格
String sql = "UPDATE imooc_goddess" +
" set user_name=?, sex=?, age=?, birthday=?, email=?, mobile=?,"+
" update_user=?, update_date=CURRENT_DATE(), isdel=? "+
" where id=?";
try{
//擷取連接配接
conn = DbUtil.getConnection();
//預編譯
pstmt = (PreparedStatement) conn.prepareStatement(sql);
//傳參
ptmt.setString(1, g.getUser_name());
ptmt.setInt(2, g.getSex());
ptmt.setInt(3, g.getAge());
ptmt.setDate(4, new Date(g.getBirthday().getTime()));
ptmt.setString(5, g.getEmail());
ptmt.setString(6, g.getMobile());
ptmt.setString(7, g.getUpdate_user());
ptmt.setInt(8, g.getIsDel());
ptmt.setInt(9, g.getId());
//執行
ptmt.execute();
}catch(SQLException e){
e.printStackTrace();
}
finally{
DbUtil.close(pstmt);
DbUtil.close(conn); //必須關閉
}
}
//删除
public void delGoddess(){
//和資料庫取得連接配接
Connection conn = null;
//建立statement
PreparedStatement pstmt = null;
//sql, 每行加空格
String sql = "delete from imooc_goddess where id=?";
try{
//擷取連接配接
conn = DbUtil.getConnection();
//預編譯
pstmt = (PreparedStatement) conn.prepareStatement(sql);
//傳參
ptmt.setInt(1, id);
//執行
ptmt.execute();
}catch(SQLException e){
e.printStackTrace();
}
finally{
DbUtil.close(pstmt);
DbUtil.close(conn); //必須關閉
}
}
//查詢,查詢指定字段
public List<Goddess> query() throws SQLException {
//和資料庫取得連接配接
Connection conn = null;
//建立statement
Statement stmt = null;
//建立結果集
ResultSet rs = null;
//sql, 每行加空格
String sql = "SELECT user_name, age FROM imooc_goddess";
try{
//擷取連接配接
conn = DbUtil.getConnection();
//預編譯
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
//執行
List<Goddess> gs = new ArrayList<Goddess>();
Goddess g = null;
while(rs.next()){
g = new Goddess();
g.setUser_name(rs.getString("user_name"));
g.setAge(rs.getInt("age"));
gs.add(g);
}
return gs;
}catch(SQLException e){
e.printStackTrace();
}
finally{
DbUtil.close(pstmt);
DbUtil.close(conn); //必須關閉
}
}
//查詢,查詢所有
public Goddess get(){
//和資料庫取得連接配接
Connection conn = null;
//建立statement
Statement stmt = null;
//建立結果集
ResultSet rs = null;
//sql, 每行加空格
String sql = "select * from imooc_goddess where id=?";
Goddess g = null;
try{
//擷取連接配接
conn = DbUtil.getConnection();
//預編譯
pstmt = (PreparedStatement) conn.prepareStatement(sql);
//傳參
ptmt.setInt(1, id);
//執行
ResultSet rs = ptmt.executeQuery();
while(rs.next()){
g = new Goddess();
g.setId(rs.getInt("id"));
g.setUser_name(rs.getString("user_name"));
g.setAge(rs.getInt("age"));
g.setSex(rs.getInt("sex"));
g.setBirthday(rs.getDate("birthday"));
g.setEmail(rs.getString("email"));
g.setMobile(rs.getString("mobile"));
g.setCreate_date(rs.getDate("create_date"));
g.setCreate_user(rs.getString("create_user"));
g.setUpdate_date(rs.getDate("update_date"));
g.setUpdate_user(rs.getString("update_user"));
g.setIsDel(rs.getInt("isdel"));
}
return g;
}catch(SQLException e){
e.printStackTrace();
}
finally{
DbUtil.close(pstmt);
DbUtil.close(conn); //必須關閉
}
}
五、Statement和PreparedStatement的異同及優缺點:
同:兩者都是用來執SQL語句的。
異:PreparedStatement需要根據SQL語句來建立,它能夠通過設定參數,指定相應的值,不是像Statement那樣使用字元串拼接的方式。
PreparedStatement的優點:
(1)其使用參數設定,可讀性好,不易記錯。在statement中使用字元串拼接,可讀性和維護性比較差。
(2)其具有預編譯機制,性能比statement更快。
(3)其能夠有效防止SQL注入攻擊。
六、execute和executeUpdate的差別:
相同點:
二者都能夠執行增加、删除、修改等操作。
不同點:
execute可以執行查詢語句,然後通過getResult把結果取出來。executeUpdate不能執行查詢語句。
execute傳回Boolean類型,true表示執行的是查詢語句,false表示執行的insert、delete、update等。executeUpdate的傳回值是int,表示有多少條資料受到了影響。