• 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

  • 相关阅读:
    性能测试分析
    常见的性能缺陷
    性能测试中TPS上不去的几种原因浅析
    Linux新增和删除环境变量
    JProfiler的详细使用介绍
    详解Tomcat的连接数和线程池
    造数据存储过程
    shell脚本解压多个jar包
    使用shell快速建立上万个文件夹
    df、du命令
  • 原文地址:https://www.cnblogs.com/youngao/p/9820827.html
Copyright © 2020-2023  润新知