java技术_JAVA-JDBC技术
1 什么是 JDBC
? JDBC(Java DataBase Connectivity)java 數據庫連接
? 是 JavaEE 平臺下的技術規范
? 定義了在 Java 語言中連接數據,執行 SQL 語句的標準
? 可以為多種關系數據庫提供統一訪問
2 什么是數據庫驅動程序
? 數據庫廠商對 JDBC 規范的具體實現
? 不同數據產品的數據庫驅動名字有差異
? 在程序中需要依賴數據庫驅動來完成對數據庫的操作
3 程序操作數據庫流程
二、 JDBC3.0 標準中常用接口與類
1 Driver 接口
Driver 接口的作用是來定義數據庫驅動對象應該具備的一些能力。比如與數據庫建立連
接的方法的定義所有支持 java 語言連接的數據庫都實現了該接口,實現該接口的類我們稱
之為數據庫驅動類。在程序中要連接數據庫,必須先通過 JDK 的反射機制加載數據庫驅動
類,將其實例化。不同的數據庫驅動類的類名有區別。
加載 MySql 驅動:Class.forName("com.mysql.jdbc.Driver");
加載 Oracle 驅動:Class.forName("oracle.jdbc.driver.OracleDriver");
2 DriverManager 類
DriverManager 通過實例化的數據庫驅動對象,能夠建立應用程序與數據庫之間建立連
接。并返回 Connection 接口類型的數據庫連接對象。
2.1常用方法
? getConnection(String jdbcUrl, String user, String password)
該方法通過訪問數據庫的 url、用戶以及密碼,返回對應的數據庫的 Connection 對象。
2.2JDBC URL
與數據庫連接時,用來連接到指定數據庫標識符。在 URL 中包括了該數據庫的類型、
地址、端口、庫名稱等信息。不同品牌數據庫的連接 URL 不同。
3 Connection 接口
Connection 與數據庫的連接(會話)對象。我們可以通過該對象執行 sql 語句并返回結
果。
連接 MySql 數據庫:
Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user",
"password");
連接 Oracle 數據庫:
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database",
"user", "password");
連接 SqlServer 數據庫:
Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port;
DatabaseName=database", "user", "password");
3.1常用方法
? createStatement():創建向數據庫發送 sql 的 Statement 接口類型的對象。
? preparedStatement(sql) :創建向數據庫發送預編譯 sql 的 PrepareSatement 接口類型的
對象。
? prepareCall(sql):創建執行存儲過程的 CallableStatement 接口類型的對象。
? setAutoCommit(boolean autoCommit):設置事務是否自動提交。
? commit() :在鏈接上提交事務。
? rollback() :在此鏈接上回滾事務。
4 Statement 接口
用于執行靜態 SQL 語句并返回它所生成結果的對象。
由 createStatement 創建,用于發送簡單的 SQL 語句(不支持動態綁定)。
4.1常用方法
? execute(String sql):執行參數中的 SQL,返回是否有結果集。
? executeQuery(String sql):運行 select 語句,返回 ResultSet 結果集。
? executeUpdate(String sql):運行 insert/update/delete 操作,返回更新的行數。
? addBatch(String sql) :把多條 sql 語句放到一個批處理中。
? executeBatch():向數據庫發送一批 sql 語句執行。
5 PreparedStatement 接口
繼承自 Statement 接口,由 preparedStatement 創建,用于發送含有一個或多個參數的 SQL
語句。PreparedStatement 對象比 Statement 對象的效率更高,并且可以防止 SQL 注入,所以
我們一般都使用 PreparedStatement。
5.1常用方法
? addBatch()把當前 sql 語句加入到一個批處理中。
? execute() 執行當前 SQL,返回個 boolean 值
? executeUpdate()運行 insert/update/delete 操作,返回更新的行數。
? executeQuery() 執行當前的查詢,返回一個結果集對象
? setDate(int parameterIndex, Date x)向當前 SQL 語句中的指定位置綁定一個 java.sql.Date
值。
? setDouble(int parameterIndex, double x)向當前 SQL 語句中的指定位置綁定一個 double
值
? setFloat(int parameterIndex, float x)向當前 SQL 語句中的指定位置綁定一個 float 值
? setInt(int parameterIndex, int x)向當前 SQL 語句中的指定位置綁定一個 int 值
? setString(int parameterIndex, String x)向當前 SQL 語句中的指定位置綁定一個 String 值
6 ResultSet 接口
ResultSet 提供檢索不同類型字段的方法。
6.1常用方法
? getString(int index)、getString(String columnName)
獲得在數據庫里是 varchar、char 等類型的數據對象。
? getFloat(int index)、getFloat(String columnName)
獲得在數據庫里是 Float 類型的數據對象。
? getDate(int index)、getDate(String columnName)
獲得在數據庫里是 Date 類型的數據。
? getBoolean(int index)、getBoolean(String columnName)
獲得在數據庫里是 Boolean 類型的數據。
? getObject(int index)、getObject(String columnName)
獲取在數據庫里任意類型的數據。
6.2ResultSet 對結果集進行滾動的方法
? next():移動到下一行。
? Previous():移動到前一行。
? absolute(int row):移動到指定行。
? beforeFirst():移動 resultSet 的最前面。
? afterLast() :移動到 resultSet 的最后面。
7 CallableStatement 接口
繼承自 PreparedStatement 接口,由方法 prepareCall 創建,用于調用數據庫的存儲過程。
三、 JDBC 的使用
加 載 數 據 庫 驅 動 程 序 → 建 立 數 據 庫 連 接 Connection → 創 建 執 行 SQL 的 語 句
Statement → 處理執行結果 ResultSet → 釋放資源
1 下載數據庫驅動
1.1MySQL 驅動
Download Connector/J
1.2Oracle 驅動
數據庫安裝目錄oracleproduct11.2.0dbhome_1jdbclib
2 創建項目添加驅動
3 通過 Statement 向表中插入數據
3.1注冊驅動
Class.forName("com.mysql.jdbc.Driver");
3.2獲取連接
Connection conn
=DriverManager.getConnection("jdbc:mysql://localhost:
3306/bjsxt?useUnicode=true&characterEncoding=utf-8",
"root", "root");
3.3執行 SQL
String sql="insert into departments
values(default,'"+department_name+"'"+location_id+")"
;
Statement state = conn.createStatement();
3.4釋放資源
if(state != null){
try {
state.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
4 通過 Statement 對象修改表中的數據
4.1代碼
//更新 departments 表中的 department_id 為 6 的數據,將
部門名稱修改為教學部,location_id 修改為 6
public void updateDempartments(String
department_name,int location_id,int department_id){
Connection conn = null;
Statement state = null;
try{
Class.forName("com.mysql.jdbc.Driver");
conn
=DriverManager.getConnection("jdbc:mysql://localhost:
3306/bjsxt?useUnicode=true&characterEncoding=utf-8",
"root", "root");
state = conn.createStatement();
String sql = "update departments d set
d.department_name = '"+department_name+"',d.location_id
= "+location_id+" where d.department_id
="+department_id;
int flag = state.executeUpdate(sql);
System.out.println(flag);
}catch(Exception e){
e.printStackTrace();
}finally{
if(state != null){
try {
state.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
5 封裝 JDBC 工具類
5.1普通版
5.1.1工具類代碼
/**
* jdbc 工具類
* @author Administrator
*
*/
public class JdbcUtil {
private static String driver =
"com.mysql.jdbc.Driver";
private static String
jdbcUrl="jdbc:mysql://localhost:3306/bjsxt?useUnicode
=true&characterEncoding=utf-8";
private static String username ="root";
private static String userpassword="root";
static{
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//獲取 Connection 對象
public static Connection getConnection(){
Connection conn = null;
try {
conn = DriverManager.getConnection(jdbcUrl,
username, userpassword);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
//關閉 Statement
public static void closeStatement(Statement
state){
try {
if(state != null){
state.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//關閉 Connection
public static void closeConnection(Connection
conn){
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//關閉資源
public static void closeResource(Statement
state,Connection conn){
closeStatement(state);
closeConnection(conn);
}
}
5.2升級版
5.2.1工模具類代碼
/**
* jdbc 工具類
* @author Administrator
*
*/
public class JdbcUtil {
private static String driver;
private static String jdbcUrl;
private static String username;
private static String userpassword;
static{
//讀取 Properties 文件
ResourceBundle bundle =
ResourceBundle.getBundle("jdbc");
driver = bundle.getString("driver");
jdbcUrl= bundle.getString("jdbcUrl");
username = bundle.getString("username");
userpassword =
bundle.getString("userpassword");
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//獲取 Connection 對象
public static Connection getConnection(){
Connection conn = null;
try {
conn = DriverManager.getConnection(jdbcUrl,
username, userpassword);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
//關閉 Statement
public static void closeStatement(Statement
state){
try {
if(state != null){
state.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//關閉 Connection
public static void closeConnection(Connection
conn){
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//關閉資源
public static void closeResource(Statement
state,Connection conn){
closeStatement(state);
closeConnection(conn);
}
}
6 通過 Statement 對象查詢數據
6.1代碼
//查詢 Departmetns 表中部門 ID 為 6 的部門信息
public void selectDepartmentsById(int
departmentId){
Connection conn = null;
Statement state = null;
ResultSet rs = null;
try{
conn= JdbcUtil.getConnection();
state = conn.createStatement();
String sql = "select * from departments d where
d.department_id = "+departmentId;
//執行查詢返回結果
rs=state.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getInt("department_id")+"
"+rs.getString("department_name")+" "+rs.getInt(3));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(state, conn,rs);
}
}
7 ResultSet 講解
注意 ResultSet 中封裝的并不是我們查詢到的所有的結果集,而是返回了查詢到的結果
集的數據庫游標。通過 ResultSet 中的 next()方法操作游標的位置獲取結果集。
8 通過 ResultSet 實現邏輯分頁
8.1代碼
//查詢 departments 表中的所有的數據,并且通過 ResultSet 實現邏輯分
頁
public void selectDeptPage(int currentPage,int pageRows){
Connection conn = null;
Statement state = null;
ResultSet rs = null;
try{
conn = JdbcUtil.getConnection();
state = conn.createStatement();
String sql = "select * from departments";
rs = state.executeQuery(sql);
//開始位置與結束位置
int begin = (currentPage -1)*pageRows;
int end = currentPage * pageRows;
//當前位置的計數器
int currentNum = 0;
while(rs.next()){
//什么情況下獲取結果集中的數據
if(currentNum >= begin && currentNum < end){
System.out.println(rs.getInt("department_id")+"
"+rs.getString("department_name"));
//結束操作 ResultSet 的邊界條件
if(currentNum == end -1){
break;
}
}
currentNum++;
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(state, conn, rs);
}
}
9 SQL 注入問題
9.1什么是 SQL 注入
所謂 SQL 注入,就是通過把含有 SQL 語句片段的參數插入到需要執行的 SQL 語句中,
最終達到欺騙數據庫服務器執行惡意操作的 SQL 命令。
9.2SQL 注入案例
//sql 注入
public void sqlInject(String departmentName,int
locationId){
Connection conn = null;
Statement state = null;
ResultSet rs = null;
try{
conn = JdbcUtil.getConnection();
state = conn.createStatement();
String sql = "select * from departments where
department_name ='"+departmentName+"' and location_id =
"+locationId;
System.out.println(sql);
rs = state.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getInt("department_id")+"
"+rs.getString("department_name")+"
"+rs.getInt("location_id"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(state, conn, rs);
}
}
10 PreparedStatement 對象的使用(重點)
10.1PreparedStatement 特點:
? PreparedStatement 接口繼承 Statement 接口
? PreparedStatement 效率高于 Statement
? PreparedStatement 支持動態綁定參數
? PreparedStatement 具備 SQL 語句預編譯能力
? 使用 PreparedStatement 可防止出現 SQL 注入問題
10.2通過 PreparedStatement 對象向表中插入數據
10.2.1 代碼
//向 Departments 表中插入一條數據
public void insertDempartments(String departmentName,int
locationId){
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("insert into departments
values(default,?,?)");
ps.setString(1, departmentName);
ps.setInt(2, locationId);
ps.execute();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
11 PreparedStatement 的預編譯能力
11.1什么是預編譯
11.1.1 SQL 語句的執行步驟
? 語法和語義解析
? 優化 sql 語句,制定執行計劃
? 執行并返回結果
但是很多情況,我們的一條 sql 語句可能會反復執行,或者每次執行的時候只有個別的
值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。
如果每次都需要經過上面的詞法語義解析、語句優化、制定執行計劃等,則效率就明顯不行
了。
所謂預編譯語句就是將這類語句中的值用占位符替代,可以視為將 sql 語句模板化或者
說參數化
預編譯語句的優勢在于:一次編譯、多次運行,省去了解析優化等過程;此外預編譯語
句能防止 sql 注入
11.1.2 解析過程
11.1.2.1 硬解析
在不開啟緩存執行計劃的情況下,每次 SQL 的處理都要經過:語法和語義的解析,優
化器處理 SQL,生成執行計劃。整個過程我們稱之為硬解析。
11.1.2.2 軟解析
如果開啟了緩存執行計劃,數據庫在處理 sql 時會先查詢緩存中是否含有與當前 SQL
語句相同的執行計劃,如果有則直接執行該計劃。
11.2預編譯方式
開始數據庫的日志
show VARIABLES like '%general_log%'
set GLOBAL general_log = on
set GLOBAL log_output='table'
11.2.1 依賴數據庫驅動完成預編譯
如果我們沒有開啟數據庫服務端編譯,那么默認的是使用數據庫驅動完成 SQL 的預編
譯處理。
11.2.2 依賴數據庫服務器完成預編譯
我們可以通過修改連接數據庫的 URL 信息,添加 useServerPrepStmts=true 信息開啟服
務端預編譯。
12 通過 PreparedStatement 對象完成數據的更新
12.1代碼
//更新數據
public void updateDepartment(int departmentId,String
departmentName,int localhostId){
Connection conn= null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("update departments set
department_name = ?,location_id = ? where department_id = ?");
ps.setString(1, departmentName);
ps.setInt(2, localhostId);
ps.setInt(3, departmentId);
ps.execute();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
13 通過 PreparedStatement 對象完成數據的查詢
13.1查詢返回單條結果集
13.1.1 代碼
//完成數據查詢
public Departments selectDepartmentsById(int
departmentId){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
Departments dept = null;
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("select * from
departments where department_id = ?");
ps.setInt(1, departmentId);
rs = ps.executeQuery();
while(rs.next()){
dept=new Departments();
dept.setDepartmentId(rs.getInt("department_id"));
dept.setDepartmentName(rs.getString("department_name"));
dept.setLocationId(rs.getInt("location_id"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, rs);
}
return dept;
}
13.2查詢返回多條結果集
13.2.1 代碼
//查詢部門表中的部門名稱,找到那些包含“人力”的部門信息
public List<Departments>
selectDepartmentByLikeName(String departmentName){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Departments> list = new ArrayList<>();
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("select * from
departments where department_name like ?");
ps.setString(1, "%"+departmentName+"%");
rs = ps.executeQuery();
while(rs.next()){
Departments dept = new Departments();
dept.setDepartmentId(rs.getInt("department_id"));
dept.setDepartmentName(rs.getString("department_name"));
dept.setLocationId(rs.getInt("location_id"));
list.add(dept);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, rs);
}
return list;
}
14 PreparedStatement 批處理操作
批處理:在與數據庫的一次連接中,批量的執行條 SQL 語句。
14.1代碼
//批量添加
public void addBatch(List<Departments> list){
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("insert into departments
values(default,?,?)");
for(int i=0;i<list.size();i++){
ps.setString(1,
list.get(i).getDepartmentName());
ps.setInt(2, list.get(i).getLocationId());
//添加批處理
ps.addBatch();
}
int[] arr =ps.executeBatch();
for(int i=0;i<arr.length;i++){
System.out.println(i);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
15 JDBC 中的事務處理
在 JDBC 操作中數據庫事務默認為自動提交。如果事務需要修改為手動提交,那么我們
需 要 使 用 Connection 對 象 中 的 setAutoCommit 方 法 來 關 閉 事 務 自 動 提 交 。 然 后 通 過
Connection 對象中的 commit 方法與 rollback 方法進行事務的提交與回滾。
15.1代碼
//事務處理
public void deleteDempartments(String depratmentName){
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
//關閉事務的自動提交
conn.setAutoCommit(false);
ps = conn.prepareStatement("delete from departments
where department_name like ?");
ps.setString(1, "%"+depratmentName+"%");
ps.executeUpdate();
ps = conn.prepareStatement("insert into departments
values(default,'開發部',2)");
ps.executeUpdate();
String str = null;
str.length();
conn.commit();
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
四、 JDBC 進階
1 動態查詢
動態查詢:根據用戶給定的條件來決定執行什么樣的查詢。
1.1代碼
//動態查詢
public List<Departments> selectDeptByProperty(Departments
departments){
Connection conn =null;
PreparedStatement ps =null;
ResultSet rs = null;
List<Departments> list = new ArrayList<>();
try{
conn =JdbcUtil.getConnection();
String sql = genSQL(departments);
System.out.println(sql);
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()){
Departments dept = new Departments();
dept.setDepartmentId(rs.getInt("department_id"));
dept.setDepartmentName(rs.getString("department_name"));
dept.setLocationId(rs.getInt("location_id"));
list.add(dept);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, rs);
}
return list;
}
//拼接需要執行的 sql 語句
private String genSQL(Departments dept){
StringBuffer sb = new StringBuffer("select * from
departments where 1=1 ");
if(dept.getDepartmentId() > 0){
sb.append(" and department_id =
").append(dept.getDepartmentId());
}
if(dept.getDepartmentName() != null &&
dept.getDepartmentName().length() > 0){
sb.append(" and department_name =
'").append(dept.getDepartmentName()).append("'");
}
if(dept.getLocationId() > 0){
sb.append(" and location_id =
").append(dept.getLocationId());
}
return sb.toString();
}
2 應用程序分層
2.1什么是應用程序分層
應用程序通過創建不同的包來實現項目的分層,將項目中的代碼根據功能做具體劃分,
并存放在不同的包下。
2.2分層優點
1、分層結構將應用系統劃分為若干層,每一層只解決問題的一部分,通過各層的協作
提供整體解決方案。大的問題被分解為一系列相對獨立的子問題,局部化在每一層中,這樣
就有效的降低了單個問題的規模和復雜度,實現了復雜系統的第一步也是最為關鍵的一步分
解。
2、分層結構具有良好的可擴展性,為應用系統的演化增長提供了一個靈活的支持,具
有良好的可擴展性。增加新的功能時,無須對現有的代碼做修改,業務邏輯可以得到最大限
度的重用。
3、分層架構易于維護。在對系統進行分解后,不同的功能被封裝在不同的層中,層與
層之間的耦合顯著降低。因此在修改某個層的代碼時,只要不涉及層與層之間的接口,就不
會對其他層造成嚴重影響。
2.3三層結構
三層結構就是將整個業務應用劃分為:界面層(User Interface layer)、業務邏輯層
(Business Logic Layer)、數據訪問層(Data access layer)。區分層次的目的即為了“高內
聚低耦合”的思想。在軟件體系架構設計中,分層式結構是最常見,也是最重要的一種結構。
2.4項目分層
2.5在分層結構中實現業務
2.5.1持久層
2.5.1.1 接口
接口
public interface DepartmentsDao {
public List<Departments> selectDeptByName(String
deptName);
public void insertDept(Departments dept);
}
接口實現類
public class DepartmentsDaoImpl implements DepartmentsDao {
@Override
public List<Departments> selectDeptByName(String deptName)
{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Departments> list = new ArrayList<>();
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("select * from
departments where department_name = ?");
ps.setString(1, deptName);
rs = ps.executeQuery();
while(rs.next()){
Departments d = new Departments();
d.setDepartmentId(rs.getInt("department_id"));
d.setDepartmentName(rs.getString("department_name"));
d.setLocationId(rs.getInt("location_id"));
list.add(d);
}
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
return list;
}
@Override
public void insertDept(Departments dept) {
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement("insert into departments
values(default,?,?)");
ps.setString(1, dept.getDepartmentName());
ps.setInt(2, dept.getLocationId());
ps.execute();
conn.commit();
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
}
2.5.2業務層
2.5.2.1 代碼
接口
public interface DepartmentsService {
public void addDepartments(Departments dept);
}
接口實現類
public class DepartmensServiceImpl implements
DepartmentsService {
@Override
public void addDepartments(Departments dept) {
DepartmentsDao deptDao = new DepartmentsDaoImpl();
deptDao.insertDept(dept);
}
}
2.5.3測試層
2.5.3.1 代碼
public class Test {
public static void main(String[] args) {
Departments dept = new Departments();
dept.setDepartmentName("研發部");
dept.setLocationId(30);
DepartmentsService ds = new DepartmensServiceImpl();
ds.addDepartments(dept);
}
}
3 封裝通用的 BaseDao
3.1封裝更新操作
3.1.1代碼
接口
public interface BaseDao {
public int executeUpdate(String sql,Object[] param);
}
接口實現類
public class BaseDaoImpl implements BaseDao {
/**
* 封裝通用的 DML 操作
*/
@Override
public int executeUpdate(String sql, Object[] param) {
Connection conn =null;
PreparedStatement ps = null;
int rows = 0;
try{
conn = JdbcUtil.getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement(sql);
//得到參數的個數
ParameterMetaData pmd = ps.getParameterMetaData();
//綁定參數
for(int i=0;i<pmd.getParameterCount();i++){
ps.setObject(i+1, param[i]);
}
rows = ps.executeUpdate();
conn.commit();
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
return rows;
}
}
Dao 層代碼 接口
public interface DepartmentsDao extends BaseDao {
public List<Departments> selectDeptByName(String
deptName);
public void insertDept(Departments dept);
public int updateDept(Departments dept);
public int deleteDeptById(int departmentId);
}
Dao 層接口實現類
public class DepartmentsDaoImpl extends BaseDaoImpl implements
DepartmentsDao {
@Override
public List<Departments> selectDeptByName(String deptName)
{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Departments> list = new ArrayList<>();
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("select * from
departments where department_name = ?");
ps.setString(1, deptName);
rs = ps.executeQuery();
while(rs.next()){
Departments d = new Departments();
d.setDepartmentId(rs.getInt("department_id"));
d.setDepartmentName(rs.getString("department_name"));
d.setLocationId(rs.getInt("location_id"));
list.add(d);
}
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
return list;
}
@Override
public void insertDept(Departments dept) {
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement("insert into departments
values(default,?,?)");
ps.setString(1, dept.getDepartmentName());
ps.setInt(2, dept.getLocationId());
ps.execute();
conn.commit();
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
//更新部門信息
@Override
public int updateDept(Departments dept) {
String sql = "update departments set department_name
= ? ,location_id = ? where department_id = ?";
Object[] param = new
Object[]{dept.getDepartmentName(),dept.getLocationId(),dept.ge
tDepartmentId()};
return this.executeUpdate(sql, param);
}
//刪除部門信息
@Override
public int deleteDeptById(int departmentId) {
String sql = "delete from departments where department_id
= ?";
Object[] param = new Object[]{departmentId};
return this.executeUpdate(sql, param);
}
}
3.2封裝查詢操作
3.2.1代碼
BaseDao 接口
public interface BaseDao {
public int executeUpdate(String sql,Object[] param);
public <T> List<T> find(String sql,Object[] param,Class<T>
clazz);
}
BaseDaoImpl 接口實現類
@Override
public <T> List<T> find(String sql, Object[] param, Class<T>
clazz) {
Connection conn =null;
PreparedStatement ps =null;
ResultSet rs = null;
List<T> list = new ArrayList<>();
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement(sql);
//得到參數的個數
ParameterMetaData pmd = ps.getParameterMetaData();
//綁定參數
for(int i=0;i<pmd.getParameterCount();i++){
ps.setObject(i+1, param[i]);
}
//處理結果集
rs = ps.executeQuery();
//獲取結果集的信息
ResultSetMetaData rsmd = rs.getMetaData();
while(rs.next()){
//完成 ORM 處理:通過 jdk 的反射
T bean =clazz.newInstance();//Departmens d = new
Department();
for(int i=0;i<rsmd.getColumnCount();i++){
//得到列名
String columnName = rsmd.getColumnName(i+1);
//獲取列的值
Object value = rs.getObject(columnName);
//通過 BeanUtil 工具類將值當如到對象中
BeanUtils.setProperty(bean, columnName,
value);
}
list.add(bean);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, rs);
}
return list;
}
DepartmentDao 接口
public interface DepartmentsDao extends BaseDao {
public List<Departments> selectDeptByName(String
deptName);
public void insertDept(Departments dept);
public int updateDept(Departments dept);
public int deleteDeptById(int departmentId);
public List<Dept> selectDeptByLikeName(String deptName);
}
DepartmentDaoImpl 接口實現類
@Override
public List<Dept> selectDeptByLikeName(String deptName) {
String sql ="select * from departments where
department_name like ?";
Object[] param = new Object[]{"%"+deptName+"%"};
return this.find(sql, param, Dept.class);
}
4 JDBC 驅動加載原理
4.1創建對象的方式
4.2創建對象時三個重要的步驟
?通過類加載器加載 class
?初始化所有靜態部分
?為新生對象分配內存
4.3MySQL 驅動類的實例化過程
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
總結
以上是生活随笔為你收集整理的java技术_JAVA-JDBC技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: echart 数据视图_关于数据可视化图
- 下一篇: node-sass -v 不是内部_奔驰