数据库连接

本文介绍了Java通过JDBC进行数据库操作的基本步骤,特别关注了SQL注入问题的原理及解决方案,重点讲解了Statement与PreparedStatement的区别,并展示了如何使用PreparedStatement防止注入。还提供了数据库增删改查操作和DAO类的重构示例。
摘要由CSDN通过智能技术生成

1.连接
JDBC---java database connection java数据库连接。 通过java代码来操作数据库表中的记录。
2. 增删改---这三个模式.
3. 步骤:
    (1)加载驱动: Class.forName("com.mysql.cj.jdbc.Driver");
    (2)获取连接对象: Connection conn=DriverManager.getConnection(url,u,p);
    (3)获取执行sql语句的对象: Statement st=conn.createStatement();
    (4)执行增删改的语句: st.executeUpdate(sql);

2.SQL注入安全问题
//演示sql注入的安全问题
    public static void main(String [] args) throws Exception{
        Scanner scanner=new Scanner(System.in); //Scanner类有没有讲过。
        System.out.print("请输入账号:");
        String username = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine(); //你输入的账号和密码 nextLine() 可以输入空格 回车任认为结束  next()输入空格后认为输入结束。
        boolean b = sqlSafe(username, password);
    }
 
    //根据name查询数据 abc  演示的根据账号和密码查询数据库表记录 如果能查询表示登录成功 否则登录失败
    private static boolean sqlSafe(String name,String password) throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "PAssW0rd");
 
        Statement statement = conn.createStatement();
        //这里的admin 是不是一个死数据  123456 也是一个死数据
        String sql="select * from user where username='"+name+"' and password='"+password+"'";
        System.out.println(sql);
        ResultSet rs = statement.executeQuery(sql);
 
        while (rs.next()){
            System.out.println("登录成功");
            return true;
        }
 
        System.out.println("登录失败");
        return false;
 
    }
可以发现: 你的账号可以随便输入 你的密码也可以随便输入 但是 在输入密码时 or '4'='4 只要这个条件成立,那么你就能登录成功。 这个就是sql注入的安全问题。只要根据条件做sql。那么就会出现sql注入安全问题。

如何解决sql安全注入问题:

1. 前端做校验: --只防君子 防不了小人。
2. 后端也做校验:--难道以后每次写功能都进行校验吗? 代码变得复杂了。
3. 执行sql的类Statement出现了问题,后期PrepareStatement该类来解决sql注入安全问题。

Statement和PrepareStatement区别?
  Statement会出现sql注入安全问题。Preparestatement不会出现sql注入安全问题。
  Preparestatement是Statement的子类。就是因为早期使用Statement发现该类出现问题,后期维护人员创建Statement的子类来解决这个问题。注意:维护人员不会再原类上做维护

2.2使用prepareStatement来解决sql注入的问题
 //演示sql注入的安全问题
    public static void main(String [] args) throws Exception{
        Scanner scanner=new Scanner(System.in); //Scanner类有没有讲过。
        System.out.print("请输入账号:");
        String username = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine(); //你输入的账号和密码 nextLine() 可以输入空格 回车任认为结束  next()输入空格后认为输入结束。
        boolean b = sqlSafe02(username, password);
    }
 
    private static boolean sqlSafe02(String name,String password) throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "pAssW0rd");
 
        //使用PrepareStatement 这里的? 是占位符。
        String sql="select * from user where username=? and password=?";
        PreparedStatement ps = conn.prepareStatement(sql);//预编译sql
        //为占位符赋值。根据占位符的类型使用不同的方法来赋值
        ps.setString(1,name); //1表示第一个占位符  name:表示第一个占位符的值
        ps.setString(2,password);
 
        //执行sql语句
        ResultSet rs = ps.executeQuery();
        while (rs.next()){
            System.out.println("登录成功");
            return true;
        }
        System.out.println("登录失败");
        return false;
    }

3.对数据库增删改查
3.1增
@Test
    public void test1()throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn= DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
                        "root","pAssW0rd");
        String sql="insert into student values(?,?,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1,2);
        ps.setString(2,"小浩");
        ps.setInt(3,23);
        ps.setString(4,"河南");
        ps.executeUpdate();
    }
3.2删
 @Test
    public void test3()throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn= DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
                        "root","pAssW0rd");
        String sql="delete from student where id=?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1,12);
        ps.executeUpdate();
    }
3.3改
 @Test
    public void test2()throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn= DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
                        "root","pAssW0rd");
        String sql="update student set name=? where id=?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1,"李四");
        ps.setInt(2,8);
        ps.executeUpdate();
    }
