JDBC操作資料庫基礎
阿新 • • 發佈:2018-12-20
JDBC操作資料庫
一、JDBC的概念
JDBC:JavaDataBaseConnection:通過java程式碼操作資料庫。可以把JDBC看成一個操作Mysql的一個客戶端。 JDBC使用步驟: 1、載入mysql的驅動類:mysql-connector-java-5.1.7-bin.jar。 2、建立資料庫與JAVA之間的連線:DriverManager.getConnection(url, user, password);url是資料庫連線地址:jdbc:mysql://localhost:3306/資料庫名。此處連得是本機。user是使用者名稱,password是資料庫登入密碼。 3、通過Connection物件建立Statement物件,conn.createStatement(); 4、通過Statement傳送SQL語句,executeUpdate():只能傳送DML語句,executeQuery();可以執行DQL語句。
程式碼如下:
public class JDBCDemo1 { //資料庫連線地址: //jdbc:mysql://mysql's ip:3306/資料庫名 private static String url = "jdbc:mysql://127.0.0.1:3306/ph"; private static String user = "j180703"; private static String password = "123456"; //驅動類名 private static String driverClassName = "com.mysql.jdbc.Driver"; /** * 建立資料庫連線,並返回該連線物件 * @return 連線物件 */ public static Connection getConnection(){ //DriverManager負責安裝資料庫驅動 Connection conn = null; try { //載入com.mysql.jdbc.Driver類到JVM Class.forName(driverClassName); //通過DriverManager建立資料庫連線 conn = DriverManager.getConnection( url, user, password); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } /** * 向學生表插入一行記錄,使用DML語句 * @param args */ public static void insertDemo(){ try { //1.獲取連線 Connection conn = getConnection(); //2.通過Connection物件建立Statement物件 Statement stmt = conn.createStatement(); //3.編寫sql語句 String sql = "insert into t_student " + "values(null,'phooxx2b','男',28," + "'2018-08-01','
[email protected]',1)"; //4.通過Statement傳送SQL //executeUpdate():只能傳送DML語句 int result = stmt.executeUpdate(sql); if(result!=1){ System.out.println("插入失敗!"); }else{ System.out.println("插入成功!"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 查詢學生表中的所有記錄,使用的是DQL語句 */ public static void queryDemo(){ try { //1.獲取連線 Connection conn = getConnection(); //2.通過Connection物件建立Statement物件 Statement stmt = conn.createStatement(); //3.編寫sql String sql = "select * from t_student"; //4.傳送Sql //傳送DQL使用executeQuery(),返回值為ResultSet //ResultSet結果集,該物件封裝了查詢結果 //ResultSet有行有列,它就是虛擬表 ResultSet rs = stmt.executeQuery(sql); //取出ResultSet中的結果: //一次取一行,迴圈去取,直到取完 //rs.next():判斷是否有下一行,如果有直接取出 //相當於迭代器的hasNext()+next() while(rs.next()){ //next()一次就取出了一行 //取一行中的各列值: System.out.println(rs.getInt("student_id")); System.out.println(rs.getString("student_name")); System.out.println(rs.getString("sex")); System.out.println("-----------"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
Statement的缺點: 1、拼寫sql容易出錯 2、不能防止sql注入 因此開發中我們常用PreparedStatement來執行sql語句。(sql注入不懂的可以上網查查,在這裡就不在細講。)
使用PreparedStatement來進行資料庫操作
public class DBUtil {
private static String url;
private static String user;
private static String password;
//驅動類名
private static String driverClassName ;
//static程式碼塊會在類被JVM載入是立即執行
//讀取db.properties檔案,並給靜態屬性賦值
static{
//1、讀取db.properties檔案
//讀取src以及同級目錄下的檔案
//1.1getClassLoader()獲取config的classloader
//獲取IO流
InputStream in = DBUtil.class.getClassLoader().
getResourceAsStream("db.properties");
//1.2建立properties物件
//專門讀取.properties檔案工具類
Properties prop = new Properties();
try {
//載入輸入流
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
//2、給靜態屬性賦值
url = prop.getProperty("jdbc.url");
user = prop.getProperty("jdbc.user");
password = prop.getProperty("jdbc.password");
driverClassName = prop.getProperty("jdbc.driverClassName");
}
/**
* 建立資料庫連線,並返回該連線物件
* @return 連線物件
*/
public static Connection getConnection(){
//DriverManager負責安裝資料庫驅動
Connection conn = null;
try {
//載入com.mysql.jdbc.Driver類到JVM
Class.forName(driverClassName);
//通過DriverManager建立資料庫連線
conn = DriverManager.getConnection(
url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* general:通用
* 封裝一個通用增刪改方法
* @param sql Object... params:佔位符:
*Object... 表示引數個數不確定,但必須放在最後一個引數位置
*相當於一個數組
*/
public static int generalUpadate(String sql,Object... params){
int result = 0;
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getConnection();
//此處執行sql語句,但佔位符處值為空
pstmt = conn.prepareStatement(sql);
//給sql中的佔位符賦值
if(params!=null){
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i+1, params[i]);
}
}
//將賦值過的佔位符值傳給sql語句
result = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
closeAll(conn,pstmt,null);
}
return result;
}
/**
* 通用查詢,可以查詢任意表,可以把查詢結果封裝成任意物件
* Java類的屬性名要和資料庫的列名一致
* 因為是通過列名反射得到的屬性名
* @param <X> 佔位符,宣告泛型
* @param cls 要封裝物件的類物件
* @param sql 查詢語句
* @param params sql語句中的佔位符值:Object...
*/
public static <X> List<X> generalQuery(Class<X> cls,String sql,Object...params){
List<X> list = new ArrayList<>();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
//給sql中佔位符賦值
if(params!=null){
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i+1, params[i]);
}
}
//將佔位符的值傳過去
rs = pstmt.executeQuery();
//如何獲取列名
//ResultSetMetaData:封裝了列的名和列的總數
ResultSetMetaData md = rs.getMetaData();
//獲取列的總數
int columnCount = md.getColumnCount();
//md.getColumnName(column):通過列號獲取列名
X x = null;
String columnName = null;
while(rs.next()){
//一行記錄對應一個物件
x = cls.newInstance();
//給物件屬性賦值
//獲取列名,為反射做準備
//一行有很多列,列號從一開始
for (int i = 1; i <= columnCount; i++) {
columnName = md.getColumnName(i);
//取出一個列名,反射得到一個屬性
try {
//1、獲取父類類物件
Class<?> superCls = cls.getSuperclass();
if(superCls == Object.class){
//如果一個類無直接父類,那麼該類屬性全在本類中
throw new NoSuchFieldException();
}
Field superField = superCls.getDeclaredField(columnName);
//無異常表示屬性屬於父類,給屬性賦值
superField.setAccessible(true);
superField.set(x, rs.getObject(i));
} catch (NoSuchFieldException e) {
// TODO: handle exception
// e.printStackTrace();
//丟擲異常屬性在子類中
Field childField = cls.getDeclaredField(columnName);
childField.setAccessible(true);
childField.set(x, rs.getObject(columnName));
}
}
//迴圈一次結束講物件加到集合中
list.add(x);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
closeAll(conn, pstmt, rs);
}
return list;
}
/**
* 關閉資源
* Connection,Statement,ResultSet
*/
public static void closeAll(Connection conn,Statement stmt,ResultSet rs){
try {
//先開的後關
if(rs!=null){
rs.close();
}
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
System.out.println(getConnection());
}
}