jdbc-mysql基礎 增刪查改 簡單示例
禮悟:
好好學習多思考,尊師重道存感恩。葉見尋根三二一,江河湖海同一體。
虛懷若谷良心主,願行無悔給最苦。讀書鍛煉強身心,誠勸且行且珍惜。
數據、數據,命根就在數據。雲計算、AI等技術,都是以數據為基礎。操作數據庫一定要謹慎小心。給最苦 這裏的代碼,看看就好,要有自己的判斷。遇到抉擇,要不恥上下問。
javaSE:8
mysql:5.7.14
mysql-connector-java:5.1.44
os:windows7 x64
ide:MyEclipse 2017
項目結構
下面是各個包下的各個類的代碼展示
com.jizuiku.jdbc
- JDBCUtils
package com.jizuiku.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.jizuiku.jdbc.dao.DaoException; /** * * * @author 給最苦 * @version V17.11.07 */ public final class JDBCUtils { /** * url格式 -> jdbc:子協議:子名稱//主機名:端口號/數據庫的名字?屬性名=屬性值&屬性名=屬性值 * configString變量中有多個參數,需要深入地去研究它們的具體含義 */ private static String configString = "?useUnicode=true&characterEncoding=utf8&useSSL=true"; private static String url = "jdbc:mysql://localhost:3306/jdbcforjava" + configString; // 本地的mysql數據庫(無子名稱) 端口號3306 數據庫jdbcforjava private static String user = "root"; private static String password = ""; // 工具類,直接使用,不可生對象 private JDBCUtils() { } // 把註冊驅動放到靜態代碼塊中,因為 靜態代碼塊只執行一次 static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block // 異常要拋出去 throw new ExceptionInInitializerError(e); } } /** * 獲取與指定數據庫的鏈接 * */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, user, password); } /** * 釋放三種資源ResultSet Statement Connection * */ public static void free(ResultSet rs, PreparedStatement ps, Connection con) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { // TODO Auto-generated catch block throw new DaoException(e); } finally { try { if (ps != null) { ps.close(); } } catch (SQLException e) { // TODO Auto-generated catch block throw new DaoException(e); } finally { try { if (con != null) { con.close(); } } catch (SQLException e) { // TODO Auto-generated catch block throw new DaoException(e); } } } } }
com.jizuiku.jdbc.dao
- BookDao
package com.jizuiku.jdbc.dao; import com.jizuiku.jdbc.domain.Book; /** * 這個接口可以將 業務邏輯層與數據訪問層 分割開來的,是一種很強的思想。 * * @author 博客園-給最苦 * @version V17.11.08 */ public interface BookDao { /** * 添加新的書籍 * */ public void addBook(Book book); /** * 根據id來查詢相關書籍的信息,因為id是唯一的 * */ public Book getBook(int id); /** * 更新數據庫中的書籍 * * */ public void updateBook(Book book); /** * 刪除數據庫中的指定書籍 * * */ public void deleteBook(Book book); }
- DaoException
package com.jizuiku.jdbc.dao; /** * 這個類很重要,即完成了拋異常的動作、通過編譯,又可以使數據邏輯層的接口保持簡潔。 * * @author 博客園-給最苦 * @version V17.11.08 */ public class DaoException extends RuntimeException { /** * */ private static final long serialVersionUID = 1L; public DaoException() { // TODO Auto-generated constructor stub } public DaoException(String message) { super(message); // TODO Auto-generated constructor stub } public DaoException(Throwable cause) { super(cause); // TODO Auto-generated constructor stub } public DaoException(String message, Throwable cause) { super(message, cause); // TODO Auto-generated constructor stub } public DaoException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); // TODO Auto-generated constructor stub } }
- DaoFactory
package com.jizuiku.jdbc.dao; import java.io.InputStream; import java.util.Properties; /** * 工廠類-單例模式 * * @author 博客園-給最苦 * @version V17.11.08 */ public class DaoFactory { /* * 這裏有個大坑:只要把這兩句話,調換一下位置。那麽返回的bookDao總是null * 為什麽? * 因為想想初始化的順序,new DaoFactory()經過千辛萬苦 把bookDao弄好了, * 緊接著 BookDao bookDao = null;...前功盡棄 * */ private static BookDao bookDao = null; private static DaoFactory instance = new DaoFactory(); /** * Properties + 反射 ->初始化 * 這樣的話,以後 給最苦 把接口從新實現了一下,生出了一個新的類。那麽 只需要改配置文件就OK了 * 天呀,這是哪位前輩想到的。。。 * * */ private DaoFactory() { // TODO Auto-generated constructor stub // 這裏使用Properties讀取配置文件 // 也可以使用xml Properties prop = new Properties(); InputStream inputStream = null; try { // 這個寫的,很強! inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("bookDao.properties"); // 通過流加載配置文件 prop.load(inputStream); /* * bookDao=com.jizuiku.jdbc.dao.impl.BookDaoJDBCImpl * key:bookDao * value:com.jizuiku.jdbc.dao.impl.BookDaoJDBCImpl * value剛好是bookDao接口的實現類 */ String bookDaoImplClassPath = prop.getProperty("bookDao"); // 有了bookDaoImplClassPath,就可以應用反射來構造這個類 bookDao = (BookDao)Class.forName(bookDaoImplClassPath).newInstance(); } catch (Exception e) { // try中所有的代碼都是初始化的過程,所以 一旦有錯誤,那麽直接報錯! throw new ExceptionInInitializerError(e); } } public static DaoFactory getInstance() { return instance; } public BookDao getBookDao() { return bookDao; } }
com.jizuiku.jdbc.dao.impl
- BookDaoJDBCImpl
package com.jizuiku.jdbc.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import com.jizuiku.jdbc.JDBCUtils; import com.jizuiku.jdbc.dao.BookDao; import com.jizuiku.jdbc.dao.DaoException; import com.jizuiku.jdbc.domain.Book; /** * * * @author 博客園-給最苦 * @version V17.11.08 */ public class BookDaoJDBCImpl implements BookDao { /** * 增加操作 * * */ @Override public void addBook(Book book) { // TODO Auto-generated method stub Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { // 註冊驅動並建立連接 con = JDBCUtils.getConnection(); // 創建語句 並 對sql語句進行一些預處理 String sql = "insert into book(name,quantity,time,price) values(?,?,?,?)"; // 註明要返回主鍵 ps = con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS); // 向sql語句中傳入值 ps.setString(1, book.getName()); ps.setInt(2, book.getQuantity()); ps.setDate(3, new java.sql.Date(book.getTime().getTime())); ps.setBigDecimal(4, book.getPrice()); // 執行sql語句 ps.executeUpdate(); // 得到的主鍵 // 因為主鍵就一個,而且是Int類型的 int id = 0; rs = ps.getGeneratedKeys(); if(rs.next()){ // 該對象成功插入數據庫,把得到的主鍵給這個book對象 id = rs.getInt(1); book.setId(id); } } catch (SQLException e) { // TODO Auto-generated catch block // 這裏針對異常的處理,蘊含著智慧,十分關鍵! throw new DaoException(e.getMessage(), e); } finally { // 釋放資源 JDBCUtils.free(rs, ps, con); } } /** * 查詢操作 * */ @Override public Book getBook(int id) { // TODO Auto-generated method stub Connection con = null; PreparedStatement ps = null; ResultSet rs = null; Book book = null; try { // 註冊驅動並建立連接 con = JDBCUtils.getConnection(); // 創建語句 String sql = "select id,name,quantity,time,price from book where id=?"; ps = con.prepareStatement(sql); ps.setInt(1, id); // 執行語句 rs = ps.executeQuery(); // 處理結果 if (rs.next()) { // 有查詢到,那麽創建一個對象s book = mappingBook(rs); } } catch (SQLException e) { // TODO Auto-generated catch block // 這裏針對異常的處理,蘊含著智慧,十分關鍵! throw new DaoException(e.getMessage(), e); } finally { // 釋放資源 JDBCUtils.free(rs, ps, con); } return book; } /** * 修改操作 * * */ @Override public void updateBook(Book book) { // TODO Auto-generated method stub Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { // 註冊驅動並建立連接 con = JDBCUtils.getConnection(); // 創建語句 String sql = "update book set name=?,quantity=?,time=?,price=? where id=?"; ps = con.prepareStatement(sql); // 向sql語句中傳入值 ps.setString(1, book.getName()); ps.setInt(2, book.getQuantity()); // 進行轉換 從util包下的date轉為 sql包下的date ps.setDate(3, new java.sql.Date(book.getTime().getTime())); ps.setBigDecimal(4, book.getPrice()); ps.setInt(5, book.getId()); // 執行語句 ps.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block // 這裏針對異常的處理,蘊含著智慧,十分關鍵! throw new DaoException(e.getMessage(), e); } finally { // 釋放資源 JDBCUtils.free(rs, ps, con); } } /** * 刪除操作 * * */ @Override public void deleteBook(Book book) { // TODO Auto-generated method stub Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { // 註冊驅動並建立連接 con = JDBCUtils.getConnection(); // 創建語句 String sql = "delete from book where id=?"; ps = con.prepareStatement(sql); ps.setInt(1, book.getId()); // 執行語句 ps.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block // 這裏針對異常的處理,蘊含著智慧,十分關鍵! throw new DaoException(e.getMessage(), e); } finally { // 釋放資源 JDBCUtils.free(rs, ps, con); } } /** * 根據查詢結果對Book對象進行賦值,並返回一個賦值好的對象 * */ private Book mappingBook(ResultSet rs) throws SQLException { // 這樣做的好處是:減少代碼重復使用 // 便於以後的優化 Book book = new Book(); book.setId(rs.getInt("id")); book.setName(rs.getString("name")); book.setQuantity(rs.getInt("quantity")); book.setTime(rs.getTimestamp("time")); book.setPrice(rs.getBigDecimal("price")); return book; } }
com.jizuiku.jdbc.domain
- Book
package com.jizuiku.jdbc.domain; import java.math.BigDecimal; /** * Book對象與數據庫的表示對應的 * * @author 博客園-給最苦 * @version V17.11.08 */ public class Book { private int id; private String name; private int quantity; private java.util.Date time; private BigDecimal price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } public java.util.Date getTime() { return time; } public void setTime(java.util.Date time) { this.time = time; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((price == null) ? 0 : price.hashCode()); result = prime * result + quantity; result = prime * result + ((time == null) ? 0 : time.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Book other = (Book) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (price == null) { if (other.price != null) return false; } else if (!price.equals(other.price)) return false; if (quantity != other.quantity) return false; if (time == null) { if (other.time != null) return false; } else if (!time.equals(other.time)) return false; return true; } @Override public String toString() { return "Book [id=" + id + ", name=" + name + ", quantity=" + quantity + ", time=" + time + ", price=" + price + "]"; } }
數據庫中的數據
下面進行 增刪查改 的測試!
com.jizuiku.jdbc.demo
- Demo
刪除測試
package com.jizuiku.jdbc.demo; import java.math.BigDecimal; import java.util.Date; import com.jizuiku.jdbc.dao.BookDao; import com.jizuiku.jdbc.dao.DaoFactory; import com.jizuiku.jdbc.domain.Book; /** * 測試類 * * @author 博客園-給最苦 * @version V17.11.08 */ public class Demo { public static void main(String[] args) { // 使用工廠類,擴展性變得更強! BookDao bookDao = DaoFactory.getInstance().getBookDao(); Book book = new Book(); book.setId(15); // 刪除測試 // 刪除id=15的那條記錄 bookDao.deleteBook(book); System.out.println(book.toString()); } }
運行代碼前數據庫的狀態
運行代碼,控制臺的輸出是
數據庫中的數據發生變動
增加測試
package com.jizuiku.jdbc.demo; import java.math.BigDecimal; import java.util.Date; import com.jizuiku.jdbc.dao.BookDao; import com.jizuiku.jdbc.dao.DaoFactory; import com.jizuiku.jdbc.domain.Book; /** * 測試類 * * @author 博客園-給最苦 * @version V17.11.08 */ public class Demo { public static void main(String[] args) { // 使用工廠類,擴展性變得更強! BookDao bookDao = DaoFactory.getInstance().getBookDao(); Book book = new Book(); book.setName("孟子"); book.setQuantity(40); book.setTime(new Date()); book.setPrice(new BigDecimal(Double.toString(99.99))); // 增加測試完成! bookDao.addBook(book); System.out.println(book.toString()); } }
運行代碼前數據庫的狀態
運行代碼,控制臺的輸出是
數據庫中的數據發生變動
查找測試
package com.jizuiku.jdbc.demo; import java.math.BigDecimal; import java.util.Date; import com.jizuiku.jdbc.dao.BookDao; import com.jizuiku.jdbc.dao.DaoFactory; import com.jizuiku.jdbc.domain.Book; /** * 測試類 * * @author 博客園-給最苦 * @version V17.11.08 */ public class Demo { public static void main(String[] args) { // 使用工廠類,擴展性變得更強! BookDao bookDao = DaoFactory.getInstance().getBookDao(); Book book = new Book(); // 查找測試完成! book = bookDao.getBook(5); System.out.println(book.toString()); } }
數據庫中存儲的數據
運行代碼後,控制臺輸出的結果
註:給最苦 所做的這個查詢是按照 id值來查詢的,結果唯一。給最苦 沒有實現結果不唯一的查詢。
修改測試
package com.jizuiku.jdbc.demo; import java.math.BigDecimal; import java.util.Date; import com.jizuiku.jdbc.dao.BookDao; import com.jizuiku.jdbc.dao.DaoFactory; import com.jizuiku.jdbc.domain.Book; /** * 測試類 * * @author 博客園-給最苦 * @version V17.11.08 */ public class Demo { public static void main(String[] args) { // 使用工廠類,擴展性變得更強! BookDao bookDao = DaoFactory.getInstance().getBookDao(); Book book = new Book(); book.setId(6); book.setName("孟子"); book.setQuantity(40); book.setTime(new Date()); book.setPrice(new BigDecimal(Double.toString(99.99))); // 更改測試完成! // 是根據Id值來更改的 bookDao.updateBook(book); System.out.println(book.toString()); } }
執行代碼前,數據庫的內容
執行代碼後,控制臺的輸出
數據庫的變動
好,博文到這裏就結束了。。。終於結束了。給最苦 都寫累了。
那個《金剛經》上講:“以無我無人無眾生無壽者。修一切善法。”,所以 給最苦 在這裏就不討要個 感恩的心了。但是,還是講如果有心的話,在心裏說聲謝謝唄。雖然 給最苦 的技術很差,這篇博文的水平也只能用來參考。但是,這份堅持把 給最苦 都感動壞了。
還是博文開頭的那句話:
數據、數據,命根就在數據。雲計算、AI等技術,都是以數據為基礎。操作數據庫一定要謹慎小心。給最苦 這裏的代碼,看看就好,要有自己的判斷。遇到抉擇,要不恥上下問。
加油!
學習資源:itcast和itheima視頻庫。如果您有公開的資源,可以分享給我的話,用您的資源學習也可以。
博文是觀看視頻後,融入思考寫成的。博文好,是老師講得好。博文壞,是 給最苦 沒認真。
jdbc-mysql基礎 增刪查改 簡單示例