Java數據庫小項目00---基礎知識


目錄

JDBC的簡單使用

向JDBC注入攻擊

防止注入攻擊

自建JDBC工具類

自建工具類優化--使用配置文件

使用數據庫連接池優化工具類

 

 

 

 

JDBC的簡單使用

 1 package Test;
 2 
 3 import java.sql.Connection;
 4 import java.sql.Driver;
 5 import java.sql.DriverManager;
 6 import java.sql.DriverPropertyInfo;
 7 import java.sql.ResultSet;
 8 import java.sql.SQLException;
 9 import java.sql.Statement;
10 
11 
12 /*JDBCsun公司提供的一套標准數據庫操作規范
13  * JDBC使用步驟
14  * 1 注冊驅動--告訴JVM使用的是哪一個數據庫
15  * 2 獲得連接--使用JDBC中的類完成對MySQL數據庫的連接
16  * 3 獲得語句執行平台--通過連接對象獲取SQL語句1的執行者對象
17  * 4 執行sql語句--使用執行者對象向數據庫執行SQL語句,並獲取執行后的結果
18  * 5 處理結果
19  * 6 釋放資源
20  * ----------在使用之前一定要先導入jar包
21  */
22 
23 public class Main{
24     public static void main(String[] args) throws ClassNotFoundException, SQLException {
25         //1 注冊驅動,但查看源碼發現這樣會注冊兩次
26         //DriverManager.registerDriver(new Driver());
27         //使用反射技術注冊,在這里類名可能找不到因此拋出類名查不到的異常
28         Class.forName("com.mysql.jdbc.Driver");
29         
30         //2連接數據庫  url:數據庫 jdbc:jdbc:mysql://連接主機IP:端口號//數據庫名
31         String url ="jdbc:mysql://localhost:3306/mybase";
32         String username="root";//用戶名
33         String password="123";//密碼
34         //連接,可能連接不到拋出SQL異常
35         Connection con =DriverManager.getConnection(url, username,password);
36         
37         //3 獲得語句執行平台,通過數據庫連接對象獲得SQL語句的執行者對象,注意導包為sql的包
38         Statement stat=con.createStatement();
39         //查詢語句
40         String sql ="Select * from titles";
41         
42         //4 調用執行者對象方法,執行SQL語句獲取結果集
43         ResultSet rs=stat.executeQuery(sql);
44         //5 處理結果集
45         while(rs.next()){
46             System.out.println(rs.getString("emp_no")+"  "+rs.getString("title"));
47         }
48         
49         //6 釋放資源
50         rs.close();
51         stat.close();
52         con.close();
53     }
54 }

 向JDBC注入攻擊

創建數據表

1 CREATE TABLE users(
2 username VARCHAR(20),
3 PASSWORD VARCHAR(10)
4 );
5 
6 INSERT INTO users VALUES('a','1'),('b','2');

 待注入攻擊的代碼:

 1 package Test;
 2 
 3 import java.sql.Connection;
 4 import java.sql.Driver;
 5 import java.sql.DriverManager;
 6 import java.sql.DriverPropertyInfo;
 7 import java.sql.ResultSet;
 8 import java.sql.SQLException;
 9 import java.sql.Statement;
10 import java.util.Scanner;
11 
12 
13 /*MySQL注入攻擊
14  * 用戶登錄案例
15  */
16 
17 public class Main{
18     public static void main(String[] args) throws ClassNotFoundException, SQLException {
19         Class.forName("com.mysql.jdbc.Driver");
20         
21         //2連接數據庫  url:數據庫 jdbc:jdbc:mysql://連接主機IP:端口號//數據庫名
22         String url ="jdbc:mysql://localhost:3306/mybase";
23         String username="root";//用戶名
24         String password="123";//密碼
25         Connection con =DriverManager.getConnection(url, username,password);        
26         Statement stat=con.createStatement();
27         //查詢語句
28         Scanner sc=new Scanner(System.in);
29         String user=sc.next();
30         String pass=sc.next();
31         String sql ="Select * from users where username= '"+user+"' and password= '"+pass+"'";
32         
33         //4 調用執行者對象方法,執行SQL語句獲取結果集
34         ResultSet rs=stat.executeQuery(sql);
35         System.out.println(sql);
36         //5 處理結果集
37         while(rs.next()){
38             System.out.println(rs.getString("username")+"  "+rs.getString("password"));
39         }
40         
41         //6 釋放資源
42         rs.close();
43         stat.close();
44         con.close();
45     }
46 }

 代碼運行結果:

