• day0620220104


    湖南

    day06数据库

    一.JDBC练习

    1.利用jdbc给user表中,添加一个用户的信息

    package cn.tedu.jdbc;
    
    import java.sql.Connection;
    import java.sql.Driver;
    import java.sql.DriverManager;
    import java.sql.Statement;
    
    //写jdbc的代码,向user表里的添加一条数据
    public class Test3 {
        public static void main(String[] args) throws Exception {
            //1,注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2,获取连接
            String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
            Connection c = DriverManager.getConnection(url, "root", "root");
            //3,获取传输器
            Statement s = c.createStatement();
            //4,执行SQL(SQL语句中的字符串可以用"" 或者 '')
            //executeUpdate()用来执行增删改的SQL,返回对数据库的影响行数
            //executeQuery()用来执行查询的SQL,返回一个结果集对象ResultSet
            int rows = s.executeUpdate("insert into user values(null,\"tony\",'1234')");
            //5,处理结果集--增删改的SQL没有结果集,省略....
            //6,释放资源
            s.close();
            c.close();
            System.out.println("数据入库成功!");
        }
    }
    

    2.模拟用户登录

    package cn.tedu.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.Scanner;
    
    //写jdbc的代码,模拟用户登录的过程
    //本质上,就是拿到用户在浏览器输入的账号和密码,利用jdbc,去查库
    public class Test4 {
        public static void main(String[] args) throws Exception {
            //1,注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2,获取连接
            String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
            Connection c = DriverManager.getConnection(url, "root", "root");
            //3,获取传输器
            Statement s = c.createStatement();
            //4,执行SQL
    //        String sql = "SELECT * FROM USER WHERE NAME='jack' AND pwd='123456'";
            //动态的拼接SQL语句
            System.out.println("请输入账号: ");
            String a = new Scanner(System.in).nextLine();
            System.out.println("请输入账密码: ");
            String b = new Scanner(System.in).nextLine();
            //动态数据,如果在中间,按照  "+???+"
            String sql = "SELECT * FROM USER WHERE NAME='"+a+"' AND pwd='"+b+"'";
            ResultSet r = s.executeQuery(sql);
            //5,处理结果集(根据用户名和密码去查,只会查出来一条记录)
            if(r.next()){//如果查到了数据,才表示库里有这个用户信息
                System.out.println("恭喜您,登录成功~~");
            }else{//如果没查到数据,
                System.out.println("请重新输入....");
            }
            //6,释放资源
            r.close();
            s.close();
            c.close();
    
            //1,问题:当用户输入特殊值: jack'#时,甚至不需要密码也能登录
            //2,产生的原因:#在SQL中表示注释的意思,相当于后面的条件被注释掉了...
            //SELECT * FROM USER WHERE NAME='jack'#' AND pwd='123456'
            //现象叫SQL攻击/SQL注入,本质上就是因为SQL语句中出现了特殊符号#
            //导致了,SQL语义发生改变
            //3,哪里出现的问题?Statement传输器不安全,低效
            //4,解决方案?使用新的传输器PreparedStatement代码现有的Statement
        }
    }
    

    二.SQL攻击

    1.概述

    1. 问题:当用户输入特殊值:jack'#时,甚至不需要密码也能登录
    2. 产生的原因:#在SQL中表示注释的意思,相当于后面的条件被注释掉了...
      select * from user where name = 'jack' and pwd='123456'
    3. 哪里出现的问题?Statement传输器不安全,低效
    4. 解决方案?使用新的传输器PreparedStatement代码现有的Statement
    5. PreparedStatement工具,安全,高效.而且SQL写法简洁
      (PreparedStatement把特殊符号#当做普通文本字符在使用,没有注释的意思了)

    2.改造用户登录

    package cn.tedu.jdbc;
    
    import java.sql.*;
    import java.util.Scanner;
    
    //写jdbc的代码,模拟用户登录的过程
    //本质上,就是拿到用户在浏览器输入的账号和密码,利用jdbc,去查库
    //1,问题:当用户输入特殊值: jack'#时,甚至不需要密码也能登录
    //2,产生的原因:#在SQL中表示注释的意思,相当于后面的条件被注释掉了...
    //SELECT * FROM USER WHERE NAME='jack'#' AND pwd='123456'
    //现象叫SQL攻击/SQL注入,本质上就是因为SQL语句中出现了特殊符号#
    //导致了,SQL语义发生改变
    //3,哪里出现的问题?Statement传输器不安全,低效
    //4,解决方案?使用新的传输器PreparedStatement代码现有的Statement
    //5,PreparedStatement工具,安全,高效.而且SQL写法简洁.
    //PreparedStatement把特殊符号当做普通文本字符在使用,没有注释的意思了
    public class Test4 {
        public static void main(String[] args) throws Exception {
            //1,注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2,获取连接
            String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
            Connection c = DriverManager.getConnection(url, "root", "root");
    //        Statement s = c.createStatement();
    //        String sql = "SELECT * FROM USER WHERE NAME='"+a+"' AND pwd='"+b+"'";
            System.out.println("请输入账号: ");
            String a = new Scanner(System.in).nextLine();
            System.out.println("请输入账密码: ");
            String b = new Scanner(System.in).nextLine();
            //新的传输器,执行的SQL有新写法--sql骨架
            String sql = "SELECT * FROM USER WHERE NAME=? AND pwd=?";
            //3,获取 新的传输器--安全,高效
            PreparedStatement s = c.prepareStatement(sql);
            //给SQL绑定参数
            s.setString(1,a);//给第一个问号,设置a的值
            s.setString(2,b);//给第二个问号,设置b的值
            //4,执行SQL语句
            ResultSet r = s.executeQuery();
    
            //5,处理结果集(根据用户名和密码去查,只会查出来一条记录)
            if(r.next()){//如果查到了数据,才表示库里有这个用户信息
                System.out.println("恭喜您,登录成功~~");
            }else{//如果没查到数据,
                System.out.println("请重新输入....");
            }
            //6,释放资源
            r.close();
            s.close();
            c.close();
        }
    }
    

    3.练习:用新的传输器查询

    package cn.tedu.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    //利用新的传输器,查询部门编号为1的数据
    public class Test5 {
        public static void main(String[] args) throws Exception {
            //1,注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2,获取连接
            String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
            Connection c = DriverManager.getConnection(url, "root", "root");
            //3,获取传输器,并执行SQL骨架
            String sql="select * from dept where deptno = ?";
            PreparedStatement s = c.prepareStatement(sql);
            //设置SQL的参数--是指给第几个问号,设置什么值
            s.setObject(1,1);
            //4,执行SQL
            ResultSet r = s.executeQuery();//执行查询的SQL
            //5,解析结果集
            while(r.next()){
                Object deptno = r.getObject(1);//获取第1列的值
                Object dname = r.getObject(2);//获取第2列的值
                Object loc = r.getObject(3);//获取第3列的值
                System.out.println(""+deptno+dname+loc);
            }
            //6,释放资源
            r.close();
            s.close();
            c.close();
        }
    }
    

    三.优化:提供jdbc的工具类

    1.创建工具类

    package cn.tedu.jdbc;
    
    import java.sql.*;
    
    //充当了jdbc的工具类,抽取一些共性代码
    public class JDBCUtils {
        /**
         * 释放资源
         * @param r 结果集
         * @param s 传输器
         * @param c 连接器
         */
        static public void close(ResultSet r, PreparedStatement s,Connection c){
            if(r != null){//防止了空指针异常
                try {
                    r.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(s != null) {//防止空指针异常
                try {
                    s.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(c != null) {//防止空指针异常
                try {
                    c.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    
        /**
         * 获取数据库的连接
         * @return 将给调用者返回一个和数据库连接的对象Connection
         * @throws Exception
         * static:保证资源在内存中,贮存的时间长.只会加载一次节省内存
         * public:工具类可以被所有人使用,最大的访问权限方便调用来调用
         */
        static public Connection get() throws Exception{
            //1,注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2,获取连接
            String url="jdbc:mysql://localhost:3306/cgb211101?characterEncoding=utf8";
            Connection c = DriverManager.getConnection(url, "root", "root");
            //把获取到的数据库的连接,返回给调用者
            return c;
        }
    }
    

    2.使用工具类(用新的传输器新增)

    package cn.tedu.jdbc;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    
    //利用新的传输器结合着工具类,新增一个用户信息
    public class Test6 {
        public static void main(String[] args) throws Exception {
            //1,利用工具类,来获取数据库的连接
            Connection c = JDBCUtils.get();
            //2,获取传输器,执行SQL
            String sql="insert into user values(null,?,?)";
            PreparedStatement p = c.prepareStatement(sql);
            //给SQL绑定参数
            p.setObject(1,"jerry");
            p.setObject(2,"123");
            //3,执行SQL
            p.executeUpdate();//执行增删改的SQL,返回一个影响行数(通常不处理)
            //4,释放资源
            p.close();
            c.close();
        }
    }
    

    3.改造上面的练习(修改资源释放的代码)

    package cn.tedu.jdbc;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    //利用新的传输器结合着工具类,新增一个用户信息
    public class Test6 {
        public static void main(String[] args) {
           //扩大变量的作用范围:为了让try  catch  finally都能用
           Connection c = null;
           PreparedStatement p = null;
           try {
                //1,利用工具类,来获取数据库的连接
                c = JDBCUtils.get();
                //2,获取传输器,执行SQL
                String sql="insert into user values(null,?,?)";
                p = c.prepareStatement(sql);
                //给SQL绑定参数
                p.setObject(1,"jerry");
                p.setObject(2,"123");
                //3,执行SQL
                p.executeUpdate();//执行增删改的SQL,返回一个影响行数(通常不处理)
           }catch (Exception e){
               System.out.println("数据插入失败!!");
           }finally {//保证一定会被执行的代码
               //利用工具类close完成释放资源(新增业务,没有结果集,传入null就可以了)
               JDBCUtils.close(null,p,c);
           }
        }
    }
  • 相关阅读:
    php安装yaf,memcache,memcached模块
    django的ORM操作
    Composer简介
    MySQL中exists和in的区别及使用场景
    MySQL事务原理浅析
    MySQL JOIN原理
    mysql 子句、子查询、连接查询
    多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP
    数据库多表连接方式介绍-HASH-JOIN
    MySQL中的case when 中对于NULL值判断的坑
  • 原文地址:https://www.cnblogs.com/elliottmoo/p/15763816.html
Copyright © 2020-2023  润新知