2.jdbc之工具类,SQL注入攻击和JDBC事务

2.jdbc之工具类,SQL注入攻击和JDBC事务,第1张

4.JDBC工具类

抽取工具类
1)编写配置文件
在src目录下创建config.properties配置文件

driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://192.168.1.224:3306/db14
username=root
password=123456

2)编写jdbc工具类
utils文件下(JDBCUtils.java)

package jdbc01.utils;

import com.mysql.cj.protocol.Resultset;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JDBCUtils {
    //1 私有化构造方法
    private JDBCUtils(){}

    //2 声明所需要的配置变量
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;
    private static Connection con;

    //3 提供静态代码块,读取配置文件的信息为变量赋值,注册驱动
    static{
        try {
            //读取配置文件的信息和变量赋值
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties");
            Properties prop = new Properties();
            prop.load(is);

            driverClass = prop.getProperty("driverClass");
            url = prop.getProperty("url");
            username = prop.getProperty("username");
            password = prop.getProperty("password");

            //注册驱动
            Class.forName(driverClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //4 获取数据库连接方法
    public static Connection getConnection(){
        try {
            con = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return con;
    }

    //5 提供释放资源的方法
    public static void close(Connection con, Statement stat, ResultSet rs){
        if(con != null){
            try {
                con.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(stat != null){
            try {
                stat.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
    public static void close(Connection con, Statement stat){
        if(con != null){
            try {
                con.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(stat != null){
            try {
                stat.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3)使用jdbc工具类优化student表的CRUD *** 作

package jdbc01.dao;

import jdbc01.domain.Student;
import jdbc01.utils.JDBCUtils;

import javax.swing.text.Utilities;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class StudentDaoImpl implements StudentDao{
    //查询所有学生信息
    @Override
    public ArrayList<Student> findAll() {
        ArrayList<Student> list = new ArrayList<>();
        Connection con = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            con = JDBCUtils.getConnection();

            //3.获取执行者对象
            stat = con.createStatement();

            //4.执行sql语句,并接受返回的结果集
            String sql = "select * from student";
            rs = stat.executeQuery(sql);

            //5.处理结果集
            while(rs.next()){
                Integer sid = rs.getInt("sid");
                String name = rs.getString("name");
                Integer age = rs.getInt("age");
                Date birthday = rs.getDate("birthday");

                //封装Student对象
                Student stu = new Student(sid, name, age, birthday);

                //将student对象保存到集合中
                list.add(stu);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(con,stat,rs);
        }
        //将集合对象返回
        return list;
    }

    //条件查询,根据id查询学生信息
    @Override
    public Student findById(Integer id) {
        Student stu = new Student();
        Connection con = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            con = JDBCUtils.getConnection();

            //3.获取执行者对象
            stat = con.createStatement();

            //4.执行sql语句,并接受返回的结果集
            String sql = "select * from student where sid='" + id + "'";
            rs = stat.executeQuery(sql);

            //5.处理结果集
            while(rs.next()){
                Integer sid = rs.getInt("sid");
                String name = rs.getString("name");
                Integer age = rs.getInt("age");
                Date birthday = rs.getDate("birthday");

                //封装Student对象
                stu.setSid(sid);
                stu.setName(name);
                stu.setAge(age);
                stu.setBirthday(birthday);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            JDBCUtils.close(con,stat,rs);
        }
        //将集合对象返回
        return stu;
    }

    //添加学生信息
    @Override
    public int insert(Student stu) {
        Connection con = null;
        Statement stat = null;
        int result =0;
        try {
            con = JDBCUtils.getConnection();

            //3.获取执行者对象
            stat = con.createStatement();

            //4.执行sql语句,并接受返回的结果集
            Date d = stu.getBirthday();
            SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");
            String birthday = sdf.format(d);
            String sql = "insert into student values('"+stu.getSid()+"','"+stu.getName()+ "','"+stu.getAge()+"','"+birthday+"')";
            result = stat.executeUpdate(sql);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //5.释放资源
            JDBCUtils.close(con,stat);
        }
        //将集合对象返回
        return result;
    }

    //修改学生信息
    @Override
    public int update(Student stu) {
        Connection con = null;
        Statement stat = null;
        int result =0;
        try {
            con = JDBCUtils.getConnection();

            //3.获取执行者对象
            stat = con.createStatement();

            //4.执行sql语句,并接受返回的结果集
            Date d = stu.getBirthday();
            SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");
            String birthday = sdf.format(d);
            String sql = "update student set sid='"+stu.getSid()+"',name='"+stu.getName()+"',age='"+stu.getAge()+"',birthday='"+birthday+"' where sid='"+stu.getSid()+"'";
            result = stat.executeUpdate(sql);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //5.释放资源
            JDBCUtils.close(con,stat);
        }
        //将集合对象返回
        return result;
    }

    //删除学生信息
    @Override
    public int delete(Integer id) {
        Connection con = null;
        Statement stat = null;
        int result =0;
        try {
            con = JDBCUtils.getConnection();

            //3.获取执行者对象
            stat = con.createStatement();

            //4.执行sql语句,并接受返回的结果集
            String sql = "delete from student where sid='"+id+"'";
            result = stat.executeUpdate(sql);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //5.释放资源
            JDBCUtils.close(con,stat);
        }
        //将集合对象返回
        return result;
    }
}
5.SQL注入攻击

1)什么是SQL注入攻击?
就是利用sql语句的漏洞对系统进行攻击

创建一个user表

建表sql
#创建用户表
CREATE TABLE USER(
	uid VARCHAR(50) PRIMARY KEY,	#用户id
	ucode VARCHAR(50),		#用户标识
	loginname VARCHAR(100),		#登录用户名
	PASSWORD VARCHAR(100),		#登录密码
	username VARCHAR(10),		#用户名
	gender VARCHAR(10),		#用户性别
	birthday DATE,			#出省日期
	dutydate DATE			#入职日期
); 

#添加一条测试数据
INSERT INTO USER VALUE ('111111','zhangsan001','zhangsan','1234','张三','男','2008-10-28','2015-11-11');

2)sql注入攻击
如果输入账号为:aaa
密码为:bbb’ or ‘1’='1
导致查询的sql变为:
SELECT * FROM USER WHERE loginname=‘aaa’ AND PASSWORD=‘bbb’ OR ‘1’=‘1’
就能登录了

3)sql注入攻击的原理
正常来说,我们在密码处输入的所有内容,都应该认为是密码的组成部分
但是现在Statement对象在执行sql语句时,将密码的一部分内容当做查询条件来执行了

4)sql注入攻击的解决
PreparedStatement预编译执行者对象:

  • 在执行sql之前,将sql语句进行提前编译。明确sql语句的个时候,就不会改变了。剩余的内容都会被认为是参数
  • sql语句中的参数使用?作为占位符

为?占位符赋予的方法:setXxx(参数1,参数2);

  • Xxx代表:数据类型
  • 参数1:?的位置标号(编号从1开始)
  • 参数2:?的实际参数
String sql = "delete from user where name=?";
pstm = conn.prepareStatement(sql);
pstm.setString(1,"张三");

执行sql语句

  • 执行insert、update、delete语句:int execteUpdate();
  • 执行select语句:ResultSet executeQuery();
import jdbc01.utils.JDBCUtils;

import java.sql.*;

public class JDBCDemo {
    public static void main(String[] args){

        String loginName = "zhangsan";
        String password = "1234";
//        loginName = "aaa";
//        password = "bbb' OR '1'='1";

        Connection con = null;
        ResultSet rs =null;
        PreparedStatement st =null;
        try {
            con = JDBCUtils.getConnection();

            String sql = "select * from user where loginname=? and password=?";
            st = con.prepareStatement(sql);
            st.setString(1,loginName);
            st.setString(2,password);

            rs = st.executeQuery();

            while(rs.next()){
                System.out.println(rs.getString("username"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            if(con != null){
                try {
                    con.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if(st != null){
                try {
                    st.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
6.JDBC事务

1)JDBC如何管理事务
管理事务的功能:Connection
开启事务:setAutoCommit(boolean autoCommit);参数为false,则开启事务。
提交事务:commit();
回滚事务:rollback();

2.批量添加数据在业务层管理事务

#StudentService接口中添加以下代码
    //批量添加
    public abstract void batchAdd(List<Student> users);
    
#StudentDao接口中添加以下代码
     //批量添加
    void save(Connection con, Student stu);
    
#StudentServiceImpl添加如下代码
    @Override
    public void batchAdd(List<Student> stus) {
        //获取数据库的连接对象
        Connection con = JDBCUtils.getConnection();
        try {
            //开启事务
            con.setAutoCommit(false);

            for (Student stu : stus) {
                //保存
                dao.save(con,stu);
            }
            //提交事务
            con.commit();
        } catch (Exception e) {
            //回滚事务
            try {
                con.rollback();
            } catch (SQLException ex) {
                e.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            //释放资源
            JDBCUtils.close(con,null);
        }
    }

#StudentDaoImpl中添加如下代码
    @Override
    public void save(Connection con, Student stu) {
        PreparedStatement pstm = null;
        try {
            con = JDBCUtils.getConnection();


            //4.执行sql语句,并接受返回的结果集
            String sql = "insert into student values(?,?,?,?)";
            pstm = con.prepareStatement(sql);
            Date d = stu.getBirthday();
            SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");
            String birthday = sdf.format(d);
            pstm.setInt(1,stu.getSid());
            pstm.setString(2,stu.getName());
            pstm.setInt(3,stu.getAge());
            pstm.setString(4,birthday);

            pstm.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //5.释放资源
            if(pstm != null){
                try {
                    pstm.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

#StudentController中测试批量添加代码
    //测试批量添加
    @Test
    public void batchAdd(){
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student(6,"周八",27,new Date()));
        list.add(new Student(7,"周九",27,new Date()));
        list.add(new Student(8,"周十",27,new Date()));

        service.batchAdd(list);
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/917302.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存