攻擊的原理:

利用SQL語句:Select * from users where username= 'a' and password= '1'or'1=1',這樣由於最后一個是或運算那么就會顯示出來所有的數據,因此在輸入時只要想辦法湊成這樣的形式就可以了。

輸入:aa 12'or'1=1  這樣便可以完成攻擊,即使輸入的用戶名不對也可以正常登陸。

防止注入攻擊

 1 package Test;
 2 
 3 import java.sql.Connection;
 4 import java.sql.Driver;
 5 import java.sql.DriverManager;
 6 import java.sql.DriverPropertyInfo;
 7 import java.sql.PreparedStatement;
 8 import java.sql.ResultSet;
 9 import java.sql.SQLException;
10 import java.sql.Statement;
11 import java.util.Scanner;
12 
13 /*MySQL防止注入攻擊--采用statement的子類preparedstatement
14  * 還可以用占位符實現增刪改查等操作
15  */
16 
17 public class Main{
18     public static void main(String[] args) throws ClassNotFoundException, SQLException {
19         Class.forName("com.mysql.jdbc.Driver");
20         
21         //2連接數據庫  url:數據庫 jdbc:jdbc:mysql://連接主機IP:端口號//數據庫名
22         String url ="jdbc:mysql://localhost:3306/mybase";
23         String username="root";//用戶名
24         String password="123";//密碼
25         Connection con =DriverManager.getConnection(url, username,password);        
26         
27         //查詢語句
28         Scanner sc=new Scanner(System.in);
29         String user=sc.next();
30         String pass=sc.next();
31         //用?占位符代替參數
32         String sql ="Select * from users where username=? and password= ?";
33         PreparedStatement pds=con.prepareStatement(sql);
34         pds.setObject(1, user);
35         pds.setObject(2, pass);
36         //4 調用執行者對象方法,執行SQL語句獲取結果集
37         ResultSet rs=pds.executeQuery();
38         System.out.println(sql);
39         //5 處理結果集
40         while(rs.next()){
41             System.out.println(rs.getString("username")+"  "+rs.getString("password"));
42         }
43         
44         //6 釋放資源
45         rs.close();
46         pds.close();
47         con.close();
48     }
49 }

 自建JDBC工具類

JDBCUtils.class文件

 1 package Test;
 2 
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import java.sql.Statement;
 8 
 9 public class JDBCUtils {
10     private JDBCUtils(){}
11     private static Connection con;
12     
13     static{
14         try {
15             Class.forName("com.mysql.jdbc.Driver");
16             //2連接數據庫  url:數據庫 jdbc:jdbc:mysql://連接主機IP:端口號//數據庫名
17             String url ="jdbc:mysql://localhost:3306/mybase";
18             String username="root";//用戶名
19             String password="123";//密碼
20             con =DriverManager.getConnection(url, username,password);
21         } catch (Exception e) {
22             throw new RuntimeException(e+"數據庫連接失敗!");
23         }            
24     }
25     //定義靜態方法,返回數據庫的連接對象
26     public static Connection getConnection(){
27         return con;
28     }    
29     
30     //釋放資源    
31     public static void close(Connection con,Statement stat){
32         if(stat!=null){
33              try {
34                  stat.close();
35             } catch (SQLException e) {
36                 // TODO Auto-generated catch block
37                 e.printStackTrace();
38             }
39         }
40         
41         if(con!=null){
42              try {
43                 con.close();
44             } catch (SQLException e) {
45                 // TODO Auto-generated catch block
46                 e.printStackTrace();
47             }
48         }
49     }
50     //重載,關閉結果集
51     public static void close(Connection con,Statement stat,ResultSet rs){
52         //注意釋放的順序
53         if(rs!=null){
54              try {
55                 rs.close();
56             } catch (SQLException e) {
57                 // TODO Auto-generated catch block
58                 e.printStackTrace();
59             }
60         }
61         
62         if(stat!=null){
63              try {
64                  stat.close();
65             } catch (SQLException e) {
66                 // TODO Auto-generated catch block
67                 e.printStackTrace();
68             }
69         }
70         
71         if(con!=null){
72              try {
73                 con.close();
74             } catch (SQLException e) {
75                 // TODO Auto-generated catch block
76                 e.printStackTrace();
77             }
78         }
79     }
80 }

