日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java技术_JAVA-JDBC技术

發(fā)布時間:2025/4/16 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java技术_JAVA-JDBC技术 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1 什么是 JDBC

? JDBC(Java DataBase Connectivity)java 數(shù)據(jù)庫連接

? 是 JavaEE 平臺下的技術(shù)規(guī)范

? 定義了在 Java 語言中連接數(shù)據(jù),執(zhí)行 SQL 語句的標準

? 可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問

2 什么是數(shù)據(jù)庫驅(qū)動程序

? 數(shù)據(jù)庫廠商對 JDBC 規(guī)范的具體實現(xiàn)

? 不同數(shù)據(jù)產(chǎn)品的數(shù)據(jù)庫驅(qū)動名字有差異

? 在程序中需要依賴數(shù)據(jù)庫驅(qū)動來完成對數(shù)據(jù)庫的操作

3 程序操作數(shù)據(jù)庫流程

二、 JDBC3.0 標準中常用接口與類

1 Driver 接口

Driver 接口的作用是來定義數(shù)據(jù)庫驅(qū)動對象應(yīng)該具備的一些能力。比如與數(shù)據(jù)庫建立連

接的方法的定義所有支持 java 語言連接的數(shù)據(jù)庫都實現(xiàn)了該接口,實現(xiàn)該接口的類我們稱

之為數(shù)據(jù)庫驅(qū)動類。在程序中要連接數(shù)據(jù)庫,必須先通過 JDK 的反射機制加載數(shù)據(jù)庫驅(qū)動

類,將其實例化。不同的數(shù)據(jù)庫驅(qū)動類的類名有區(qū)別。

加載 MySql 驅(qū)動:Class.forName("com.mysql.jdbc.Driver");

加載 Oracle 驅(qū)動:Class.forName("oracle.jdbc.driver.OracleDriver");

2 DriverManager 類

DriverManager 通過實例化的數(shù)據(jù)庫驅(qū)動對象,能夠建立應(yīng)用程序與數(shù)據(jù)庫之間建立連

接。并返回 Connection 接口類型的數(shù)據(jù)庫連接對象。

2.1常用方法

? getConnection(String jdbcUrl, String user, String password)

該方法通過訪問數(shù)據(jù)庫的 url、用戶以及密碼,返回對應(yīng)的數(shù)據(jù)庫的 Connection 對象。

2.2JDBC URL

與數(shù)據(jù)庫連接時,用來連接到指定數(shù)據(jù)庫標識符。在 URL 中包括了該數(shù)據(jù)庫的類型、

地址、端口、庫名稱等信息。不同品牌數(shù)據(jù)庫的連接 URL 不同。

3 Connection 接口

Connection 與數(shù)據(jù)庫的連接(會話)對象。我們可以通過該對象執(zhí)行 sql 語句并返回結(jié)

果。

連接 MySql 數(shù)據(jù)庫:

Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user",

"password");

連接 Oracle 數(shù)據(jù)庫:

Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database",

"user", "password");

連接 SqlServer 數(shù)據(jù)庫:

Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port;

DatabaseName=database", "user", "password");

3.1常用方法

? createStatement():創(chuàng)建向數(shù)據(jù)庫發(fā)送 sql 的 Statement 接口類型的對象。

? preparedStatement(sql) :創(chuàng)建向數(shù)據(jù)庫發(fā)送預(yù)編譯 sql 的 PrepareSatement 接口類型的

對象。

? prepareCall(sql):創(chuàng)建執(zhí)行存儲過程的 CallableStatement 接口類型的對象。

? setAutoCommit(boolean autoCommit):設(shè)置事務(wù)是否自動提交。

? commit() :在鏈接上提交事務(wù)。

? rollback() :在此鏈接上回滾事務(wù)。

4 Statement 接口

用于執(zhí)行靜態(tài) SQL 語句并返回它所生成結(jié)果的對象。

由 createStatement 創(chuàng)建,用于發(fā)送簡單的 SQL 語句(不支持動態(tài)綁定)。

4.1常用方法

? execute(String sql):執(zhí)行參數(shù)中的 SQL,返回是否有結(jié)果集。

? executeQuery(String sql):運行 select 語句,返回 ResultSet 結(jié)果集。

? executeUpdate(String sql):運行 insert/update/delete 操作,返回更新的行數(shù)。

? addBatch(String sql) :把多條 sql 語句放到一個批處理中。

