• jdbc(DriverManager+Connection+Statement+ResultSet)+SQL注入+开启预编译+数据连接池


    1 JDBC概念

    JDBC 就是使用Java连接并操作数据库的一套API

    全称:( Java DataBase Connectivity ) Java 数据库连接

    2 JDBC优势

    可随时替换底层数据库,访问数据库的Java代码基本不变

    以后编写操作数据库的代码只需要面向JDBC(接口),操作哪儿个关系型数据库就需要导入该数据库的驱动包,如需要操作MySQL数据库,就需要再项目中导入MySQL数据库的驱动包。

    3 JDBC快速入门

    第一步:编写Java代码
    第二步:Java代码将SQL发送到MySQL服务端
    第三步:MySQL服务端接收到SQL语句并执行该SQL语句
    第四步:将SQL语句执行的结果返回给Java代码

    3.1 编写代码步骤

    • 创建工程,导入驱动jar包
      将mysql的驱动包放在模块下的lib目录(随意命名)下,并将该jar包添加为库文件
      在这里插入图片描述

    在这里插入图片描述

    • 在添加为库文件的时候,有如下三个选项

      • Global Library : 全局有效
      • Project Library : 项目有效
      • Module Library : 模块有效

        一般选择全局有效

    • 注册驱动

      Class.forName("com.mysql.jdbc.Driver");
      
      • 1
    • 获取连接
      Java代码需要发送SQL给MySQL服务端,就需要先建立连接

      Connection conn = DriverManager.getConnection(url, username, password);
      
      • 1
    • 定义SQL语句

      String sql =update…” ;
      
      • 1
    • 获取执行SQL对象

      执行SQL语句需要SQL执行对象,而这个执行对象就是Statement对象

      Statement stmt = conn.createStatement();
      
      • 1
    • 执行SQL

      stmt.executeUpdate(sql);  
      
      • 1
    • 处理返回结果

    • 释放资源

    3.2 完整代码

    /**
     * JDBC快速入门
     */
    public class JDBCDemo {
    
        public static void main(String[] args) throws Exception {
            //1. 注册驱动
            //Class.forName("com.mysql.jdbc.Driver");
            //2. 获取连接
            String url = "jdbc:mysql://127.0.0.1:3306/db1";
            String username = "root";
            String password = "1234";
            Connection conn = DriverManager.getConnection(url, username, password);
            //3. 定义sql
            String sql = "update account set money = 2000 where id = 1";
            //4. 获取执行sql的对象 Statement
            Statement stmt = conn.createStatement();
            //5. 执行sql
            int count = stmt.executeUpdate(sql);//受影响的行数
            //6. 处理结果
            System.out.println(count);
            //7. 释放资源
            stmt.close();
            conn.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3 DriverManager

    DriverManager(驱动管理类)用于

    • 注册驱动

      但MySQL 5之后的驱动包,可以省略注册驱动的步骤

    • 获取数据库连接

      语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2…

      示例:jdbc:mysql://127.0.0.1:3306/db1

      细节:

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

      • 配置 useSSL=false 参数,禁用安全连接方式,解决警告提示

    4 Connection

    Connection(数据库连接对象)作用:

    • 获取执行 SQL 的对象
    • 管理事务

    4.1 获取执行对象

    • 普通执行SQL对象

      Statement createStatement()
      
      • 1

      入门案例中就是通过该方法获取的执行对象。

    • 预编译SQL的执行SQL对象:防止SQL注入

      PreparedStatement  prepareStatement(sql)
      
      • 1

      通过这种方式获取的 PreparedStatement SQL语句执行对象可以防止SQL注入。

    4.2 事务管理

    先回顾一下MySQL事务管理的操作:

    • 开启事务 : BEGIN; 或者 START TRANSACTION;
    • 提交事务 : COMMIT;
    • 回滚事务 : ROLLBACK;

    MySQL默认是自动提交事务

    接下来学习JDBC事务管理的方法。

    Connection几口中定义了3个对应的方法:

    • 开启事务
      参与autoCommit 表示是否自动提交事务,true表示自动提交事务,false表示手动提交事务。而开启事务需要将该参数设为为false。
    • 提交事务
    • 回滚事务
      具体代码实现如下:
    /**
     * JDBC API 详解:Connection
     */
    public class JDBCDemo3_Connection {
    
        public static void main(String[] args) throws Exception {
            //1. 注册驱动
            //Class.forName("com.mysql.jdbc.Driver");
            //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
            String url = "jdbc:mysql:///db1?useSSL=false";
            String username = "root";
            String password = "1234";
            Connection conn = DriverManager.getConnection(url, username, password);
            //3. 定义sql
            String sql1 = "update account set money = 3000 where id = 1";
            String sql2 = "update account set money = 3000 where id = 2";
            //4. 获取执行sql的对象 Statement
            Statement stmt = conn.createStatement();
    
            try {
                // ============开启事务==========
                conn.setAutoCommit(false);
                //5. 执行sql
                int count1 = stmt.executeUpdate(sql1);//受影响的行数
                //6. 处理结果
                System.out.println(count1);
                int i = 3/0;
                //5. 执行sql
                int count2 = stmt.executeUpdate(sql2);//受影响的行数
                //6. 处理结果
                System.out.println(count2);
    
                // ============提交事务==========
                //程序运行到此处,说明没有出现任何问题,则需求提交事务
                conn.commit();
            } catch (Exception e) {
                // ============回滚事务==========
                //程序在出现异常时会执行到这个地方,此时就需要回滚事务
                conn.rollback();
                e.printStackTrace();
            }
    
            //7. 释放资源
            stmt.close();
            conn.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    5 Statement

    Statement对象的作用就是用来执行SQL语句。而针对不同类型的SQL语句使用的方法也不一样。

    /**
      * 执行DML语句
      * @throws Exception
      */
    @Test
    public void testDML() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql = "update account set money = 3000 where id = 1";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        //5. 执行sql
        int count = stmt.executeUpdate(sql);//执行完DML语句,受影响的行数
        //6. 处理结果
        //System.out.println(count);
        if(count > 0){
            System.out.println("修改成功~");
        }else{
            System.out.println("修改失败~");
        }
        //7. 释放资源
        stmt.close();
        conn.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    6 ResultSet

    6.1 概述

    ResultSet(结果集对象)是用来封装SQL查询语句的结果。

    而执行了DQL语句后就会返回该对象,对应执行DQL语句的方法如下:

    ResultSet  executeQuery(sql):执行DQL 语句,返回 ResultSet 对象
    
    • 1

    那么我们就需要从 ResultSet 对象中获取我们想要的数据。ResultSet 对象提供了操作查询结果数据的方法,如下:

    boolean next()

    • 将光标从当前位置向前移动一行
    • 判断当前行是否为有效行

    6.2 代码实现

    /**
      * 执行DQL
      * @throws Exception
      */
    @Test
    public void testResultSet() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql = "select * from account";
        //4. 获取statement对象
        Statement stmt = conn.createStatement();
        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //6. 处理结果, 遍历rs中的所有数据
        // 6.1 光标向下移动一行,并且判断当前行是否有数据
        while (rs.next()){
            //6.2 获取数据  getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money");
    
            System.out.println(id);
            System.out.println(name);
            System.out.println(money);
    
            System.out.println("--------------");
        }
    
        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    7 SQL注入

    SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。

    代码模拟

    select * from tb_user where username = 'sjdljfld' and password = ''or '1' = '1'
    
    • 1

    从上面语句可以看出条件 username = 'sjdljfld' and password = '' 不管是否满足,而 or 后面的 '1' = '1' 是始终满足的,最终条件是成立的,就可以正常的进行登陆了。

    7.1 PreparedStatement简介

    PreparedStatement作用: 预编译SQL语句并执行:预防SQL注入问题。

    • 获取 PreparedStatement 对象

      // SQL语句中的参数值,使用?占位符替代
      String sql = "select * from user where username = ? and password = ?";
      // 通过Connection对象获取,并传入对应的sql语句
      PreparedStatement pstmt = conn.prepareStatement(sql);
      
      • 1
      • 2
      • 3
      • 4
    • 设置参数值

    • 执行SQL语句

      executeUpdate(); 执行DDL语句和DML语句

      executeQuery(); 执行DQL语句

      注意:

      • 调用这两个方法时不需要传递SQL语句,因为获取SQL语句执行对象时已经对SQL语句进行预编译了。

    7.2 使用PreparedStatement改进sql注入

     @Test
    public void testPreparedStatement() throws  Exception {
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
    
        // 接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "' or '1' = '1";
    
        // 定义sql
        String sql = "select * from tb_user where username = ? and password = ?";
        // 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        // 设置?的值
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);
        // 执行sql
        ResultSet rs = pstmt.executeQuery();
        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }
        //7. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    执行上面语句就可以发现不会出现SQL注入漏洞问题了。那么PreparedStatement又是如何解决的呢?它是将特殊字符进行了转义,转义的SQL如下:

    select * from tb_user where username = 'sjdljfld' and password = '\'or \'1\' = \'1'
    
    • 1

    8 开启预编译

    数据库检查SQL和编译SQL花费的时间比执行SQL的时间还要长。如果我们只是重新设置参数,那么检查SQL语句和编译SQL语句将不需要重复执行。这样就提高了性能。
    
    • 1
    • 开启预编译功能

      在代码中编写url时需要加上以下参数。而我们之前根本就没有开启预编译功能,只是解决了SQL注入漏洞。

      useServerPrepStmts=true
      
      • 1
    • 配置MySQL执行日志(重启mysql服务后生效)

      在mysql配置文件(my.ini)中添加如下配置

      log-output=FILE
      general-log=1
      general_log_file="D:\mysql.log"
      slow-query-log=1
      slow_query_log_file="D:\mysql_slow.log"
      long_query_time=2
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    9 数据库连接池

    9.1 简介

    • 数据库连接池是个容器,负责分配、管理数据库连接(Connection)

    • 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;

    • 释放超过最大空闲时间的数据库连接来避免数据库连接遗漏

    • 好处

      • 资源重用
      • 提升系统响应速度
      • 避免数据库连接遗漏

    之前我们代码中使用连接是没有使用都创建一个Connection对象,使用完毕就会将其销毁。这样重复创建销毁的过程性能很低。
    而使用数据库连接池能达到Connection对象的复用.

    9.2 实现

    • 标准接口:DataSource

      Connection getConnection()
      
      • 1

      以后就不需要通过 DriverManager 对象获取 Connection 对象,而是通过连接池(DataSource)获取 Connection 对象。

    • 常见的数据库连接池

      • DBCP
      • C3P0
      • Druid

      我们现在使用更多的是Druid(阿里巴巴开源),它的性能比其他两个会好一些。

    9.3 Driud使用

    • 导入jar包 druid-1.1.12.jar
    • 定义配置文件
    • 加载配置文件
    • 获取数据库连接池对象
    • 获取连接

    现在通过代码实现,首先需要先将druid的jar包放到项目下的lib下并添加为库文件。编写配置文件如下:

    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true
    username=root
    password=1234
    # 初始化连接数量
    initialSize=5
    # 最大连接数
    maxActive=10
    # 最大等待时间
    maxWait=3000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用druid的代码如下:

    /**
     * Druid数据库连接池演示
     */
    public class DruidDemo {
    
        public static void main(String[] args) throws Exception {
            //1.导入jar包
            //2.定义配置文件
            //3. 加载配置文件
            Properties prop = new Properties();
            prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
            //4. 获取连接池对象
            DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
    
            //5. 获取数据库连接 Connection
            Connection connection = dataSource.getConnection();
            System.out.println(connection); //获取到了连接后就可以继续做其他操作了
    
            //System.out.println(System.getProperty("user.dir"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    10 案例实现

    完成商品品牌数据的增删改查操作

    • 查询:查询所有数据
    • 添加:添加品牌
    • 修改:根据id修改
    • 删除:根据id删除

    9.1 环境准备

    • 数据库表 tb_brand

      -- 删除tb_brand表
      drop table if exists tb_brand;
      -- 创建tb_brand表
      create table tb_brand (
          -- id 主键
          id int primary key auto_increment,
          -- 品牌名称
          brand_name varchar(20),
          -- 企业名称
          company_name varchar(20),
          -- 排序字段
          ordered int,
          -- 描述信息
          description varchar(100),
          -- 状态:0:禁用  1:启用
          status int
      );
      -- 添加数据
      insert into tb_brand (brand_name, company_name, ordered, description, status)
      values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
             ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
             ('小米', '小米科技有限公司', 50, 'are you ok', 1);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    • 在pojo包下实体类 Brand

      /**
       * 品牌
       * alt + 鼠标左键:整列编辑
       * 在实体类中,基本数据类型建议使用其对应的包装类型
       */
      public class Brand {
          // id 主键
          private Integer id;
          // 品牌名称
          private String brandName;
          // 企业名称
          private String companyName;
          // 排序字段
          private Integer ordered;
          // 描述信息
          private String description;
          // 状态:0:禁用  1:启用
          private Integer status;
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public String getBrandName() {
              return brandName;
          }
      
          public void setBrandName(String brandName) {
              this.brandName = brandName;
          }
      
          public String getCompanyName() {
              return companyName;
          }
      
          public void setCompanyName(String companyName) {
              this.companyName = companyName;
          }
      
          public Integer getOrdered() {
              return ordered;
          }
      
          public void setOrdered(Integer ordered) {
              this.ordered = ordered;
          }
      
          public String getDescription() {
              return description;
          }
      
          public void setDescription(String description) {
              this.description = description;
          }
      
          public Integer getStatus() {
              return status;
          }
      
          public void setStatus(Integer status) {
              this.status = status;
          }
      
          @Override
          public String toString() {
              return "Brand{" +
                      "id=" + id +
                      ", brandName='" + brandName + '\'' +
                      ", companyName='" + companyName + '\'' +
                      ", ordered=" + ordered +
                      ", description='" + description + '\'' +
                      ", status=" + status +
                      '}';
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
    5.2.2 查询所有
     /**
       * 查询所有
       * 1. SQL:select * from tb_brand;
       * 2. 参数:不需要
       * 3. 结果:List
       */
    
    @Test
    public void testSelectAll() throws Exception {
        //1. 获取Connection
        //3. 加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //4. 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
    
        //5. 获取数据库连接 Connection
        Connection conn = dataSource.getConnection();
        //2. 定义SQL
        String sql = "select * from tb_brand;";
        //3. 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //4. 设置参数
        //5. 执行SQL
        ResultSet rs = pstmt.executeQuery();
        //6. 处理结果 List 封装Brand对象,装载List集合
        Brand brand = null;
        List<Brand> brands = new ArrayList<>();
        while (rs.next()){
            //获取数据
            int id = rs.getInt("id");
            String brandName = rs.getString("brand_name");
            String companyName = rs.getString("company_name");
            int ordered = rs.getInt("ordered");
            String description = rs.getString("description");
            int status = rs.getInt("status");
            //封装Brand对象
            brand = new Brand();
            brand.setId(id);
            brand.setBrandName(brandName);
            brand.setCompanyName(companyName);
            brand.setOrdered(ordered);
            brand.setDescription(description);
            brand.setStatus(status);
    
            //装载集合
            brands.add(brand);
        }
        System.out.println(brands);
        //7. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    5.2.3 添加数据
    /**
      * 添加
      * 1. SQL:insert into tb_brand(brand_name, company_name, ordered, description, status) values(?,?,?,?,?);
      * 2. 参数:需要,除了id之外的所有参数信息
      * 3. 结果:boolean
      */
    @Test
    public void testAdd() throws Exception {
        // 接收页面提交的参数
        String brandName = "香飘飘";
        String companyName = "香飘飘";
        int ordered = 1;
        String description = "绕地球一圈";
        int status = 1;
    
        //1. 获取Connection
        //3. 加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //4. 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //5. 获取数据库连接 Connection
        Connection conn = dataSource.getConnection();
        //2. 定义SQL
        String sql = "insert into tb_brand(brand_name, company_name, ordered, description, status) values(?,?,?,?,?);";
        //3. 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //4. 设置参数
        pstmt.setString(1,brandName);
        pstmt.setString(2,companyName);
        pstmt.setInt(3,ordered);
        pstmt.setString(4,description);
        pstmt.setInt(5,status);
    
        //5. 执行SQL
        int count = pstmt.executeUpdate(); // 影响的行数
        //6. 处理结果
        System.out.println(count > 0);
    
        //7. 释放资源
        pstmt.close();
        conn.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    5.2.4 修改数据
    /**
      * 修改
      * 1. SQL:
    
         update tb_brand
             set brand_name  = ?,
             company_name= ?,
             ordered     = ?,
             description = ?,
             status      = ?
         where id = ?
    
       * 2. 参数:需要,所有数据
       * 3. 结果:boolean
       */
    
    @Test
    public void testUpdate() throws Exception {
        // 接收页面提交的参数
        String brandName = "香飘飘";
        String companyName = "香飘飘";
        int ordered = 1000;
        String description = "绕地球三圈";
        int status = 1;
        int id = 4;
    
        //1. 获取Connection
        //3. 加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //4. 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //5. 获取数据库连接 Connection
        Connection conn = dataSource.getConnection();
        //2. 定义SQL
        String sql = " update tb_brand\n" +
            "         set brand_name  = ?,\n" +
            "         company_name= ?,\n" +
            "         ordered     = ?,\n" +
            "         description = ?,\n" +
            "         status      = ?\n" +
            "     where id = ?";
    
        //3. 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
    
        //4. 设置参数
        pstmt.setString(1,brandName);
        pstmt.setString(2,companyName);
        pstmt.setInt(3,ordered);
        pstmt.setString(4,description);
        pstmt.setInt(5,status);
        pstmt.setInt(6,id);
    
        //5. 执行SQL
        int count = pstmt.executeUpdate(); // 影响的行数
        //6. 处理结果
        System.out.println(count > 0);
    
        //7. 释放资源
        pstmt.close();
        conn.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    5.2.5 删除数据
    /**
      * 删除
      * 1. SQL:
                delete from tb_brand where id = ?
      * 2. 参数:需要,id
      * 3. 结果:boolean
      */
    @Test
    public void testDeleteById() throws Exception {
        // 接收页面提交的参数
        int id = 4;
        //1. 获取Connection
        //3. 加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //4. 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //5. 获取数据库连接 Connection
        Connection conn = dataSource.getConnection();
        //2. 定义SQL
        String sql = " delete from tb_brand where id = ?";
        //3. 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //4. 设置参数
        pstmt.setInt(1,id);
        //5. 执行SQL
        int count = pstmt.executeUpdate(); // 影响的行数
        //6. 处理结果
        System.out.println(count > 0);
    
        //7. 释放资源
        pstmt.close();
        conn.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    第三章 关系数据库标准语言SQL
    【Redis】Redis做为缓存,MySQL如何与Redis保持数据一致
    使用 StringUtils.split 的坑
    非暴力 破解wifi密码
    Error: [mobx-miniprogram] no store specified (小程序全局数据共享bug)
    PHP8的数组-PHP8知识详解
    J2EE基础:自定义mvc框架实现
    The Steps to prepare the Remote Device and necessary packages for Deep Learning
    【方向盘】启动命令和IDEA如何传递:VM参数、命令行参数、系统参数、环境变量参数、main方法参数
    【Linux网络编程】服务端编程初体验
  • 原文地址:https://blog.csdn.net/zhiaidaidai/article/details/133756524