前言
本文重在展示jdbc、druid、jdbcTemplate三種方式操作資料庫(Mysql)。
搭配其他文章與自己實際操作為佳。如有錯誤還請指正
jdbc操作資料庫
jdbc是java語言操作資料庫,即對資料庫資料做增删查改操作,事務操作等。
使用步驟
1. 導入jar包
mysql-connector-java-5.1.37-bin.jar
2. 注冊驅動
3. 擷取資料庫連接配接對象 Connection
4. 定義sql
5. 擷取執行sql語句的對象 Statement
6. 執行sql,接收傳回結果
7. 釋放資源
具體實作執行個體
//1. 導入驅動jar包
//2.注冊驅動
Class.forName("com.mysql.jdbc.Driver");
//3.擷取資料庫連接配接對象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/One", "root", "pass");
//4.定義sql語句
String sql = "update account set balance = 500 where id = 1";
//5.擷取執行sql的對象 Statement
Statement stmt = conn.createStatement();
//6.執行sql
int count = stmt.executeUpdate(sql);
//7.處理結果
System.out.println(count);
//8.釋放資源
stmt.close();
conn.close();
詳解對象
1. DriverManager:驅動管理對象
* 功能:
1. 注冊驅動:告訴程式該使用哪一個資料庫驅動jar
static void registerDriver(Driver driver) :注冊與給定的驅動程式 DriverManager 。
寫代碼使用: Class.forName("com.mysql.jdbc.Driver");
通過檢視源碼發現:在com.mysql.jdbc.Driver類中存在靜态代碼塊
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
注意:mysql5之後的驅動jar包可以省略注冊驅動的步驟。
2. 擷取資料庫連接配接:
* 方法:static Connection getConnection(String url, String user, String password)
* 參數:
url:指定連接配接的路徑
* 文法:jdbc:mysql://ip位址(域名):端口号/資料庫名稱
* 例子:jdbc:mysql://localhost:3306/db3
* 細節:如果連接配接的是本機mysql伺服器,并且mysql服務預設端口是3306,則url可以簡寫為:jdbc:mysql:///資料庫名稱
user:使用者名
password:密碼
2. Connection:資料庫連接配接對象
1. 功能:
1. 擷取執行sql 的對象
* Statement createStatement()
* PreparedStatement prepareStatement(String sql)
2. 管理事務:
* 開啟事務:setAutoCommit(boolean autoCommit) :調用該方法設定參數為false,即開啟事務
* 送出事務:commit()
* 復原事務:rollback()
3. Statement:執行sql的對象
1. 執行sql
1. boolean execute(String sql) :可以執行任意的sql 了解
2. int executeUpdate(String sql) :執行DML(insert、update、delete)語句、DDL(create,alter、drop)語句
* 傳回值:影響的行數,可以通過這個影響的行數判斷DML語句是否執行成功 傳回值>0的則執行成功,反之,則失敗。
3. ResultSet executeQuery(String sql) :執行DQL(select)語句
4. ResultSet:結果集對象,封裝查詢結果
* boolean next(): 遊标向下移動一行,判斷目前行是否是最後一行末尾(是否有資料),如果是,則傳回false,如果不是則傳回true
* getXxx(參數):擷取資料
* Xxx:代表資料類型 如: int getInt() , String getString()
* 參數:
1. int:代表列的編号,從1開始 如: getString(1)
2. String:代表列名稱。 如: getDouble("balance")
* 注意:
* 使用步驟:
1. 遊标向下移動一行
2. 判斷是否有資料
3. 擷取資料
5. PreparedStatement:執行sql的對象
1. SQL注入問題:在拼接sql時,有一些sql的特殊關鍵字參與字元串的拼接。會造成安全性問題
1. 輸入使用者随便,輸入密碼:a' or 'a' = 'a
2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
2. 解決sql注入問題:使用PreparedStatement對象來解決
3. 預編譯的SQL:參數使用?作為占位符
4. 步驟:
1. 導入驅動jar包 mysql-connector-java-5.1.37-bin.jar
2. 注冊驅動
3. 擷取資料庫連接配接對象 Connection
4. 定義sql
* 注意:sql的參數使用?作為占位符。 如:select * from user where username = ? and password = ?;
5. 擷取執行sql語句的對象 PreparedStatement Connection.prepareStatement(String sql)
6. 給?指派:
* 方法: setXxx(參數1,參數2)
* 參數1:?的位置編号 從1 開始
* 參數2:?的值
如:pstmt.setString(1,"username");
7. 執行sql,接受傳回結果,不需要傳遞sql語句
8. 處理結果
9. 釋放資源
5. 注意:後期都會使用PreparedStatement來完成增删改查的所有操作
1. 可以防止SQL注入
2. 效率更高
使用JDBC操作資料庫
檢視jdbc庫中的user表資料:
//導包
//注冊驅動
Class.forName("com.mysql.cj.jdbc.Driver");
//擷取資料庫連接配接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC","root","pass");
//定義sql
String sql = "select id,name from user";
//擷取sql的執行對象Statement
Statement stmt = conn.createStatement();
//執行sql
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
String id = rs.getString("id");
String name = rs.getString("name");
System.out.println(id + " - " + name);
}
//關閉連接配接
rs.close();
stmt.close();
conn.close();
往jdbc庫中的user表插入資料如“XXX”,“123”:
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "pass");
//插入資料
String sql = "insert into user values('XXX','123')";
//更新資料
//String sql = "update user set name = '456' where id = 'XXX'";
//删除資料
//String sql = "delete from user where id = 'XXX'";
Statement stmt = conn.createStatement();
int i = stmt.executeUpdate(sql);
System.out.println(i);
stmt.close();
conn.close();
修改jdbc庫中user表的id = “XXX”對應的name為“456”:增删改的執行操作都是executeUpdate(),差別在sql語句而已,傳回的是修改行數;
而查的執行操作是executeQuery(),傳回的是一個結果集resultSet
jdbc操作事務
使用Connection對象來管理事務
開啟事務:setAutoCommit(boolean autoCommit) :調用該方法設定參數為false,即開啟事務
在執行sql之前開啟事務
送出事務:commit() 當所有sql都執行完送出事務
復原事務:rollback() 在catch中復原事務
/**
* aaa向bbb轉賬
*/
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "pass");
//開啟事務
conn.setAutoCommit(false);
String sql1 = "update balance set balance = ? where username = ?";
String sql2 = "update balance set balance = ? where username = ?";
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
pstmt1.setInt(1,500);
pstmt1.setString(2,"aaa");
pstmt2.setInt(1,1500);
pstmt2.setString(2,"bbb");
pstmt1.executeUpdate();
pstmt2.executeUpdate();
} catch (ClassNotFoundException | SQLException e) {
try {
//復原事務
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
try {
//送出事務
conn.commit();
pstmt1.close();
pstmt2.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
druid操作資料庫
druid資料庫連接配接池,避免了jdbc頻繁建立關閉連接配接的過程。
使用步驟
//導包:druid-1.2.5.jar 、mysql-connector-java-8.0.22.jar
//定義配置
//加載配置
Properties properties = new Properties();
InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//擷取資料庫連接配接池
dataSource = DruidDataSourceFactory.createDataSource(properties);
//擷取連接配接
conn = dataSource.getConnection();
//往下與jdbc一樣
讀取jdbc庫中balance表的資料:
public static DataSource dataSource;
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
//定義配置
Properties properties = new Properties();
InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
//加載配置
properties.load(is);
//建立資料庫連接配接池
dataSource = DruidDataSourceFactory.createDataSource(properties);
//擷取連接配接
conn = dataSource.getConnection();
//定義sql
String sql = "select username,balance from balance";
//擷取執行對象
pstmt = conn.prepareStatement(sql);
//擷取結果集
rs = pstmt.executeQuery();
while(rs.next()){
String username = rs.getString("username");
String balance = rs.getString("balance");
System.out.println(username + " " + balance);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
往jdbc庫中的balance表插入資料行”ddd“,1000:
private static DataSource dataSource;
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try{
Properties pro = new Properties();
InputStream is = DruidDemo2.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
dataSource = DruidDataSourceFactory.createDataSource(pro);
conn = dataSource.getConnection();
String sql = "insert into balance values(?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1,"ddd");
ps.setInt(2,1000);
int i = ps.executeUpdate();
System.out.println(i);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
ps.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
增删查改跟jdbc大同小異,其思想就是對資料庫連接配接的池化。
druid處理事務
跟jdbc操作事務基本相似。
jdbcTemplate操作資料庫
使用步驟
//導包
commons-logging-1.2.jar
spring-beans-5.0.0.RELEASE.jar
spring-core-5.0.0.RELEASE.jar
spring-jdbc-5.0.0.RELEASE.jar
spring-tx-5.0.0.RELEASE.jar
使用jdbcTemplate查詢資料庫資料:
private static DataSource dataSource;
public static void main(String[] args) {
try{
//定義配置
Properties pro = new Properties();
InputStream is = JdbcTemplate1.class.getClassLoader().getResourceAsStream("druid.properties");
//加載配置
pro.load(is);
//建立資料池連接配接
dataSource = DruidDataSourceFactory.createDataSource(pro);
//建立jdbcTemplate執行個體對象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "select * from balance";
//擷取結果集
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
for (Map<String, Object> stringObjectMap : list) {
System.out.println(stringObjectMap);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
使用jdbcTemplate增删改資料:
private static DataSource dataSource;
public static void main(String[] args) {
try{
Properties pro = new Properties();
InputStream is = JdbcTemplate2.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
dataSource = DruidDataSourceFactory.createDataSource(pro);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "insert into balance values(?,?)";
int update = jdbcTemplate.update(sql,"eee",1000);
//String sql = "update balance set balance = ? where username = ?";
//int update = jdbcTemplate.update(sql, 100, "eee");
//String sql = "delete from balance where username = ?";
//int update = jdbcTemplate.update(sql, "eee");
System.out.println(update);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
不需要手動關閉連接配接。