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+"		");
20             System.out.println();
21         }
22     }
23     
24 }

0

原文地址:https://www.cnblogs.com/youngao/p/9820827.html