JDBC實現數據庫的連接和操作:
- 一、連接數據庫
- 1.Java代碼
- 2.配置文件`myjdbc.properties`
- 二、創建執行語句,Statement語句
- 三、執行SQL語句
- 1.實現數據庫的操作:`增刪改`,此時並沒有返回值
- 2.實現數據庫的操作:`查`
- 3.用到的Employees類
一、連接數據庫
1.Java代碼
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
/**
* Java連接數據庫 JDBC:
* 一、創建連接 Connection 對象
* 二、創建執行的語句 Statement 對象
* 三、執行 SQL 語句
*
* 一、創建連接
* 1.最耿直,直接創建對象。由於獲取驅動的實例化對象時使用了第三方的包 mysql.jdbc.Driver()
* Driver driver = new com.mysql.jdbc.Driver();
*
* 2.法一不利於代碼的移植和擴展性,所以在此基礎之上,利用反射的方法創建 Driver 對象
* 獲取類對象 getClassname()
* 獲取構造器,創建對象 getDeclaredConstructor().newInstance()
* 獲取指定的方法 getMethod(方法名,參數列表),如 getMethod("setPrice", int.class)
* 使用類的方法進行初始化 invoke(創建的對象, 14)
*
* Class clazz = Class.forName("com.mysql.jdbc.Driver");
* Driver driver = (Driver)clazz.getDeclaredConstructor().newInstance();
*
* 3.直接使用驅動不方便,引入驅動管理的實現類,進一步簡化。並且在 mysql的Driver實現類中已經
* 聲明瞭註冊驅動
* Class.forName("com.mysql.jdbc.Driver");
* Connection conn = DriverManager.getConnection(url, user, password);
*
* 4.直接寫死了用户名、密碼等信息,不安全、不方便,引入配置文件
* 連接mysql,jdbc:mysql:協議,localhost:ip地址,3306:默認mysql的端口號,test:連接的數據庫名稱
* String string = "jdbc:mysql://localhost:3306/test";
* Properties info = new Properties();
* // 將用户名和密碼封裝在Properties中
* info.setProperty("user", "tom");
* info.setProperty("password", "123");
* 配置文件讓用户能夠脱離程序本身去修改相關的變量設置。
* 1、從目標路徑 myjdbc.properites 中獲取輸入流對象
* 2、使用 Properties類的 load()方法從字節輸入流中獲取數據
* 3.使用 Properties類的 getProperty(String key)方法,根據參數key獲取value
*
*
* @Auther:sommer1111
* @date 2020/10/10 17:36
*/
public class _01_ConnectionMySQL {
public static void main(String[] args) throws Exception{
//1.從目標路徑myjdbc.properites中獲取輸入流對象
InputStream in = _01_ConnectionMySQL.class.getClassLoader().getResourceAsStream("myjdbc.properties");
//2.使用Properties類的load()方法從字節輸入流中獲取數據
Properties pro = new Properties();
pro.load(in);
String driverClass = pro.getProperty("driverClass");
String url = pro.getProperty("url");
String name = pro.getProperty("user");
String password = pro.getProperty("password");
//3.加載驅動
Class.forName(driverClass);
//4.獲取連接
Connection connect = DriverManager.getConnection(url,name,password);
System.out.println(connect);
}
}
2.配置文件myjdbc.properties
#設置配置信息
url=jdbc:mysql://localhost:3306/myemployees
user=tom
password=123
driverClass=com.mysql.jdbc.Driver
二、創建執行語句,Statement語句
將代碼專門抽象成一個工具類
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* @Auther:sommer1111
* @date 2020/10/13 16:25
*/
public class statementUtil {
//獲取連接
public static Connection getConnect() throws Exception {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream("myjdbc.properties");
Properties ps = new Properties();
ps.load(in);
String driverClass = ps.getProperty("driverClass");
String url = ps.getProperty("url");
String user = ps.getProperty("user");
String password = ps.getProperty("password");
Class.forName(driverClass);
return DriverManager.getConnection(url, user, password);
}
//關閉資源
public static void closeConnetion(Connection con,PreparedStatement sta){
try {
if(con != null){
con.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(sta != null){
sta.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
//增加一個關閉資源
public static void closeConnetion(Connection con, PreparedStatement sta, ResultSet rs){
try {
if(con != null){
con.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(sta != null){
sta.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(rs != null){
rs.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
//設置statment
public static void update(String sql,Object ...args) {
Connection connection = null;
PreparedStatement statement = null;
try {
//1.預編譯
connection = getConnect();
statement = connection.prepareStatement(sql);
//2.填充佔位符
for(int i = 0;i<args.length;i++){
statement.setObject(i+1,args[i]);
}
//3.執行
statement.execute();
} catch (Exception e) {
e.printStackTrace();
}finally {
closeConnetion(connection,statement);
}
}
}
三、執行SQL語句
1.實現數據庫的操作:增刪改,此時並沒有返回值
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;
/**
* 實現創建數據庫語句的操作(增刪改,沒有返回)
*
* 1.獲取數據庫連接
* InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream("myjdbc.properties");
* Properties ps = new Properties();
* ps.load(in);
* String driverClass = ps.getProperty("driverClass");
* String url = ps.getProperty("url");
* String user = ps.getProperty("user");
* String password = ps.getProperty("password");
* Class.forName(driverClass);
* connection = DriverManager.getConnection(url, user, password);
*
* 2.預編譯sql語句,返回PreparedStatement的實例
* String sql = new String("UPDATE locations SET street_address = ? WHERE location_id = ?;");
* statement = connection.prepareStatement(sql);
*
* 3.填充佔位符
* statement.setObject(1,"wuhan");
* statement.setObject(2,"2200");
* 4.執行
* statement.execute();
* 5.資源的關閉(都需要用 try catch)
* statement.close();
* connection.close()
*
* 優化:
* 1.將數據庫的連接、預編譯、關閉資源都封裝成方法 statementUtil,簡化代碼
*
* @Auther:sommer1111
* @date 2020/10/13 15:38
*/
public class _02_Statement {
public static void main(String[] args) {
String sql = "UPDATE locations SET street_address = ? WHERE location_id = ?;";
Object[] arg = {"jiangxi","2300"};
statementUtil.update(sql,arg);
// Connection connection = null;
// PreparedStatement statement = null;
// try {
// //1.獲取數據庫連接
// InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream("myjdbc.properties");
// Properties ps = new Properties();
// ps.load(in);
// String driverClass = ps.getProperty("driverClass");
// String url = ps.getProperty("url");
// String user = ps.getProperty("user");
// String password = ps.getProperty("password");
// Class.forName(driverClass);
// connection = DriverManager.getConnection(url, user, password);
//
//
// //2.預編譯sql語句,返回PreparedStatement的實例
// String sql = new String("UPDATE locations SET street_address = ? WHERE location_id = ?;");
// statement = connection.prepareStatement(sql);
// //3.填充佔位符
// statement.setObject(1,"wuhan");
// statement.setObject(2,"2200");
//
// //4.執行
// statement.execute();
// } catch (Exception e) {
// e.printStackTrace();
// }finally {
// //5.資源的關閉
// if(statement != null){
// try {
// statement.close();
// } catch (SQLException throwables) {
// throwables.printStackTrace();
// }
// }
// if(connection != null){
// try {
// connection.close();
// } catch (SQLException throwables) {
// throwables.printStackTrace();
// }
// }
// }
}
}
2.實現數據庫的操作:查
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collection;
/**
* JDBC 實現數據庫的查詢
* 一、分析:
* 1. 使用 PreparedStatement實現查詢操作,查詢操作的區別在於會有一個數據返回
* 2. 返回的數據用一個類封裝 ResultSet,這個表中只有數據,但是如果我們還需要獲取表頭信息
* 3. 用 getMetaData 獲取關於 ResultSet 對象中列的類型和屬性信息的對象 ResultSetMetaData
* 4. ResultSet 資源也需要釋放
*
* 二、實現:
* 1.獲取連接
* 2.執行sql語句,得打結果返回 ResultSet,ResultSet rs = ps.executeQuery();
* 3.要想顯示結果,將數據讀取出來封裝在一個 Collection 對象中 key-value 鍵值對
* |--讀取出表頭信息:
* (1)獲取元數據集,ResultSetMetaData rsmd = rs.getMetaData();
* (2)獲取結果集中的列數,迭代讀取元數據集的表頭:
* int columnCount = rsmd.getColumnCount();
* String columnName = rsmd.getColumnName(i + 1);
* (3)獲取列值,此時列值屬性失去,都變成了 Object
* Object columValue = rs.getObject(i + 1);
* (4)利用反射恢復列值在 Collection 對象的屬性,並添加到集合中:
* Field field = Customer.class.getDeclaredField(columnLabel);
* field.setAccessible(true);使在用反射時能訪問私有變量
* field.set(cust, columValue);
* 4.關閉資源
*
* 三、筆記
* 1.查詢需要調用PreparedStatement 的 executeQuery() 方法,查詢結果是一個ResultSet 對象
* ResultSet通過指針迭代取數據,常用方法有:
* next(),用於迭代的指針,指向下一個值。
* getObject(),獲取列值。
*
* 2.ResultSetMetaData對象的常用方法
* getColumnName(int column):獲取指定列的名稱
* getColumnLabel(int column):獲取指定列的別名(MySQL中的別名,推薦使用)
* getColumnCount():返回當前 ResultSet 對象中的列數。
* getColumnTypeName(int column):檢索指定列的數據庫特定的類型名稱。
*
* @Auther:sommer1111
* @date 2020/10/14 15:35
*/
public class _03_StatementQuery {
public static void main(String[] args) {
String sql = "SELECT employee_id,last_name,email,salary FROM employees WHERE employee_id>?;";
Collection<Employees> employees = queryForEmployees(sql, 128);
for(Employees employee:employees){
System.out.println(employee);
}
}
//基本實現
public static Collection<Employees> queryForEmployees(String sql, Object...args) {
statementUtil util = null;
Connection connect = null;
PreparedStatement ps = null;
ResultSet rs = null;
Collection<Employees> list = new ArrayList<>();
try {
util = new statementUtil();
connect = util.getConnect();
ps = connect.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1,args[i]);
}
//得到數據集
rs = ps.executeQuery();
//獲取元數據
ResultSetMetaData rsmd = rs.getMetaData();
//開始讀取值
while(rs.next()){//一行的數據為一個next
Employees em = new Employees();
int columnCount = rsmd.getColumnCount();
for (int i = 0; i < columnCount; i++) {
//獲取數據
Object value = rs.getObject(i+1);
//獲取列名,最好使用別名來獲取
String columnName = rsmd.getColumnLabel(i + 1);
//恢復屬性
Field field = Employees.class.getDeclaredField(columnName);
field.setAccessible(true);
field.set(em,value);
}
list.add(em);
}
return list;
} catch (Exception e) {
e.printStackTrace();
}finally{
util.closeConnetion(connect,ps,rs);
}
return null;
}
//優化增強擴展性,將具體的類換成泛型
public static <T>T queryForEmployees(Class<T> clazz,String sql, Object...args) throws Exception {
//修改創建類的語句
T t = clazz.getDeclaredConstructor().newInstance();
//修改反射設值的語句,其餘不變
//field.set(t,value);
return null;
}
}
3.用到的Employees類
/**
* @Auther:sommer1111
* @date 2020/10/14 16:28
*/
class Employees {
private int employee_id;
private String last_name;
private String email;
private double salary;
public Employees() {
}
public Employees(int employee_id, String last_name, String email, int salary) {
this.employee_id = employee_id;
this.last_name = last_name;
this.email = email;
this.salary = salary;
}
@Override
public String toString() {
return "Employees{" +
"employee_id=" + employee_id +
", last_name='" + last_name + '\'' +
", email='" + email + '\'' +
", salary=" + salary +
'}';
}
public int getEmployee_id() {
return employee_id;
}
public void setEmployee_id(int employee_id) {
this.employee_id = employee_id;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。