JDBC簡介
JDBC(Java DataBase Connectivity,java數據庫連接)是一種用於執行SQL語句的Java API,可以爲多種關係數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基準,據此可以構建更高級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序。
JDBC可以在各種平臺上使用Java,如Windows,Mac OS和各種版本的UNIX。
JDBC體系結構
JDBC API支持用於數據庫訪問的兩層和三層處理模型,但通常,JDBC體系結構由兩層組成:
- JDBC: 提供了應用程序到數據庫連接規範。
- JDBC驅動程序: 連接數據庫的驅動程序的實現。
JDBC API使用驅動程序管理器和特定於數據庫的驅動程序來提供與異構數據庫的透明連接。
JDBC核心組件
DriverManager: 此類管理數據庫驅動程序列表。使用通信協議將來自java應用程序的連接請求與適當的數據庫驅動程序匹配。
Driver:此接口處理與數據庫服務器的通信,我們很少會直接與Driver對象進行交互。而是使用DriverManager對象來管理這種類型的對象。
Connection: 該接口具有用於連接數據庫的所有方法。連接對象表示通信上下文,數據庫的所有通信僅通過連接對象。
Statement:使用從此接口創建的對象將SQL語句提交到數據庫。除了執行存儲過程之外,一些派生接口還接受參數。
ResultSet: 在使用Statement對象執行SQL查詢後,這些對象保存從數據庫檢索的數據。它作爲一個迭代器,允許我們移動其數據。
SQLException: 此類處理數據庫應用程序中發生的任何異常。
JDBC使用步驟
構建JDBC應用程序涉及以下六個步驟:
- 導入JDBC驅動包: 需要下載包含數據庫編程所需的JDBC的jar包。
- *註冊JDBC驅動程序: *要求您初始化驅動程序,以便您可以打開與數據庫的通信通道。
- 創建連接: 需要使用
DriverManager.getConnection()
方法創建一個Connection對象,該對象表示與數據庫的物理連接。 - 執行查詢: 需要使用類型爲Statement的對象來構建和提交SQL語句到數據庫。
- 從結果集中提取數據: 需要使用相應的
ResultSet.getXXX()
方法從結果集中檢索數據。 - 釋放資源: 需要明確地關閉所有數據庫資源,而不依賴於JVM的垃圾收集。
代碼示例1:
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcDemo1 {
public static void main(String[] args) {
//1、加載驅動
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//2、創建連接
//String url = "jdbc:mysql://localhost:3306/db_test";//不安全警告,需要將ssl禁用顯示出來useSSL=false
String url = "jdbc:mysql://localhost:3306/db_test?useSSL=false&characterEncoding=utf8";
try {
//url、數據庫用戶名和密碼,有返回值表示連接成功
Connection conn = DriverManager.getConnection(url, "root", "123456");
if(conn!=null){
System.out.println("連接成功!");
}
//3、關閉連接
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
代碼示例2:
package jdbc;
import java.sql.*;
import java.util.Scanner;
public class JdbcDemo2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("請輸入賬號");
String username = input.nextLine();
System.out.println("請輸入密碼");
String password = input.nextLine();
//1、註冊驅動
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//2、創建連接
String url = "jdbc:mysql://localhost:3306/db_test?useSSL=false&characterEncoding=utf8";
try {
Connection conn = DriverManager.getConnection(url, "root", "123456");
//3、使用命令
PreparedStatement pstat = conn.prepareStatement("SELECT * FROM USER WHERE username=? AND password=?");
pstat.setString(1,username);
pstat.setString(2,password);
ResultSet rs = pstat.executeQuery();
//Statement stat = conn.createStatement();
//4、執行命令
//int result = stat.executeUpdate("insert into student values(1,'jack')");//返回受影響的行數
//ResultSet rs = stat.executeQuery("SELECT * FROM USER WHERE username='"+username+"' AND password='"+password+"'");
//admin' or 1=1# 此處sql注入危險,應防止注入
if(rs.next()){
System.out.println("登錄成功!");
}else{
System.out.println("登錄失敗!");
}
//5、關閉連接
pstat.close();
conn.close();
System.out.println("執行成功!");
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("執行失敗");
}
}
}
DAO設計模式
DAO(Database Access Object 數據庫訪問對象)
爲了降低耦合性,提出了DAO封裝數據庫操作的設計模式。
它可以實現業務邏輯與數據庫訪問相分離。相對來說,數據庫是比較穩定的,其中DAO組件依賴於數據庫系統,提供數據庫訪問的接口,隔離了不同的數據庫實現。
DAO模式的組成部分
1、DAO接口(主要有添加 修改 查詢 刪除方法)
2、DAO實現類
3、實體類 (domain(領域)、beans、entity、pojo、model)
PO (VO)(Persistent Object, Value Object)
VO (View Object)
DTO (Data Transfer Object)
--作用:用在數據訪問代碼和業務邏輯代碼之間通過實體類來傳輸數據
--實體類特徵:
◦屬性一般使用private修飾
◦提供public修飾的getter/setter方法
◦實體類提供無參構造方法,根據業務提供有參構造
◦實現java.io.Serializable接口,支持序列化機制
4、數據庫連接和關閉工具類
設計的包名 :
domain 存放實體類
utils 存放工具類
dao 存放接口
dao.impl 存放實現類
示例:
測試類:
package jdbcdao.test;
import jdbcdao.dao.Userdao;
import jdbcdao.dao.impl.UserdaoImpl;
import jdbcdao.domain.User;
import org.junit.Test;
import java.util.List;
public class UserdaoTest {
@Test
public void testFindAll(){
Userdao userdao = new UserdaoImpl();
List<User> list = userdao.findAll();
for (User s:list){
System.out.println(s.toString());
}
}
}
接口:Userdao
package jdbcdao.dao;
import jdbcdao.domain.User;
import java.util.List;
public interface Userdao {
List<User> findAll();
}
實現類:UserdaoImpl
package jdbcdao.dao.impl;
import jdbcdao.dao.Userdao;
import jdbcdao.domain.User;
import jdbcdao.utils.DbUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class UserdaoImpl implements Userdao {
@Override
public List<User> findAll() {
List<User> list = new ArrayList<>();
Connection conn = DbUtils.getConnection();
PreparedStatement pstat=null;
ResultSet rs=null;
try {
pstat = conn.prepareStatement("select * from student");
rs = pstat.executeQuery();
while (rs.next()){
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
String eamil = rs.getString("eamil");
User user = new User(id,username,password,eamil);
list.add(user);
}
return list;
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DbUtils.closeAll(conn,pstat,rs);
}
return null;
}
}
實體類:User
package jdbcdao.domain;
public class User {
private int id;
private String username;
private String password;
private String eamil;
public User() {
}
public User(int id, String username, String password, String eamil) {
this.id = id;
this.username = username;
this.password = password;
this.eamil = eamil;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEamil() {
return eamil;
}
public void setEamil(String eamil) {
this.eamil = eamil;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", eamil='" + eamil + '\'' +
'}';
}
}
工具類:
package jdbcdao.utils;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class DbUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
static {
// driver="com.mysql.jdbc.Driver";
// url= "jdbc:mysql://localhost:3306/db_test?useSSL=false&characterEncoding=utf8";
// username= "root";
// password="123456";
Properties prop = new Properties();
InputStream in = DbUtils.class.getClassLoader().getResourceAsStream("db.properties");
//註冊驅動
try {
prop.load(in);
driver = prop.getProperty("driver");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
System.out.println("註冊驅動失敗");
}
}
//創建連接
public static Connection getConnection(){
try {
return DriverManager.getConnection(url,username,password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
public static void closeAll(Connection conn, Statement stat,ResultSet resultSet){
try {
if (conn != null) {
conn.close();
}
if (stat != null) {
stat.close();
}
if (resultSet != null) {
resultSet.close();
}
}catch (SQLException e) {
e.printStackTrace();
}
}
public static int executeUpdate(String sql,Object... params){
Connection conn=null;
PreparedStatement pstat = null;
try {
//創建連接
conn = getConnection();
//執行命令
pstat = conn.prepareStatement(sql);
if(params!=null){
for (int i = 0; i <params.length ; i++) {
pstat.setObject(i+1,params[i]);
}
}
//返回受影響的行
return pstat.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
return -1;
}
}
配置文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_test?useSSL=false&characterEncoding=utf8
username=root
password=123456