zoukankan      html  css  js  c++  java
  • JDBC05详解各个类2

    1、DriverManager:驱动管理对象(类)

     功能:

      a. 注册驱动:告诉程序该使用哪一个数据库驱动jar包

        DriverManager下的方法 public static void registerDriver(java.sql.Driver driver):注册与给定的驱动程序DriverManager

        写代码使用:Class.forName("com.mysql.jdbc.Driver"); 把Driver类文件加载进内存,类里的代码会被自动执行。静态代码块的代码会被自动执行。

        通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块。

        static {
            try {
                java.sql.DriverManager.registerDriver(new Driver());
            } catch (SQLException var1) {
                throw new RuntimeException("Can't register driver!");
            }
        }

      注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。不过建议还是写上。

        即Class.forName("com.mysql.jdbc.Driver");可以省略。因为mysql5的jar包中META-INF->services->java.sql.Driver文件下存在“com.mysql.jdbc.Driver”,会自动地注册驱动。如果代码中没有注册会先读取java.sql.Driver文件去自动的注册驱动。

      b. 获取数据库连接

      • 方法:static Connection getConnection(String url, String user, String password) 尝试建立与给定数据库URL的连接。
      • 参数:
        • url:指定连接的路径

            语法:jdbc:mysql://ip地址(域名):端口号/数据库名称

            例子:jdbc:mysql://localhost:3306/db3

            细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称

        • user:用户名
        • password:密码

    2、Connection:数据库连接对象(接口)

     java.sql.Connection功能:

      a. 获取执行sql的对象

      • java.sql.Statement createStatement():创建一个Statement对象,用于将SQL语句发送到数据库。
      • java.sql.PreparedStatement prepareStatement(String sql):创建一个PreparedStatement对象,用于将参数化的SQL语句发送到数据库。

      b. 管理事务

      • 开启事务:void setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务。将此连接的自动提交模式设置为给定状态。
      • 提交事务:void commit()。使自上次提交/回滚以来所做的所有更改都将永久性,并释放此Connection对象当前持有的任何数据库锁。
      • 回滚事务:void rollback()。撤销在当前事务中所做的所有更改,并释放此Connection对象当前持有的任何数据库锁。

    3、Statement:执行sql的对象(接口)

     用于执行静态SQL(里面参数都是给定值)语句并返回其生成的结果的对象。

     a. 执行sql

      • boolean execute(String sql):执行给定的SQL语句,这可能会返回多个结果。可以执行任意的sql,了解即可。
      • int executeUpdate(String sql):执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句。
        • 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功,返回值>0的则执行成功,反之则失败。
      • ResultSet executeQuery(String sql):执行给定的SQL语句,该语句返回单个ResultSet对象。执行DQL(select)语句。

    4、练习

     1. account表添加一条记录

    package cn.itcast.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    /**
     * account表添加一条记录 insert语句
     */
    public class JDBCDemo2 {
        public static void main(String[] args) {
            Statement stat = null;
            Connection conn = null;
            //1. 注册驱动
            try {
                Class.forName("com.mysql.jdbc.Driver");
                //2. 定义sql
                String sql = "insert into account values (null,'wangwu',3000)";
                //3. 获取Connection对象
                conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
                //4. 获取执行sql的对象 Statement
                stat = conn.createStatement();
                //5. 执行sql
                int count = stat.executeUpdate(sql);//count为影响的行数
                //6. 处理结果
                System.out.println(count);
                if(count > 0 ){
                    System.out.println("添加成功!");
                }else{
                    System.out.println("添加失败!");
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //7. 释放资源
                //避免空指针异常
                if(stat != null){
                    try {
                        stat.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
    
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }

     输出结果:

     

     2. account表修改记录

    package cn.itcast.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    /**
     * account表修改记录
     */
    public class JDBCDemo3 {
        public static void main(String[] args) {
            Statement stat = null;
            Connection conn = null;
            //1. 注册驱动
            try {
                Class.forName("com.mysql.jdbc.Driver");
                //2. 定义sql
                String sql = "update account set balance = 1500 where id = 3";
                //3. 获取Connection对象
                conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
                //4. 获取执行sql的对象 Statement
                stat = conn.createStatement();
                //5. 执行sql
                int count = stat.executeUpdate(sql);//count为影响的行数
                //6. 处理结果
                System.out.println(count);
                if(count > 0 ){
                    System.out.println("更新成功!");
                }else{
                    System.out.println("更新失败!");
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //7. 释放资源
                //避免空指针异常
                if(stat != null){
                    try {
                        stat.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
    
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }

     输出结果:

     

     3. account表删除一条记录

    package cn.itcast.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    /**
     * account表删除一条记录
     */
    public class JDBCDemo4 {
        public static void main(String[] args) {
            Statement stat = null;
            Connection conn = null;
            //1. 注册驱动
            try {
                Class.forName("com.mysql.jdbc.Driver");
                //2. 定义sql
                String sql = "delete from account where id = 3";
                //3. 获取Connection对象
                conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
                //4. 获取执行sql的对象 Statement
                stat = conn.createStatement();
                //5. 执行sql
                int count = stat.executeUpdate(sql);//count为影响的行数
                //6. 处理结果
                System.out.println(count);
                if(count > 0 ){
                    System.out.println("删除成功!");
                }else{
                    System.out.println("删除失败!");
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //7. 释放资源
                //避免空指针异常
                if(stat != null){
                    try {
                        stat.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

     输出结果:

     

     4. 新增Student表

    package cn.itcast.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    /**
     * 执行DDL语句
     */
    public class JDBCDemo5 {
        public static void main(String[] args) {
            Statement stat = null;
            Connection conn = null;
            //1. 注册驱动
            try {
                Class.forName("com.mysql.jdbc.Driver");
                //2. 定义sql
                String sql = "create table student (id int , name varchar(20))";
                //3. 获取Connection对象
                conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
                //4. 获取执行sql的对象 Statement
                stat = conn.createStatement();
                //5. 执行sql
                int count = stat.executeUpdate(sql);//count为影响的行数
                //6. 处理结果
                System.out.println(count);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //7. 释放资源
                //避免空指针异常
                if(stat != null){
                    try {
                        stat.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

     输出结果:

     

    5、ResultSet:结果集对象,封装查询结果(接口)

    • boolean next():将光标从当前位置向下移动一行。ResultSet光标最初位于第一行之前; 第一次调用方法next使第一行成为当前行; 第二个调用使第二行成为当前行,依此类推。当调用next方法返回false时,光标位于最后一行之后。
    • getXXX(参数):获取数据
      • XXX:代表数据类型。如:int getInt(),String getString()
      • 参数:
        • int:代表列的编号,从1开始。如:getString(1)
        • String:代表带名称。如:getDouble("balance")

          int getInt(int coulumnIndex)、int getInt(String columnLabel)、String getString(int coulumnIndex)、String getString(String columnLabel)

    • 注意:
      • 使用步骤:

          1. 游标向下移动一行

          2. 判断是否有数据

          3. 获取数据

    package cn.itcast.jdbc;
    
    import java.sql.*;
    
    public class JDBCDemo7 {
        public static void main(String[] args) {
            Statement stat = null;
            Connection conn = null;
            ResultSet rs = null;
            //1. 注册驱动
            try {
                Class.forName("com.mysql.jdbc.Driver");
                //2. 定义sql
                String sql = "select * from account";
                //3. 获取Connection对象
                conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
                //4. 获取执行sql的对象 Statement
                stat = conn.createStatement();
                //5. 执行sql
                rs = stat.executeQuery(sql);//count为影响的行数
                //6. 处理结果
                //6.1 让游标向下移动一行,循环判断游标是否是最后一行末尾
                while(rs.next()){
                    //6.2 获取数据
                    int id = rs.getInt(1);
                    String name = rs.getString("name");
                    double balance = rs.getDouble(3);
    
                    System.out.println(id + "---" + name + "---" + balance);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //7. 释放资源
                //避免空指针异常
                if(rs != null){
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(stat != null){
                    try {
                        stat.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

     输出结果:

     

    6、练习

     定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回。

      1. 定义emp类

      2. 定义方法 public List<Emp> findAll(){}

      3. 实现方法 select * from emp;

    package cn.itcast.jdbc;
    
    import java.util.Date;
    
    /**
     * 封装Emp表数据的JavaBean
     */
    public class Emp {
        private int id;
        private String ename;
        private int job_id;
        private int mgr;
        private Date joindate;
        private double salary;
        private double bonus;
        private int dept_id;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getEname() {
            return ename;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public int getJob_id() {
            return job_id;
        }
    
        public void setJob_id(int job_id) {
            this.job_id = job_id;
        }
    
        public int getMgr() {
            return mgr;
        }
    
        public void setMgr(int mgr) {
            this.mgr = mgr;
        }
    
        public Date getJoindate() {
            return joindate;
        }
    
        public void setJoindate(Date joindate) {
            this.joindate = joindate;
        }
    
        public double getSalary() {
            return salary;
        }
    
        public void setSalary(double salary) {
            this.salary = salary;
        }
    
        public double getBonus() {
            return bonus;
        }
    
        public void setBonus(double bonus) {
            this.bonus = bonus;
        }
    
        public int getDept_id() {
            return dept_id;
        }
    
        public void setDept_id(int dept_id) {
            this.dept_id = dept_id;
        }
    
        @Override
        public String toString() {
            return "Emp{" +
                    "id=" + id +
                    ", ename='" + ename + '\'' +
                    ", job_id=" + job_id +
                    ", mgr=" + mgr +
                    ", joindate=" + joindate +
                    ", salary=" + salary +
                    ", bonus=" + bonus +
                    ", dept_id=" + dept_id +
                    '}';
        }
    }
    package cn.itcast.jdbc;
    
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.List;
    
    public class JDBCDemo8 {
    
        public static void main(String[] args) {
            List<Emp> list = new JDBCDemo8().findAll();
            System.out.println(list);
            System.out.println(list.size());
        }
    
        /**
         * 查询所有emp对象
         * @return
         */
        public List<Emp> findAll(){
            Connection conn = null;
            Statement stat = null;
            ResultSet rs = null;
            List<Emp> list = null;
    
            try {
                //1. 注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                //2. 获取连接
                conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
                //3. 定义sql
                String sql = "select * from emp";
                //4. 获取执行sql的对象 Statement
                stat = conn.createStatement();
                //5. 执行sql
                rs = stat.executeQuery(sql);
                //6. 遍历结果集,封装对象,装载集合
                Emp emp = null;
                list = new ArrayList<Emp>();
                while(rs.next()){
                    //获取数据
                    int id = rs.getInt("id");
                    String ename = rs.getString("ename");
                    int job_id = rs.getInt("job_id");
                    int mgr = rs.getInt("mgr");
                    Date joindate = rs.getDate("joindate");//这是java.sql.Date,是java.util.Date的子类
                    double salary = rs.getDouble("salary");
                    double bonus = rs.getDouble("bonus");
                    int dept_id = rs.getInt("dept_id");
                    //创建emp对象,并赋值
                    emp = new Emp();
                    emp.setId(id);
                    emp.setEname(ename);
                    emp.setJob_id(job_id);
                    emp.setMgr(mgr);
                    emp.setJoindate(joindate);
                    emp.setSalary(salary);
                    emp.setBonus(bonus);
                    emp.setDept_id(dept_id);
                    //装载集合
                    list.add(emp);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //7. 释放资源
                //避免空指针异常
                if(rs != null){
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(stat != null){
                    try {
                        stat.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
            return list;
        }
    }

     输出结果:

     

    6、PreparedStatement:执行sql的对象,比Statement更强大(接口)

     表示预编译(动态)SQL语句的对象。

     1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题。

      a. 输入用户随便,输入密码:a' or 'a' = 'a

      b. sql:select * from user where username = 'sdfweeyr' and password = 'a' or 'a' = 'a',执行此sql会查出来表中所有的数据

     2. 解决sql注入问题:使用PreparedStatement对象来解决

     3. 预编译的SQL:参数使用?作为占位符,执行sql时给?赋值即可。

        4. 使用PreparedStatement步骤:

      a. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar

      b. 注册驱动
      c. 获取数据库连接对象 Connection
      d. 定义sql

        注意:sql的参数使用?作为占位符。select * from user where username = ? and password = ?;

      e. 获取执行sql语句的对象PreparedStatement Connection.prepareStatement(String sql);

      f. 给?赋值:

        PreparedStatement方法:void setXXX(参数1, 参数2)  将指定参数设置为给定的Java int/double/String/boolean等值。 

        参数1:?的位置编号从1开始。int parameterIndex

        参数2:?的值

      g. 执行sql,接受返回结果,不需要传递sql语句

      h. 处理结果

      i. 释放资源

    package cn.itcast.jdbc;
    
    import java.sql.*;
    import java.util.Scanner;
    
    /**
     * 需求:
     *             1. 通过键盘录入用户名和密码
     *             2. 判断用户是否登录成功
     */
    public class JDBCDemo11 {
    
        public static void main(String[] args) {
            //1. 键盘录入,接收用户名和密码
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入用户名");
            String username = sc.nextLine();
            System.out.println("请输入密码");
            String password = sc.nextLine();
    
            //2. 调用方法
            JDBCDemo11 jdbcDemo11 = new JDBCDemo11();
            boolean flag = jdbcDemo11.login(username,password);
    
            //3. 判断结果,输出不同语句
            if(flag){
                System.out.println("登录成功!");
            }else{
                System.out.println("用户名或密码错误!");
            }
        }
    
        /**
         * 登录方法,使用Prepared Statement实现
         */
        public boolean login(String username,String password){
    
            if(username == null && password == null){
                return false;
            }
            Connection conn = null;
            PreparedStatement pstat = null;
            ResultSet rs = null;
            //连接数据库判断是否登录成功
            //1. 获取连接
            try {
                conn = JDBCUtils.getConnection();
                //2. 定义sql
                String sql = "select * from user where username= ? and password = ?";
                System.out.println(sql);
                //3. 获取执行sql的对象
                pstat = conn.prepareStatement(sql);
                //给?赋值
                pstat.setString(1,username);
                pstat.setString(2,password);
                //4. 执行查询,不需要传递sql
                rs = pstat.executeQuery();
                //5. 判断
                return rs.next();//如果有下一行则返回true
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JDBCUtils.close(rs, pstat, conn);
            }
            return false;
        }
    }

     执行结果:

        

     5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作。

      a. 可以防止SQL注入

      b. 效率更高

  • 相关阅读:
    vue ui 命令使用
    vue环境搭建
    简版的电商项目学习——第四步:从数据库获取数据,页面跳转以及跳转页面成功与否的提示信息设置
    简版的电商项目学习——第三步:数据库创建,注册功能实现以及用户密码加密
    简版的电商项目学习——第二步:页面布局,以及路由设置
    简版的电商项目学习——第一步:express后台搭建以及基本模块、插件配置
    sass 控制指令
    继承,混合器,占位符的用法 和 sass的数据类型
    ruby 安装 和 sass入门
    大数乘法,分治O(n^1.59)
  • 原文地址:https://www.cnblogs.com/ajing2018/p/15765154.html
Copyright © 2011-2022 走看看