一、JDBC簡介
JDBC(Java Data Base Connectivity,java數據庫連接)是一種用於執行SQL語句的Java API,可以為多種關系數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基准,據此可以構建更高級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序。JDBC是用於java操作數據庫,如完成數據庫的連接,添加,修改,刪除,查詢等操作。
1.2、工作原理
JDBC API可做三件事:與數據庫建立連接、執行SQL 語句、處理結果
DriverManager :依據數據庫的不同,管理JDBC驅動
Connection :負責連接數據庫並擔任傳送數據的任務
Statement :由 Connection 產生、負責執行SQL語句
ResultSet:負責保存Statement執行后所產生的查詢結果集
1.3、簡單示例
1.3.1、創建表與添加數據

#創建表 CREATE TABLE `stu` ( `id` int NULL AUTO_INCREMENT , `name` varchar(32) NOT NULL , `sex` varchar(4) NULL , `age` int NULL , PRIMARY KEY (`id`) ); #刪除表 drop table stu #添加數據 insert into stu(name,sex,age) values('張學友','男',18); insert into stu(name,sex,age) values('張娜拉','女',73); insert into stu(name,sex,age) values('張家輝','男',23); insert into stu(name,sex,age) values('張匯美','女',85); insert into stu(name,sex,age) values('張鐵林','男',35); insert into stu(name,sex,age) values('張國立','男',99); #2、查詢數據----- #2.1、查詢所有學生 select id,name,sex,age from stu; #2.2、查詢年齡大於80歲女學生 select id,name,sex,age from stu where age>80 and sex='女'; #2.3、查詢平均年齡 select AVG(age) from stu where sex='女'; #3、修改數據----- #3.1、將編號為1的學生年齡加大1歲 update stu set age=age+1 where id=1; #3.2、將80歲以上的女學生年齡修改為90歲且將姓名后增加“老人” #CONCAT(str1,str2,...) 連接字符串 update stu set age=90,name=CONCAT(name,'(老人)') where age>=80 and sex='女'; #3.3、將編號4的學生名字修改為張匯美 update stu set name='張匯美' where id=4; #4、刪除數據----- #4.1、刪除年齡大於70歲的學生 delete from stu where age>70; #4.2、刪除所有學生 delete from stu;
1.3.2、添加引用
請查看第二大點
1.3.3、連接數據庫並查詢所有學生信息
package com.zhangguo.chapter11.demo1; import java.sql.*; public class StudentJDBC { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "uchr@123" ); System.out.println("連接成功"); //查詢所有學生信息,命令對象 PreparedStatement cmd=conn.prepareStatement("select id,name,sex,age from stu"); //執行查詢並返回結果集 ResultSet set=cmd.executeQuery(); //遍歷每一行 while (set.next()) { //取出當前行的id值 System.out.print(set.getInt("id")+"\t"); System.out.print(set.getString("name")+"\t"); System.out.print(set.getString("sex")+"\t"); System.out.print(set.getInt("age")+"\n"); } //關閉結果集 set.close(); } catch (Exception e) { e.printStackTrace(); }finally { try { //關閉連接 conn.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
結果:
二、加載驅動
2.1、下載驅動
https://www.mysql.com/products/connector/
2.2、在java應用程序中引入jar驅動包
//加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
三、獲取數據庫連接
//獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功");
四、Java實現數據庫訪問
package com.zhangguo.chapter11.demo1; import java.sql.*; public class StudentJDBC { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功"); //查詢所有學生信息,命令對象 PreparedStatement cmd=conn.prepareStatement("select id,name,sex,age from stu"); //執行查詢並返回結果集 ResultSet set=cmd.executeQuery(); //遍歷每一行 while (set.next()) { //取出當前行的id值 System.out.print(set.getInt("id")+"\t"); System.out.print(set.getString("name")+"\t"); System.out.print(set.getString("sex")+"\t"); System.out.print(set.getInt("age")+"\n"); } //關閉結果集 set.close(); } catch (Exception e) { e.printStackTrace(); }finally { try { //關閉連接 conn.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
4.1、增刪改
4.1.1、增加
package com.zhangguo.chapter11.demo1; import java.sql.*; public class StudentCRUD { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功"); //執行添加 PreparedStatement cmd=conn.prepareStatement("insert into stu(name,sex,age) values('張衛健','男',45);"); //執行操作並返回影響行數 int n=cmd.executeUpdate(); System.out.println("影響行數:"+n); //釋放命令對象 cmd.close(); } catch (Exception e) { e.printStackTrace(); }finally { try { //關閉連接 conn.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
4.1.2、更新
將id為8的name與sex修改
package com.zhangguo.chapter11.demo1; import java.sql.*; public class StudentUpdate { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功"); //執行更新 PreparedStatement cmd=conn.prepareStatement("update stu set name='張一山',sex='男' where id=8"); //執行操作並返回影響行數 int n=cmd.executeUpdate(); System.out.println("影響行數:"+n); //釋放命令對象 cmd.close(); } catch (Exception e) { e.printStackTrace(); }finally { try { //關閉連接 conn.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
結果:
4.1.3、刪除
package com.zhangguo.chapter11.demo1; import java.sql.*; public class StudentDelete { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功"); //執行刪除 PreparedStatement cmd=conn.prepareStatement("delete from stu where id=8"); //執行操作並返回影響行數 int n=cmd.executeUpdate(); System.out.println("影響行數:"+n); //釋放命令對象 cmd.close(); } catch (Exception e) { e.printStackTrace(); }finally { try { //關閉連接 conn.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
結果:
4.2、查詢
4.2.1、查詢結果集
#查詢所有女生的姓名與年齡
select name,age from stu where sex='女'
package com.zhangguo.chapter11.demo1; import java.sql.*; public class StudentSelect { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; ResultSet resultset=null; PreparedStatement cmd=null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功"); //查詢所有女生的姓名與年齡 cmd=conn.prepareStatement("select name,age from stu where sex='女'"); //執行查詢返回結果集 resultset=cmd.executeQuery(); //獲取數據,遍歷,指針下移 while (resultset.next()) { System.out.println(resultset.getString("name")+"\t"+resultset.getInt("age")); } } catch (Exception e) { e.printStackTrace(); }finally { try { //釋放對象 if(conn!=null)conn.close(); if(cmd!=null)cmd.close(); if(resultset!=null)resultset.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
4.2.2、查詢單行單列數據
package com.zhangguo.chapter11.demo1; import java.sql.*; public class StudentSelect2 { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; ResultSet resultset=null; PreparedStatement cmd=null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功"); //查詢男生人數 cmd=conn.prepareStatement("select count(*) from stu where sex='男'"); //執行查詢返回結果集 resultset=cmd.executeQuery(); //獲取數據,遍歷,指針下移 if(resultset.next()) { //根據索引獲取當前行的數據,1表示第幾列 System.out.println("男生數:"+resultset.getInt(1)); } } catch (Exception e) { e.printStackTrace(); }finally { try { //釋放對象 if(conn!=null)conn.close(); if(cmd!=null)cmd.close(); if(resultset!=null)resultset.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
結果:
4.3、帶參數
sql語句中的字符如果來自用戶,則可能會拼接sql,拼接字符串的做法很不安全,可以使用帶參數的命令。
4.3.1、添加學員 - 拼接
package com.zhangguo.chapter11.demo1; import java.sql.*; import java.util.Scanner; public class StudentParam1 { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; PreparedStatement cmd=null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功"); Scanner input=new Scanner(System.in); System.out.print("請輸入姓名:"); String name=input.next(); System.out.print("請輸入性別:"); String sex=input.next(); System.out.print("請輸入年齡:"); int age=input.nextInt(); //查詢男生人數 cmd=conn.prepareStatement("insert into stu(name,sex,age) values('"); //執行添加 int n=cmd.executeUpdate(); System.out.println("影響行數:"+n); } catch (Exception e) { e.printStackTrace(); }finally { try { //釋放對象 if(conn!=null)conn.close(); if(cmd!=null)cmd.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
4.3.2、添加學員 - 參數
package com.zhangguo.chapter11.demo1; import java.sql.*; import java.util.Scanner; public class StudentParam2 { //加載驅動 static{ try { //反射獲得類型 Class.forName( "com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //連接對象 Connection conn = null; PreparedStatement cmd=null; try { //獲得連接對象,school數據庫名,root用戶名,uchr@123密碼 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123" ); System.out.println("連接成功"); Scanner input=new Scanner(System.in); System.out.print("請輸入姓名:"); String name=input.next(); System.out.print("請輸入性別:"); String sex=input.next(); System.out.print("請輸入年齡:"); int age=input.nextInt(); //查詢男生人數 cmd=conn.prepareStatement("insert into stu(name,sex,age) values(?,?,?);"); //指定參數 cmd.setString(1, name); cmd.setString(2, sex); cmd.setInt(3, age); //執行添加 int n=cmd.executeUpdate(); System.out.println("影響行數:"+n); } catch (Exception e) { e.printStackTrace(); }finally { try { //釋放對象 if(conn!=null)conn.close(); if(cmd!=null)cmd.close(); System.out.println("關閉成功"); } catch (Exception e) { e.printStackTrace(); } } } }
4.4、封裝
從前面的示例中可以看出如果數據庫訪問的代碼(腳本)存在大量的冗余,操作模式基本相同,對數據庫訪問進行封裝可以實現代碼的可復用、可擴展、可維護。
結合反射對JDBC的數據庫訪問封裝如下:
學生實體類Stu.java:
package com.zhangguo.util.test; /** * Java Bean (java 豆子) * 實體類 * */ public class Stu { public Stu(int id, String name, String sex, int age) { super(); this.id = id; this.name = name; this.sex = sex; this.age = age; } public Stu(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } public Stu() { } private int id; private String name; private String sex; private int age; 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
JDBCUtils數據庫訪問封裝
package com.zhangguo.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class JDBCUtils { public static String DRIVER="com.mysql.jdbc.Driver"; public static String URL="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8"; public static String USER_NAME="root"; public static String PASSWORD="uchr@123"; //加載驅動 static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } private JDBCUtils() { } /** * 獲得連接 * * @return */ public static Connection getconnnection() { Connection con = null; try { con = DriverManager.getConnection(URL, USER_NAME, PASSWORD); } catch (SQLException e) { e.printStackTrace(); } return con; } /** * 關閉連接 * * @param rs * @param st * @param con */ public static void close(ResultSet rs, Statement st, Connection con) { try { try { if (rs != null) { rs.close(); } } finally { try { if (st != null) { st.close(); } } finally { if (con != null) con.close(); } } } catch (SQLException e) { e.printStackTrace(); } } /** * 關閉連接 * * @param rs */ public static void close(ResultSet rs) { Statement st = null; Connection con = null; try { try { if (rs != null) { st = rs.getStatement(); rs.close(); } } finally { try { if (st != null) { con = st.getConnection(); st.close(); } } finally { if (con != null) { con.close(); } } } } catch (SQLException e) { e.printStackTrace(); } } /** * 關閉連接 * * @param st * @param con */ public static void close(Statement st, Connection con) { try { try { if (st != null) { st.close(); } } finally { if (con != null) con.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * insert/update/delete * 增加/更新/刪除 * * @param sql 數據庫語句 * @param args 可變參數(可以不帶參數,可以帶0-n個參數) * @return */ public static int update(String sql, Object... args) { int result = 0; Connection con = getconnnection(); PreparedStatement ps = null; try { ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } result = ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { close(ps, con); } return result; } /** * query, because need to manually close the resource, so not recommended * for use it * * @param sql * @param args * @return ResultSet */ @Deprecated //注解 public static ResultSet query(String sql, Object... args) { ResultSet result = null; Connection con = getconnnection(); PreparedStatement ps = null; try { ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } result = ps.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return result; } /** * Query a single record * 查詢單個記錄 * @param sql * @param args * @return Map<String,Object> */ public static Map<String, Object> queryForMap(String sql, Object... args) { Map<String, Object> result = new HashMap<String, Object>(); List<Map<String, Object>> list = queryForList(sql, args); if (list.size() > 0) { result = list.get(0); } return result; } /** * Query a single record * 查詢單個記錄返回強類型對象 * @param sql * @param args * @return <T> //泛型 */ public static <T> T queryForObject(String sql, Class<T> clz, Object... args) { T result = null; List<T> list = queryForList(sql, clz, args); if (list.size() > 0) { result = list.get(0); } return result; } /** * Query a single record * * @param sql * @param args * @return List<Map<String,Object>> */ public static List<Map<String, Object>> queryForList(String sql, Object... args) { List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); Connection con = null; ResultSet rs = null; PreparedStatement ps = null; try { con = getconnnection(); ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { Map<String, Object> map = new HashMap<String, Object>(); for (int i = 1; i <= columnCount; i++) { map.put(rsmd.getColumnLabel(i), rs.getObject(i)); } result.add(map); } } catch (SQLException e) { e.printStackTrace(); } finally { close(rs, ps, con); } return result; } /** * Query records * 查詢多個對象,返回強類型集合 * @param sql * @param args * @return List<T> */ public static <T> List<T> queryForList(String sql, Class<T> clz, Object... args) { List<T> result = new ArrayList<T>(); Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con = getconnnection(); ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { T obj = clz.newInstance(); for (int i = 1; i <= columnCount; i++) { String columnName = rsmd.getColumnName(i); String methodName = "set" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1, columnName.length()); Method method[] = clz.getMethods(); for (Method meth : method) { if (methodName.equals(meth.getName())) { meth.invoke(obj, rs.getObject(i)); } } } result.add(obj); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { close(rs, ps, con); } return result; } }
測試:
package com.zhangguo.util.test; import java.util.List; import com.zhangguo.util.JDBCUtils; public class JDBCUtilTest { public static void main(String[] args) { //增加 int n=JDBCUtils.update("insert into stu(name,sex,age) values(?,?,?)", "王娜菲","男",87); System.out.println("成功添加:"+n+"行"); //修改 JDBCUtils.update("update stu set name='李娜娜' where id=?",7); //刪除 JDBCUtils.update("delete from stu where id=?",10); //查詢 List<Stu> stus=JDBCUtils.queryForList("select id,name,age,sex from stu where age>? and name like ?", Stu.class,18,"%娜%"); //遍歷學生集合 for (Stu stu : stus) { System.out.println(stu.getName()+"\t"+stu.getSex()+"\t"+stu.getAge()); } } }
運行結果:
五、DVD租賃系統JDBC版
5.1、數據庫
/* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50506 Source Host : localhost:3306 Source Database : dvdstore Target Server Type : MYSQL Target Server Version : 50506 File Encoding : 65001 Date: 2017-06-08 11:31:13 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `dvd` -- ---------------------------- DROP TABLE IF EXISTS `dvd`; CREATE TABLE `dvd` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '編號', `name` varchar(64) NOT NULL COMMENT '名稱', `price` double DEFAULT NULL COMMENT '價格', `isRent` int(11) DEFAULT NULL COMMENT '是否借出', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of dvd -- ---------------------------- INSERT INTO `dvd` VALUES ('2', '異形', '75.3', '0'); INSERT INTO `dvd` VALUES ('3', '暗戰', '19.5', '1'); INSERT INTO `dvd` VALUES ('4', '戰狼', '9.98', '0');
5.2、實現類
DVD.java
package com.zhangguo.dvd.v2; /** 光碟 實體 模型 */ public class DVD { /** 構造方法 */ public DVD(int _id, String _name, double _price, int _isRent) { this.id = _id; this.name = _name; this.price = _price; this.isRent = _isRent; } public DVD(String _name, double _price, int _isRent) { this.name = _name; this.price = _price; this.isRent = _isRent; } public DVD() { } /** 編號 */ private int id; /** 名稱 */ private String name; /** 價格 */ private double price; /** 是否被借出 0未借出 1借出 */ private int isRent; 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 double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getIsRent() { return isRent; } public void setIsRent(int isRent) { this.isRent = isRent; } @Override public String toString() { return ("編號:" + this.id + "\t\t" + "名稱:" + this.name + "\t\t" + "價格:" + this.price + "\t\t" + "借出:" + (this.isRent==1 ? "是" : "否")); } }
DVDService.java
package com.zhangguo.dvd.v2; import java.util.List; /** DVD服務類,完成數據庫訪問 */ public class DVDService { /**添加DVD到數據庫**/ public int add(DVD dvd){ return JDBCUtils.update("insert into dvd(name,price,isRent) values(?,?,?);", dvd.getName(),dvd.getPrice(),dvd.getIsRent()); } /**刪除DVD**/ public int del(int id){ return JDBCUtils.update("delete from dvd where id=?", id); } /**更新DVD到數據庫**/ public int update(DVD dvd){ return JDBCUtils.update("update dvd set name=?,price=?,isRent=? where id=?", dvd.getName(),dvd.getPrice(),dvd.getIsRent(),dvd.getId()); } /**獲得所有DVD信息*/ public List<DVD> getAll(){ return JDBCUtils.queryForList("select id,name,price,isRent from dvd", DVD.class); } /**獲得DVD信息通過狀態*/ public List<DVD> getAll(int isRent){ return JDBCUtils.queryForList("select id,name,price,isRent from dvd where isRent=?", DVD.class,isRent); } /**根據DVD編號獲得單個DVD*/ public DVD get(int id){ return JDBCUtils.queryForObject("select id,name,price,isRent from dvd where id=?", DVD.class, id); } /**根據DVD編號更新指定狀態*/ public int edit(int id,int isRent){ return JDBCUtils.update("update dvd set isRent=? where id=?", isRent,id); } }
DVDStore.java
package com.zhangguo.dvd.v2; import java.util.List; import java.util.Scanner; public class DVDStore { /** 數據訪問 */ public DVDService service = new DVDService(); /** 掃描器 */ Scanner input = new Scanner(System.in); /** 菜單 */ public void menu() { $("***************************DVD小店歡迎您***************************"); $("1、顯示DVD"); $("2、借出DVD"); $("3、歸還DVD"); $("4、添加DVD"); $("5、刪除DVD"); $("6、編輯DVD"); $("7、退出系統"); $("***************************DVD小店歡迎您***************************"); $$("請選擇[1-7]:"); int index = input.nextInt(); switch (index) { case 1: fun1(); break; case 2: fun2(1); break; case 3: fun3(0); break; case 4: fun4(); break; case 5: fun5(); break; case 6: fun6(); break; case 7: fun7(); break; default: $("輸入有誤,請重輸"); break; } menu(); } /** 6、編輯DVD */ private void fun6() { $$("編號:"); int _id = input.nextInt(); $$("名稱:"); String _name = input.next(); $$("價格:"); double _price = input.nextDouble(); $$("借出[0/1]:"); int _isRent = input.nextInt(); DVD dvd = service.get(_id); if (_name != null && !_name.equals("")) { dvd.setName(_name); } if (_price > 0) { dvd.setPrice(_price); } if (_isRent >= 0) { dvd.setIsRent(_isRent); } int n = service.update(dvd); if (n > 0) { $("更新成功"); } else { $("更新失敗"); } } /** 7、退出系統 */ private void fun7() { $$("歡迎您下次光臨!"); System.exit(0); } /** 5、刪除DVD */ private void fun5() { if (fun1() > 0) { $$("請輸入要刪除的編號:"); int id = input.nextInt(); int n = service.del(id); if (n > 0) { $("刪除成功"); } else { $("刪除失敗"); } } else { $("您的商店沒有任何DVD,現在添加"); } } /** 2、借出DVD */ private void fun2(int isRent) { if (show(0) > 0) { $$("請輸入要操作的編號:"); int id = input.nextInt(); int n = service.edit(id, isRent); if (n > 0) { $("操作成功"); } else { $("操作失敗"); } } else { $("沒有可以借出的DVD"); } } /** 3、歸還DVD */ private void fun3(int isRent) { if (show(1) > 0) { $$("請輸入要操作的編號:"); int id = input.nextInt(); int n = service.edit(id, isRent); if (n > 0) { $("操作成功"); } else { $("操作失敗"); } } else { $("沒有需要歸還的DVD"); } } /** 1、顯示DVD */ private int fun1() { List<DVD> dvds = service.getAll(); for (DVD dvd : service.getAll()) { $(dvd); } return dvds.size(); } /** 顯示指定狀態的DVD */ private int show(int isRent) { List<DVD> dvds = service.getAll(isRent); for (DVD dvd : dvds) { $(dvd); } return dvds.size(); } /** 4、添加DVD */ private void fun4() { $$("名稱:"); String _name = input.next(); $$("價格:"); double _price = input.nextDouble(); $$("借出[0/1]:"); int _isRent = input.nextInt(); service.add(new DVD(_name, _price, _isRent)); $("添加成功"); } /** 工具方法 */ public void $(Object obj) { System.out.println(obj); } public void $$(Object obj) { System.out.print(obj); } }
JDBCUtils.java
package com.zhangguo.dvd.v2; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class JDBCUtils { public static String DRIVER="com.mysql.jdbc.Driver"; public static String URL="jdbc:mysql://localhost:3306/dvdstore?useUnicode=true&characterEncoding=UTF-8"; public static String USER_NAME="root"; public static String PASSWORD="uchr@123"; //加載驅動 static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } private JDBCUtils() { } /** * 獲得連接 * * @return */ public static Connection getconnnection() { Connection con = null; try { con = DriverManager.getConnection(URL, USER_NAME, PASSWORD); } catch (SQLException e) { e.printStackTrace(); } return con; } /** * 關閉連接 * * @param rs * @param st * @param con */ public static void close(ResultSet rs, Statement st, Connection con) { try { try { if (rs != null) { rs.close(); } } finally { try { if (st != null) { st.close(); } } finally { if (con != null) con.close(); } } } catch (SQLException e) { e.printStackTrace(); } } /** * 關閉連接 * * @param rs */ public static void close(ResultSet rs) { Statement st = null; Connection con = null; try { try { if (rs != null) { st = rs.getStatement(); rs.close(); } } finally { try { if (st != null) { con = st.getConnection(); st.close(); } } finally { if (con != null) { con.close(); } } } } catch (SQLException e) { e.printStackTrace(); } } /** * 關閉連接 * * @param st * @param con */ public static void close(Statement st, Connection con) { try { try { if (st != null) { st.close(); } } finally { if (con != null) con.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * insert/update/delete * 增加/更新/刪除 * * @param sql 數據庫語句 * @param args 可變參數(可以不帶參數,可以帶0-n個參數) * @return */ public static int update(String sql, Object... args) { int result = 0; Connection con = getconnnection(); PreparedStatement ps = null; try { ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } result = ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { close(ps, con); } return result; } /** * query, because need to manually close the resource, so not recommended * for use it * * @param sql * @param args * @return ResultSet */ @Deprecated //注解 public static ResultSet query(String sql, Object... args) { ResultSet result = null; Connection con = getconnnection(); PreparedStatement ps = null; try { ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } result = ps.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return result; } /** * Query a single record * 查詢單個記錄 * @param sql * @param args * @return Map<String,Object> */ public static Map<String, Object> queryForMap(String sql, Object... args) { Map<String, Object> result = new HashMap<String, Object>(); List<Map<String, Object>> list = queryForList(sql, args); if (list.size() > 0) { result = list.get(0); } return result; } /** * Query a single record * 查詢單個記錄返回強類型對象 * @param sql * @param args * @return <T> //泛型 */ public static <T> T queryForObject(String sql, Class<T> clz, Object... args) { T result = null; List<T> list = queryForList(sql, clz, args); if (list.size() > 0) { result = list.get(0); } return result; } /** * Query a single record * * @param sql * @param args * @return List<Map<String,Object>> */ public static List<Map<String, Object>> queryForList(String sql, Object... args) { List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); Connection con = null; ResultSet rs = null; PreparedStatement ps = null; try { con = getconnnection(); ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { Map<String, Object> map = new HashMap<String, Object>(); for (int i = 1; i <= columnCount; i++) { map.put(rsmd.getColumnLabel(i), rs.getObject(i)); } result.add(map); } } catch (SQLException e) { e.printStackTrace(); } finally { close(rs, ps, con); } return result; } /** * Query records * 查詢多個對象,返回強類型集合 * @param sql * @param args * @return List<T> */ public static <T> List<T> queryForList(String sql, Class<T> clz, Object... args) { List<T> result = new ArrayList<T>(); Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con = getconnnection(); ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { T obj = clz.newInstance(); for (int i = 1; i <= columnCount; i++) { String columnName = rsmd.getColumnName(i); String methodName = "set" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1, columnName.length()); Method method[] = clz.getMethods(); for (Method meth : method) { if (methodName.equals(meth.getName())) { meth.invoke(obj, rs.getObject(i)); } } } result.add(obj); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { close(rs, ps, con); } return result; } }
NFDVDStore.java
package com.zhangguo.dvd.v2; public class NFDVDStore { public static void main(String[] args) { DVDStore ds=new DVDStore(); ds.menu(); } }
5.3、運行結果
***************************DVD小店歡迎您***************************
1、顯示DVD
2、借出DVD
3、歸還DVD
4、添加DVD
5、刪除DVD
6、編輯DVD
7、退出系統
***************************DVD小店歡迎您***************************
請選擇[1-7]:4
名稱:鏡子
價格:19.3
借出[0/1]:0
添加成功
***************************DVD小店歡迎您***************************
1、顯示DVD
2、借出DVD
3、歸還DVD
4、添加DVD
5、刪除DVD
6、編輯DVD
7、退出系統
***************************DVD小店歡迎您***************************
請選擇[1-7]:1
編號:2 名稱:異形 價格:75.3 借出:否
編號:3 名稱:暗戰 價格:19.5 借出:是
編號:4 名稱:戰狼 價格:9.98 借出:否
編號:8 名稱:鏡子 價格:19.3 借出:否
***************************DVD小店歡迎您***************************
1、顯示DVD
2、借出DVD
3、歸還DVD
4、添加DVD
5、刪除DVD
6、編輯DVD
7、退出系統
***************************DVD小店歡迎您***************************
請選擇[1-7]:2
編號:2 名稱:異形 價格:75.3 借出:否
編號:4 名稱:戰狼 價格:9.98 借出:否
編號:8 名稱:鏡子 價格:19.3 借出:否
請輸入要操作的編號:8
操作成功
***************************DVD小店歡迎您***************************
1、顯示DVD
2、借出DVD
3、歸還DVD
4、添加DVD
5、刪除DVD
6、編輯DVD
7、退出系統
***************************DVD小店歡迎您***************************
請選擇[1-7]:3
編號:3 名稱:暗戰 價格:19.5 借出:是
編號:8 名稱:鏡子 價格:19.3 借出:是
請輸入要操作的編號:8
操作成功
***************************DVD小店歡迎您***************************
1、顯示DVD
2、借出DVD
3、歸還DVD
4、添加DVD
5、刪除DVD
6、編輯DVD
7、退出系統
***************************DVD小店歡迎您***************************
請選擇[1-7]:1
編號:2 名稱:異形 價格:75.3 借出:否
編號:3 名稱:暗戰 價格:19.5 借出:是
編號:4 名稱:戰狼 價格:9.98 借出:否
編號:8 名稱:鏡子 價格:19.3 借出:否
***************************DVD小店歡迎您***************************
1、顯示DVD
2、借出DVD
3、歸還DVD
4、添加DVD
5、刪除DVD
6、編輯DVD
7、退出系統
***************************DVD小店歡迎您***************************
請選擇[1-7]:8
輸入有誤,請重輸
***************************DVD小店歡迎您***************************
1、顯示DVD
2、借出DVD
3、歸還DVD
4、添加DVD
5、刪除DVD
6、編輯DVD
7、退出系統
***************************DVD小店歡迎您***************************
六、下載與視頻
第一次課示例:
http://files.cnblogs.com/files/best/Chapter11.zip
第三次課示例:
http://files.cnblogs.com/files/best/GoMall.zip
139班上課示例1
http://files.cnblogs.com/files/best/Chapter11_136_V2.zip
不斷更新的視頻:
http://search.bilibili.com/all?keyword=%E5%BC%A0%E6%9E%9C&from_source=banner_search
七、面試題
7.1、請使用JDBC完成產品表Product(編號id,title名稱,price價格,address產地)的訪問。從控制台完成添加產品,修改產品,刪除產品,顯示產品功能。可以增加產品狀態(State)
7.2、請完成DVD租賃系統
參考示例(139)
八、原生JDBC示例
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; public class JdbcTest { // 1、添加jar驅動包 // 2、加載驅動類 static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { //insert(); select(); } // 添加 public static int insert() { int n = 0; try { // 3、獲得連接對象 Connection conn = DriverManager .getConnection( "jdbc:mysql://localhost:3306/dvdshop?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123"); // 4、創建SQL命令對象 PreparedStatement cmd = conn .prepareStatement("insert into dvd(name,price,state) values(?,?,?);"); //ORM cmd.setObject(1, "征服"); cmd.setObject(2, 98.1); cmd.setObject(3, 0); // 5、執行sql,返回影響行數 n = cmd.executeUpdate(); // 6、釋放資源 cmd.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } return n; } public static void select() { try { // 3、獲得連接對象 Connection conn = DriverManager .getConnection( "jdbc:mysql://localhost:3306/uchr?useUnicode=true&characterEncoding=UTF-8", "root", "uchr@123"); // 4、創建SQL命令對象 PreparedStatement cmd = conn .prepareStatement("select * from list_values"); // 5、執行sql查詢 ResultSet result = cmd.executeQuery(); // 6、取得結果集中的數據 while (result.next()) { System.out.print(result.getString(1) + "\t"); System.out.print(result.getString(2)); System.out.println(); } // 7、釋放資源 result.close(); cmd.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } }