05、Mysql_JDBC

191 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

05、Mysql_JDBC

01.JDBC_Java程序和MySQL的关系:

    1).Java程序跟其它MySQL客户端一样,就是一个"客户端",用于"封装SQL语句"并发送给MySQL服务器,

       MySQL服务器会直接返回结果给我们的程序。

02.JDBC_驱动的概念:

    由数据库厂商为每种编程语言提供的一个程序包。有两种语言组成:前端:所面向的编程语言;后端:数据库本身的语言。

    它可以使各种编程语言直接访问本语言,就可以访问数据库软件,方便操作。

03.JDBC_JDBC的概念:

    由SUN公司提出的Java连接数据库的规范,它规范了Java连接各种数据库所遵循的步骤和数据类型。它要求各数据库厂商的驱动

    程序必须遵守这套规范,也需要Java程序员直接学习这套规范,这样可以使得Java程序员访问各种数据库都使用同样的步骤和数据类型。

    JDBC物理上由一组类和接口组成,随JDK一起发放。

04.JDBC_JDBC的四个核心类:

    1).DriverManager(类) : 驱动管理器。 用于连接数据库的"驱动程序",并通过驱动程序去连接数据库软件,向程序返回一个"连接通道(Connection对象)"。

    2).Connection(接口) : "连接"对象。代表了程序和数据库之间的一个"连接通道"。

    3).Statement(接口) : SQL执行器。用于执行SQL语句。

    4).ResultSet(接口) : 结果集。当Statement执行"查询"语句时,会返回此对象。

05.JDBC_JDBC的开发步骤:

    1).下载MySQL的Java驱动包,并复制到项目目录下,并添加到构建路径:

        mysql-connector-java-5.1.37-bin.jar

    2).开发步骤:

        1.注册驱动

        2.获取连接

        3.获取SQL执行器

        4.执行SQL,并获取结果集(查询)

        5.解析结果集

        6.关闭资源                    // 关闭资源一定要按顺序关闭

         //1.注册驱动          //反射加载 驱动类Class对象 Driver  到内存中,第二步用    由驱动管理器来用

         Class.forName("com.mysql.jdbc.Driver");

         //2.获取连接          // 第一个参数 http  url 路径  getConnection找到第一步 Driver Class 对象,创建一个对象 负责把三个参数信息传给driver类,driver类负责连接数据库,连接数据库之后返回一个连接通道,所以getConnection方法有返回值,返回值是Connection接口的子类对象 ;driver 遵守Connection接口 协议,所以返回其子类对象;DriverManager是一个普通类,驱动管理器

         Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/hei70_day21db_1", "root", "123");

         //3.获取SQL执行器     //Statement 是一个接口,

         Statement stmt = conn.createStatement();

         //4.执行SQL,并获取结果集(查询)

         String sql = "select * from product";

         ResultSet rs = stmt.executeQuery(sql);

         //5.解析结果集

06.JDBC_关于Statement的常用方法:

    1).public int executeUpdate(String sql):用于执行添加(insert)、修改(update)、删除(delete)语句的。

                                            返回值:int,影响的行数

    2).public ResultSet executeQuery(String sql):用于执行查询(select)

                        返回值:ResultSet结果集。

        public boolean execute(String sql);      //  返回值 boolean  值  好像建表成功也返回false  好像所有sql语句都能执行

    注意:两种不能混用。不能用executeUpdate()执行查询语句,反之也不可以。

07.JDBC_关于ResultSet的使用:

    1).ResultSet就类似于之前的"迭代器"
        迭代器:while(it.hasNext())                 结果集:while(rs.next())
                it.next();                                    rs.get数据类型(String 列名)
                                                                 或者
                                                                 rs.get数据类型(int 列索引)

                                                                 大招:
                                                                 rs.getObject(String 列名)                    //不知道字段什么类型
                                                                 rs.getObject(int 列索引)                         // 可以填字段名,也可以填 第几个字段 比如 1  2   3  第一个字段为 1

while(rs.next()){
              System.out.println(rs.getInt("id")+"\t"+
                                     rs.getString("name")+"\t"+
                                     rs.getInt("age"));

         }

08.JDBC_使用JDBC实现增删改查:

09.JDBC_JDBC工具类的制作:

    public class JDBCUtils {
        //1.获取Connection对象--代码重用的目的
        public static Connection getConnection() throws Exception{
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/hei70_day21db_1","root","123");
            return conn;
        }
        //2.关闭资源                         // 关闭资源要按顺序依次关闭
        public static void closeAll(ResultSet rs,Statement stmt,Connection conn) throws SQLException{
            if(rs != null){
                rs.close();
            }
            if(stmt != null){
                stmt.close();
            }
            if(conn != null){
                conn.close();
            }
        }
    }

10.JDBC_SQL语句的封装:

    public class Demo {
        public static void main(String[] args) throws Exception {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入商品名称:");
            String pname = sc.next();//海尔冰柜
            System.out.println("价格:");
            int price = sc.nextInt();//2300
            System.out.println("类别ID:");
            int cid = sc.nextInt();//1

            //1.获取连接对象
            Connection conn = JDBCUtils.getConnection();
            //2.获取SQL执行器
            Statement stmt = conn.createStatement();
            //3.【封装SQL语句】                    //  SQL 语句的拼接
            //先想象,封装后的SQL语句:"insert into product values(null,'海尔冰柜',2300,1)"
            String sql = "insert into product values(null,'" + pname +
                                "'," + price + "," +
                                cid + ")";
            System.out.println(sql);

            //4.执行SQL语句
            int row = stmt.executeUpdate(sql);
            System.out.println("添加影响的行数:" + row);
            //5.释放资源
            JDBCUtils.closeAll(null, stmt, conn);
        }
    }

11.JDBC_关于SQL注入的问题:

    1).什么是SQL注入:是指在用户的数据中,包含了一些SQL的格式化符号,例如:)或者(或者,或者',如果程序接收后,不加以判断直接封装到SQL语句中会导致SQL语句的错误。这种现象就叫:SQL注入。

    2).SQL注入的登录演示:

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入登录名:");
        String loginName = sc.nextLine();//jfdks
        System.out.println("输入密码:");
        String loginPwd = sc.nextLine();//jfdjfd' or '1=1

        //1.获取连接对象
        Connection conn = JDBCUtils.getConnection();
        Statement stmt = conn.createStatement();
        String sql = "select * from users where uname = '" + loginName +
                        "' and password = '" + loginPwd + "'";
        System.out.println(sql);
        ResultSet rs = stmt.executeQuery(sql);
        if(rs.next()){
            System.out.println("欢迎:" + loginName + " 登录系统!");
        }else{
            System.out.println("用户名或密码错误!!");
        }

        //2.释放资源
        JDBCUtils.closeAll(rs, stmt, conn);

    3).怎样解决SQL注入的问题:

3).怎样解决SQL注入的问题:

        不用Statement,改用它的子接口:PreparedStatement--预处理的SQL执行器

        PreparedStatement:它可以严格的区分出"SQL语句"和"数据",不会将数据中的SQL的格式化符号解析为SQL格式化符号,而认为就是数据。

12.JDBC_使用PreparedStatement解决SQL注入的问题:

    Scanner sc = new Scanner(System.in);
    System.out.println("请输入登录名:");
    String loginName = sc.nextLine();
    System.out.println("输入密码:");
    String loginPwd = sc.nextLine();

    Connection conn = JDBCUtils.getConnection();
    //1.先封装SQL语句,数据部分要用?号占位,任何数据类型不需要单引号
    String sql = "select * from users where uname = ? and password = ?";    / /如果拼接字符串的话会报错
    //2.获取PreparedStatemet对象
    PreparedStatement ps = conn.prepareStatement(sql);
    //3.填充数据                                             //  第一个 问号 是 1  不是 0
    ps.setString(1, loginName);
    ps.setString(2, loginPwd);

    //4.执行
    ResultSet rs = ps.executeQuery();//注意:不要再传SQL语句了,因为之前已经有SQL语句了
    if(rs.next()){
        System.out.println("欢迎:" + loginName + " 登录系统!");
    }else{
        System.out.println("用户名或密码错误!!");
    }

    //2.释放资源
    JDBCUtils.closeAll(rs, ps, conn);

13.JDBC_使用PreparedStatement完成增删改查(CRUD)

    public void add() throws Exception{
        //1.获取连接对象
        Connection conn = JDBCUtils.getConnection();
        //2.获取预处理对象
        String sql = "insert into product values(null,?,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        //3.填充数据
        ps.setString(1, "奔驰");
        ps.setInt(2, 440000);
        ps.setInt(3, 1);
        //4.执行SQL
        int row = ps.executeUpdate();
        System.out.println("添加影响的行数:" + row);
        //5.释放资源
        JDBCUtils.closeAll(null, ps, conn);
    }
    public void update() throws Exception{
        //1.获取连接对象
        Connection conn = JDBCUtils.getConnection();
        //2.获取预处理对象
        String sql = "update product set pname = ? , price = ? where pid = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        //3.填充数据
        ps.setString(1, "奔驰E级");
        ps.setInt(2, 420000);
        ps.setInt(3, 9);
        //4.执行SQL
        int row = ps.executeUpdate();
        System.out.println("修改影响的行数:"  + row);
        //5.释放资源
        JDBCUtils.closeAll(null, ps, conn);
    }
    public void delete() throws Exception{
        Connection conn = JDBCUtils.getConnection();
        String sql = "delete from product where pid = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, 9);
        int row = ps.executeUpdate();
        System.out.println("删除影响的行数:" + row);
        JDBCUtils.closeAll(null, ps, conn);
    }
    public void findAll() throws Exception{
        Connection conn = JDBCUtils.getConnection();
        String sql = "select * from product";
        PreparedStatement ps = conn.prepareStatement(sql);

        ResultSet rs = ps.executeQuery();
        while(rs.next()){
            System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t"
                            + rs.getInt("price") + "\t" + rs.getInt("cid"));
        }
        JDBCUtils.closeAll(rs, ps, conn);
    }
    @Test
    public void findById() throws Exception{
        Connection conn = JDBCUtils.getConnection();
        String sql = "select * from product where pid = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, 1);

        ResultSet rs = ps.executeQuery();
        if(rs.next()){
            System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t"
                                        + rs.getInt("price") + "\t" + rs.getInt("cid"));
        }

        JDBCUtils.closeAll(rs, ps, conn);

    }