測試代碼:

 1 package Test;
 2 
 3 import java.sql.Connection;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import Test.JDBCUtils;
 8 
 9 public class JDBCTset {
10     public static void main(String[] args) throws SQLException {
11         Connection con =JDBCUtils.getConnection();
12         PreparedStatement pst=con.prepareStatement("SELECT * FROM titles");
13         ResultSet rs =pst.executeQuery();
14         while(rs.next()){
15             System.out.println(rs.getString("title"));
16         }
17         //釋放資源
18         JDBCUtils.close(con, pst);
19     }
20 }

自建工具類優化--使用配置文件

優化代碼

  1 package Test;
  2 
  3 import java.io.IOException;
  4 import java.io.InputStream;
  5 
  6 /*在前面的代碼中由於數據庫用戶名,密碼直接在靜態代碼塊中,相當於寫死了代碼,不容易修改
  7  * 因此采用properties配置文件,方便后期維護。配置文件建議放在src下,方便自動拷貝bin目錄下
  8  * 
  9  */
 10 
 11 import java.sql.Connection;
 12 import java.sql.DriverManager;
 13 import java.sql.ResultSet;
 14 import java.sql.SQLException;
 15 import java.sql.Statement;
 16 import java.util.Properties;
 17 
 18 public class JDBCUtils {
 19     private JDBCUtils(){}
 20     private static Connection con;
 21     private static String driverClass;
 22     private static String url;
 23     private static String username;
 24     private static String password;
 25     //放到靜態代碼塊中保證讀取配置文件,獲取連接只執行一次
 26     static{
 27         try{
 28             readConfig();
 29             //反射
 30             Class.forName(driverClass);
 31             con=DriverManager.getConnection(url,username,password);
 32         }catch(Exception e){
 33             throw new RuntimeException("數據庫連接失敗!");
 34         }
 35         
 36     }
 37     
 38     private static void readConfig() throws IOException{
 39         //通過字節流,使用類加載器讀取配置文件的內容
 40         InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("database.properties");
 41         Properties pro = new Properties();
 42         pro.load(in);
 43         driverClass=pro.getProperty("driverClass");
 44         url = pro.getProperty("url");
 45         username=pro.getProperty("username");
 46         password=pro.getProperty("password");
 47     }
 48     
 49     //定義靜態方法,返回數據庫的連接對象
 50     public static Connection getConnection(){
 51         return con;
 52     }    
 53     
 54     //釋放資源    
 55     public static void close(Connection con,Statement stat){
 56         if(stat!=null){
 57              try {
 58                  stat.close();
 59             } catch (SQLException e) {
 60                 // TODO Auto-generated catch block
 61                 e.printStackTrace();
 62             }
 63         }
 64         
 65         if(con!=null){
 66              try {
 67                 con.close();
 68             } catch (SQLException e) {
 69                 // TODO Auto-generated catch block
 70                 e.printStackTrace();
 71             }
 72         }
 73     }
 74     //重載,關閉結果集
 75     public static void close(Connection con,Statement stat,ResultSet rs){
 76         //注意釋放的順序
 77         if(rs!=null){
 78              try {
 79                 rs.close();
 80             } catch (SQLException e) {
 81                 // TODO Auto-generated catch block
 82                 e.printStackTrace();
 83             }
 84         }
 85         
 86         if(stat!=null){
 87              try {
 88                  stat.close();
 89             } catch (SQLException e) {
 90                 // TODO Auto-generated catch block
 91                 e.printStackTrace();
 92             }
 93         }
 94         
 95         if(con!=null){
 96              try {
 97                 con.close();
 98             } catch (SQLException e) {
 99                 // TODO Auto-generated catch block
100                 e.printStackTrace();
101             }
102         }
103     }
104 }