? executeBatch():向數(shù)據(jù)庫發(fā)送一批 sql 語句執(zhí)行。

5 PreparedStatement 接口

繼承自 Statement 接口,由 preparedStatement 創(chuàng)建,用于發(fā)送含有一個或多個參數(shù)的 SQL

語句。PreparedStatement 對象比 Statement 對象的效率更高,并且可以防止 SQL 注入,所以

我們一般都使用 PreparedStatement。

5.1常用方法

? addBatch()把當(dāng)前 sql 語句加入到一個批處理中。

? execute() 執(zhí)行當(dāng)前 SQL,返回個 boolean 值

? executeUpdate()運行 insert/update/delete 操作,返回更新的行數(shù)。

? executeQuery() 執(zhí)行當(dāng)前的查詢,返回一個結(jié)果集對象

? setDate(int parameterIndex, Date x)向當(dāng)前 SQL 語句中的指定位置綁定一個 java.sql.Date

值。

? setDouble(int parameterIndex, double x)向當(dāng)前 SQL 語句中的指定位置綁定一個 double

? setFloat(int parameterIndex, float x)向當(dāng)前 SQL 語句中的指定位置綁定一個 float 值

? setInt(int parameterIndex, int x)向當(dāng)前 SQL 語句中的指定位置綁定一個 int 值

? setString(int parameterIndex, String x)向當(dāng)前 SQL 語句中的指定位置綁定一個 String 值

6 ResultSet 接口

ResultSet 提供檢索不同類型字段的方法。

6.1常用方法

? getString(int index)、getString(String columnName)

獲得在數(shù)據(jù)庫里是 varchar、char 等類型的數(shù)據(jù)對象。

? getFloat(int index)、getFloat(String columnName)

獲得在數(shù)據(jù)庫里是 Float 類型的數(shù)據(jù)對象。

? getDate(int index)、getDate(String columnName)

獲得在數(shù)據(jù)庫里是 Date 類型的數(shù)據(jù)。

? getBoolean(int index)、getBoolean(String columnName)

獲得在數(shù)據(jù)庫里是 Boolean 類型的數(shù)據(jù)。

? getObject(int index)、getObject(String columnName)

獲取在數(shù)據(jù)庫里任意類型的數(shù)據(jù)。

6.2ResultSet 對結(jié)果集進行滾動的方法

? next():移動到下一行。

? Previous():移動到前一行。

? absolute(int row):移動到指定行。

? beforeFirst():移動 resultSet 的最前面。

? afterLast() :移動到 resultSet 的最后面。

7 CallableStatement 接口

繼承自 PreparedStatement 接口,由方法 prepareCall 創(chuàng)建,用于調(diào)用數(shù)據(jù)庫的存儲過程。

三、 JDBC 的使用

加 載 數(shù) 據(jù) 庫 驅(qū) 動 程 序 → 建 立 數(shù) 據(jù) 庫 連 接 Connection → 創(chuàng) 建 執(zhí) 行 SQL 的 語 句

Statement → 處理執(zhí)行結(jié)果 ResultSet → 釋放資源

1 下載數(shù)據(jù)庫驅(qū)動

1.1MySQL 驅(qū)動

Download Connector/J

1.2Oracle 驅(qū)動

數(shù)據(jù)庫安裝目錄oracleproduct11.2.0dbhome_1jdbclib

2 創(chuàng)建項目添加驅(qū)動

3 通過 Statement 向表中插入數(shù)據(jù)

3.1注冊驅(qū)動

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執(zhí)行 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 對象修改表中的數(shù)據(jù)

4.1代碼

//更新 departments 表中的 department_id 為 6 的數(shù)據(jù),將

部門名稱修改為教學(xué)部,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;

}

//關(guān)閉 Statement

public static void closeStatement(Statement

state){

try {

if(state != null){

state.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

//關(guān)閉 Connection

public static void closeConnection(Connection

conn){

try {

if(conn != null){

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

//關(guān)閉資源

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;

}

//關(guān)閉 Statement

public static void closeStatement(Statement

state){

try {

if(state != null){

state.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

//關(guān)閉 Connection

public static void closeConnection(Connection

conn){

try {

if(conn != null){

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

//關(guān)閉資源

public static void closeResource(Statement

state,Connection conn){

closeStatement(state);

closeConnection(conn);

}

}

6 通過 Statement 對象查詢數(shù)據(jù)

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;

//執(zhí)行查詢返回結(jié)果

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 中封裝的并不是我們查詢到的所有的結(jié)果集,而是返回了查詢到的結(jié)果

集的數(shù)據(jù)庫游標。通過 ResultSet 中的 next()方法操作游標的位置獲取結(jié)果集。

8 通過 ResultSet 實現(xiàn)邏輯分頁

8.1代碼

//查詢 departments 表中的所有的數(shù)據(jù),并且通過 ResultSet 實現(xiàn)邏輯分

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);

//開始位置與結(jié)束位置

int begin = (currentPage -1)*pageRows;

int end = currentPage * pageRows;

//當(dāng)前位置的計數(shù)器

int currentNum = 0;

while(rs.next()){

//什么情況下獲取結(jié)果集中的數(shù)據(jù)

if(currentNum >= begin && currentNum < end){

System.out.println(rs.getInt("department_id")+"

"+rs.getString("department_name"));

//結(jié)束操作 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 語句片段的參數(shù)插入到需要執(zhí)行的 SQL 語句中,

最終達到欺騙數(shù)據(jù)庫服務(wù)器執(zhí)行惡意操作的 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 支持動態(tài)綁定參數(shù)

? PreparedStatement 具備 SQL 語句預(yù)編譯能力

? 使用 PreparedStatement 可防止出現(xiàn) SQL 注入問題

10.2通過 PreparedStatement 對象向表中插入數(shù)據(jù)

10.2.1 代碼

//向 Departments 表中插入一條數(shù)據(jù)

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 的預(yù)編譯能力

11.1什么是預(yù)編譯

11.1.1 SQL 語句的執(zhí)行步驟

? 語法和語義解析

? 優(yōu)化 sql 語句,制定執(zhí)行計劃

? 執(zhí)行并返回結(jié)果

但是很多情況,我們的一條 sql 語句可能會反復(fù)執(zhí)行,或者每次執(zhí)行的時候只有個別的

值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。

如果每次都需要經(jīng)過上面的詞法語義解析、語句優(yōu)化、制定執(zhí)行計劃等,則效率就明顯不行

了。

所謂預(yù)編譯語句就是將這類語句中的值用占位符替代,可以視為將 sql 語句模板化或者

說參數(shù)化

預(yù)編譯語句的優(yōu)勢在于:一次編譯、多次運行,省去了解析優(yōu)化等過程;此外預(yù)編譯語

句能防止 sql 注入

11.1.2 解析過程

11.1.2.1 硬解析

在不開啟緩存執(zhí)行計劃的情況下,每次 SQL 的處理都要經(jīng)過:語法和語義的解析,優(yōu)

化器處理 SQL,生成執(zhí)行計劃。整個過程我們稱之為硬解析。

11.1.2.2 軟解析

如果開啟了緩存執(zhí)行計劃,數(shù)據(jù)庫在處理 sql 時會先查詢緩存中是否含有與當(dāng)前 SQL

語句相同的執(zhí)行計劃,如果有則直接執(zhí)行該計劃。

11.2預(yù)編譯方式

開始數(shù)據(jù)庫的日志

show VARIABLES like '%general_log%'

set GLOBAL general_log = on

set GLOBAL log_output='table'

11.2.1 依賴數(shù)據(jù)庫驅(qū)動完成預(yù)編譯

如果我們沒有開啟數(shù)據(jù)庫服務(wù)端編譯,那么默認的是使用數(shù)據(jù)庫驅(qū)動完成 SQL 的預(yù)編

譯處理。

11.2.2 依賴數(shù)據(jù)庫服務(wù)器完成預(yù)編譯

我們可以通過修改連接數(shù)據(jù)庫的 URL 信息,添加 useServerPrepStmts=true 信息開啟服

務(wù)端預(yù)編譯。

12 通過 PreparedStatement 對象完成數(shù)據(jù)的更新

12.1代碼

//更新數(shù)據(jù)

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 對象完成數(shù)據(jù)的查詢

13.1查詢返回單條結(jié)果集

13.1.1 代碼

//完成數(shù)據(jù)查詢

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查詢返回多條結(jié)果集

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 批處理操作

批處理:在與數(shù)據(jù)庫的一次連接中,批量的執(zhí)行條 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 中的事務(wù)處理

在 JDBC 操作中數(shù)據(jù)庫事務(wù)默認為自動提交。如果事務(wù)需要修改為手動提交,那么我們

需 要 使 用 Connection 對 象 中 的 setAutoCommit 方 法 來 關(guān) 閉 事 務(wù) 自 動 提 交 。 然 后 通 過

Connection 對象中的 commit 方法與 rollback 方法進行事務(wù)的提交與回滾。

15.1代碼

//事務(wù)處理

public void deleteDempartments(String depratmentName){

Connection conn = null;

PreparedStatement ps = null;

try{

conn = JdbcUtil.getConnection();

//關(guān)閉事務(wù)的自動提交

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,'開發(fā)部',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 動態(tài)查詢

動態(tài)查詢:根據(jù)用戶給定的條件來決定執(zhí)行什么樣的查詢。

1.1代碼

//動態(tài)查詢

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;

}

//拼接需要執(zhí)行的 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 應(yīng)用程序分層

2.1什么是應(yīng)用程序分層

應(yīng)用程序通過創(chuàng)建不同的包來實現(xiàn)項目的分層,將項目中的代碼根據(jù)功能做具體劃分,

并存放在不同的包下。

2.2分層優(yōu)點

1、分層結(jié)構(gòu)將應(yīng)用系統(tǒng)劃分為若干層,每一層只解決問題的一部分,通過各層的協(xié)作

提供整體解決方案。大的問題被分解為一系列相對獨立的子問題,局部化在每一層中,這樣

就有效的降低了單個問題的規(guī)模和復(fù)雜度,實現(xiàn)了復(fù)雜系統(tǒng)的第一步也是最為關(guān)鍵的一步分

解。

2、分層結(jié)構(gòu)具有良好的可擴展性,為應(yīng)用系統(tǒng)的演化增長提供了一個靈活的支持,具

有良好的可擴展性。增加新的功能時,無須對現(xiàn)有的代碼做修改,業(yè)務(wù)邏輯可以得到最大限

度的重用。

3、分層架構(gòu)易于維護。在對系統(tǒng)進行分解后,不同的功能被封裝在不同的層中,層與

層之間的耦合顯著降低。因此在修改某個層的代碼時,只要不涉及層與層之間的接口,就不

會對其他層造成嚴重影響。

2.3三層結(jié)構(gòu)

三層結(jié)構(gòu)就是將整個業(yè)務(wù)應(yīng)用劃分為:界面層(User Interface layer)、業(yè)務(wù)邏輯層

(Business Logic Layer)、數(shù)據(jù)訪問層(Data access layer)。區(qū)分層次的目的即為了“高內(nèi)

聚低耦合”的思想。在軟件體系架構(gòu)設(shè)計中,分層式結(jié)構(gòu)是最常見,也是最重要的一種結(jié)構(gòu)。

2.4項目分層

2.5在分層結(jié)構(gòu)中實現(xiàn)業(yè)務(wù)

2.5.1持久層

2.5.1.1 接口

接口

public interface DepartmentsDao {

public List<Departments> selectDeptByName(String

deptName);

public void insertDept(Departments dept);

}

接口實現(xiàn)類

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業(yè)務(wù)層

2.5.2.1 代碼

接口

public interface DepartmentsService {

public void addDepartments(Departments dept);

}

接口實現(xiàn)類

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("研發(fā)部");

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);

}

接口實現(xiàn)類

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);

//得到參數(shù)的個數(shù)

ParameterMetaData pmd = ps.getParameterMetaData();

//綁定參數(shù)

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 層接口實現(xiàn)類

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 接口實現(xiàn)類

@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);

//得到參數(shù)的個數(shù)

ParameterMetaData pmd = ps.getParameterMetaData();

//綁定參數(shù)

for(int i=0;i<pmd.getParameterCount();i++){

ps.setObject(i+1, param[i]);

}

//處理結(jié)果集

rs = ps.executeQuery();

//獲取結(jié)果集的信息

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 工具類將值當(dāng)如到對象中

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 接口實現(xiàn)類

@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 驅(qū)動加載原理

4.1創(chuàng)建對象的方式

4.2創(chuàng)建對象時三個重要的步驟

?通過類加載器加載 class

?初始化所有靜態(tài)部分

?為新生對象分配內(nèi)存

4.3MySQL 驅(qū)動類的實例化過程

static {

try {

java.sql.DriverManager.registerDriver(new Driver());

} catch (SQLException E) {

throw new RuntimeException("Can't register driver!");

}

}

總結(jié)

以上是生活随笔為你收集整理的java技术_JAVA-JDBC技术的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。