3.4查
@Test
    public void test4()throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn= DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
                        "root","pAssW0rd");
        String sql="select * from student";
        PreparedStatement ps = conn.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        while(rs.next()){
            int id= rs.getInt("id");
            String name=rs.getString("name");
            String address =rs.getString("address");
            int age =rs.getInt("age");
            System.out.println(id+"\t"+name+"\t"+address+"\t"+age);
        }
    }

4.抽取一个dao的公共的父类
4.1抽取父类
因为我们对每一张表都封装了一个操作类,那么再数据库中有很多表,那么我们就会有很多操作类,这些操作类都有一些公共的代码,为了减少代码的冗余,我们就抽取了一个父类

private String driverName = "com.mysql.cj.jdbc.Driver";
    private String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
    private String user = "root";
    private String password = "pAssW0rd";
    protected PreparedStatement ps = null;
    protected Connection conn = null;
    protected ResultSet rs = null;
    public Connection getConn()throws Exception{
        Class.forName(driverName);
        conn = DriverManager.getConnection(url,user,password);
        return conn;
    }
    public void closeAll(){
        try {
            if(rs!=null){
                rs.close();
            }
            if(ps!=null){
                ps.close();
            }
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    public void edit(String sql,Object ... params){
        try {
            getConn();
            ps = conn.prepareStatement(sql);
            for(int i= 0;i<params.length;i++){
                ps.setObject(i+1,params[i]);
            }
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            closeAll();
        }
    }

4.2为添加 删除 修改抽取公共的方法
public Dept findOne(int id){
        Dept d = new Dept();
        try {
            getConn();
            String sql="select * from tb_emp where id=?";
            ps =conn.prepareStatement(sql);
            ps.setObject(1,id);
            rs = ps.executeQuery();
            while(rs.next()){
                d.setId(rs.getInt("id"));
                d.setName(rs.getString("name"));
                d.setAge(rs.getInt("age"));
                d.setJob(rs.getString("job"));
                d.setSalary(rs.getInt("salary"));
                d.setEntrydate(rs.getString("entrydate"));
                d.setManagerid(rs.getInt("managerid"));
                d.setDept_id(rs.getInt("dept_id"));
 
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return d;
    }
    public List<Dept> findAll(){
        List<Dept> list  =  new ArrayList<Dept>();
        try {
            getConn();
            String sql="select * from tb_emp";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while(rs.next()){
                Dept d  = new Dept();
                d.setId(rs.getInt("id"));
                d.setName(rs.getString("name"));
                d.setAge(rs.getInt("age"));
                d.setJob(rs.getString("job"));
                d.setSalary(rs.getInt("salary"));
                d.setEntrydate(rs.getString("entrydate"));
                d.setManagerid(rs.getInt("managerid"));
                d.setDept_id(rs.getInt("dept_id"));
                list.add(d);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return list;
     }
     public void insertDpet(Dept dept){
        String sql="insert into tb_emp values(null,?,?,?,?,?,?,?)";
        edit(sql,dept.getName(),dept.getAge(),dept.getJob(),dept.getSalary(),
                dept.getEntrydate(),dept.getManagerid(),dept.getDept_id());
     }
     public void updateDept(Dept dept){
        String sql ="update tb_emp set name =? where id=?";
        edit(sql,dept.getName(),dept.getId());
     }
     public void deleteDept(int id){
        String sql = "delete from tb_emp where id=?";
        edit(sql,id);
     }

4.3测试
public class Test1 {
    DeptDao deptDao = new DeptDao();
    @Test
    public void testFindOne(){
        Dept d = deptDao.findOne(1);
        System.out.println(d.getId()+"\t"+d.getName()+"\t"+d.getAge()+"\t"+
                d.getJob()+"\t"+d.getSalary()+"\t"+d.getEntrydate()+"\t"+
                d.getManagerid()+"\t"+d.getDept_id());
    }
 
    @Test
    public void testFindAll(){
       List<Dept>  all= deptDao.findAll();
    for(Dept d:all){
        System.out.println(d.getId()+"\t"+d.getName()+"\t"+d.getAge()+"\t"+
                d.getJob()+"\t"+d.getSalary()+"\t"+d.getEntrydate()+"\t"+
                d.getManagerid()+"\t"+d.getDept_id());
    }
    }
    @Test
    public void testInsert(){
        Dept d = new Dept();
        d.setName("小杨");
        d.setAge(24);
        d.setJob("经理");
        d.setSalary(20000);
        d.setEntrydate("2022-05-07");
        d.setManagerid(1);
        d.setDept_id(2);
        deptDao.insertDpet(d);
    }
    @Test
    public void testUpdate(){
       Dept d= new Dept();
       d.setName("小刘");
       d.setId(16);
       deptDao.updateDept(d);
    }
    @Test
    public void testDelete(){
        deptDao.deleteDept(16);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值