測試代碼

 1 package Test;
 2 
 3 import java.sql.Connection;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import Test.JDBCUtils;
 8 
 9 public class JDBCTset {
10     public static void main(String[] args) throws SQLException {
11         Connection con =JDBCUtils.getConnection();
12         //當能輸出數據庫連接時邊說用工具類正常了
13         System.out.println(con);
14         //由於是簡單的測試,因此不用釋放資源
15         //JDBCUtils.close(con, pst);
16     }
17 }

使用數據庫連接池優化工具類

優化代碼:

 1 package Test;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.util.Properties;
 5 
 6 import javax.sql.DataSource;
 7 
 8 /*
 9  * JDBC連接池工具類,使用連接池專門負責數據庫的連接
10  * JDBC連接池簡化了sql語句中的增刪改查操作,方便代碼編寫
11  */
12 import org.apache.commons.dbcp.BasicDataSource;
13 
14 
15 public class JDBCUtils {
16     private JDBCUtils(){}
17     private static String driverClass;
18     private static String url;
19     private static String username;
20     private static String password;
21     private static  BasicDataSource datasource =new BasicDataSource();
22     //放到靜態代碼塊中保證讀取配置文件,獲取連接只執行一次
23     static{
24         try {
25             readConfig();
26             //數據庫連接配置
27             datasource.setDriverClassName(driverClass);
28             datasource.setUrl(url);
29             datasource.setUsername(username);
30             datasource.setPassword(password);
31             //對象連接池中的數量配置,這些配置可以不用配置的
32             datasource.setInitialSize(10);//初始化的連接數
33             datasource.setMaxActive(8);//最大連接數
34             datasource.setMaxIdle(5);//最大空閑數
35             datasource.setMinIdle(1);//最小空閑數    
36         } catch (IOException e) {
37             // TODO Auto-generated catch block
38             e.printStackTrace();
39         }            
40     }
41     
42     private static void readConfig() throws IOException{
43         //通過字節流,使用類加載器讀取配置文件的內容
44         InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("database.properties");
45         Properties pro = new Properties();
46         pro.load(in);
47         driverClass=pro.getProperty("driverClass");
48         url = pro.getProperty("url");
49         username=pro.getProperty("username");
50         password=pro.getProperty("password");        
51     }
52     
53     //定義靜態方法,返回數據庫的連接對象
54     public static DataSource getDataSource(){
55         return datasource;
56     }        
57 }

測試代碼:

 1 package Test;
 2 
 3 import java.sql.SQLException;
 4 import java.util.List;
 5 
 6 import org.apache.commons.dbutils.QueryRunner;
 7 import org.apache.commons.dbutils.handlers.ArrayHandler;
 8 import org.apache.commons.dbutils.handlers.ArrayListHandler;
 9 
10 public class JDBCTset {
11     private static QueryRunner qr=new QueryRunner(JDBCUtils.getDataSource());
12     
13     public static void main(String[] args) throws SQLException {
14         String sql="select * from titles";
15 //ArrayListHandler:把結果集中的每一行數據都轉成一個對象數組,再存放到List中。這是dbutils所特有的
16         List<Object[]> list =qr.query(sql, new ArrayListHandler());
17         for(Object[] objs:list){
18             for(Object obj:objs)
19                 System.out.print(obj+"\t\t");
20             System.out.println();
21         }
22     }
23     
24 }

 

 

0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM