day2324_jdbc

今日内容

零、 复习昨日
一、作业
二、SQL注入
三、PreparedStatement
四、事务
五、DBUtil

零、 复习昨日

一、引言


1.1 如何操作数据库

使用客户端工具访问数据库,需要手工建立连接,输入用户名和密码登录,编写 SQL 语句,点击执行,查看操作结果(结果集或受影响行数)。

客户端操作数据库步骤
image-20230316181353316

1.2 实际开发中,会采用客户端操作数据库吗?

在实际开发中,当用户的数据发生改变时,不可能通过客户端操作执行 SQL 语句,因为操作量过大,无法保证效率和正确性。

二、JDBC


2.1 什么是 JDBC?

JDBC(Java Database Connectivity) Java 连接数据库的规范(标准),可以使用 Java 语言连接数据库完成 CRUD 操作。

2.2 JDBC 核心思想

Java 中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。由数据库厂商提供驱动实现类(Driver 数据库驱动)。

核心思想
image-20230316181411600

2.2.1 MySQL 数据库驱动

  • mysql-connector-java-5.1.X.jar 适用于 5.X 版本
  • mysql-connector-java-8.0.X.jar 适用于 8.X版本

ps: 常识

jar包其实就是一种压缩包,其中就是一个java项目

mysql-connector-java-5.1.X.jar 中就是mysql厂商根据jdbc协议提供一些实现代码

2.3 环境搭建

mysql厂商提供的jdbc规范的实现,要想完成JDBC操作,就需要将驱动包加入到当前项目中.

2.3.1 idea导入类库

打开项目结构(Project Structure)
image-20230320105013907
选择libraries,添加jar包
image-20221121111310058
本地磁盘选择jar包
image-20221121111402075
应用生效
image-20221121111442727
下方,External查看导入类库
image-20221121111616446

2.3.2 maven依赖

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
            <!-- <version>8.0.29</version> -->
        </dependency>

2.3.3 测试

public class TestJDBC {

    public static void main(String[] args) throws ClassNotFoundException {
        /**
         * 这个是java反射机制
         * 通过类路径将mysql驱动包文件加载到jvm
         */
        Class.forName("com.mysql.jdbc.Driver");
        System.out.println("OK" );// 只要不报错,就说明jar包导入成功
    }
}

三、JDBC编程

JDBC编程有标准步骤(八股文)

  • 注册驱动
    • 将sql语句的运行环境加载到JVM
  • 连接数据库
  • 获得执行SQL的对象
  • 执行SQL语句,获得结果
  • 关流

3.1 注册驱动

Class.forName("com.mysql.jdbc.Driver");//5.7版本 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");//5.8版本 加载驱动

3.2 连接数据库

  • 通过 DriverManager.getConnection(url,user,password) 获取数据库连接对象
    • URL:jdbc:mysql://localhost:3306/database
      • ?useUnicode=true&characterEncoding=utf8 // 解决数据编码格式乱码
      • &useSSL=false // 解决执行时控制台红色警告
      • &serverTimezone=UTC // mysql8版本需要加时区
    • username:root
    • password:123456
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库名字?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC   ", "数据库用户名","数据库密码");
  • URL(Uniform Resource Locator) 统一资源定位符:由协议、IP、端口、SID(程序实例名称)组成

3.3 获取发送 SQL 的对象

通过 Connection 对象获得 Statement 对象,用于对数据库进行通用访问。

Statement statement = conn.createStatement();

3.4 执行SQL 语句

执行 SQL 语句并接收执行结果。

String sql ="INSERT INTO t_jobs(JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY) VALUES('JAVA_Le','JAVA_Lecturer',4000,10000);";

int result = statement.executeUpdate(sql);//执行SQL语句并接收结果
  • 注意:在编写 DML 语句时,一定要注意字符串参数的符号是单引号 ‘值’
  • DML 语句:增删改时,返回受影响行数(int 类型)。
  • DQL 语句:查询时,返回结果数据(ResultSet 结果集)。

3.5 处理结果

接受处理操作结果。

if(result == 1){
	System.out.println("Success");
}
  • 受影响行数:逻辑判断、方法返回。
  • 查询结果集:迭代、依次获取。

3.6 释放资源

遵循先开后关原则,释放所使用到的资源对象。

statement.close();
conn.close();

3.7 案例

准备数据库表,进行CRUD.

create table tb_user(
 id int(11) primary key auto_increment comment '用户编号',
 username varchar(10) comment '用户名',
 password varchar(10) comment '密码',
 phone varchar(11) comment '手机号',
 create_time date comment '注册时间',
 money double(10,2) comment '账户余额',
 sex int(1) comment '性别 1男2女'
);

需求: 使用JDBC完成对tb_user表插入数据


package com.qf.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 演示JDBC
 */
public class Demo1_insert {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        // 1 加载驱动
        // ps: 利用反射技术,将驱动类加载到JVM
        Class.forName("com.mysql.jdbc.Driver");

        // 2 通过驱动管理对象获得连接对象
        /**
         * 参数1 url: 数据库连接的地址
         *    协议://ip:端口/库名
         * 参数2 username: 数据库用户名
         * 参数3 password: 数据库密码
         */
        String url = "jdbc:mysql://localhost:3306/java2311?useSSL=false&serverTimezone=UTC";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url,username,password);

        // 3 通过连接对象,创建执行sql语句的对象
        Statement statement = conn.createStatement();

        // 4 通过执行语句对象,执行sql,获得结果
        String sql = "insert into tb_user (id,username,password,phone,create_time,money,sex) values (2,'root','123456','1122200','2022-11-21',2000.0,2)";
        // 执行查询,是executeQuery()
        // 执行增删改,是executeUpdate(),返回受影响的行数
        int num = statement.executeUpdate(sql);

        if (num > 0) {
            System.out.println("插入成功!!" );
        }

        // 5 关流
        statement.close();
        conn.close();

    }
}

四、完成增删改

4.1 插入

参考入门案例

4.2 更新

任何的JDBC都是那5个步骤.

package com.qf.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 更新
 */
public class Demo2_update {

    public static void main(String[] args) throws Exception {

        // 1 加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        // 2 通过驱动管理对象获得连接对象
        String url = "jdbc:mysql://localhost:3306/java2311?useSSL=false";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, username, password);

        // 3 通过连接对象创建执行语句对象
        Statement statement = conn.createStatement( );

        // 4 通过执行语句对象执行sql,获得结果
        String sql = "update tb_user set username = '小孟', phone = '666666' where id = 3";
        int num = statement.executeUpdate(sql);

        if (num > 0) {
            System.out.println("更新成功!" );
        }

        // 5 将对象的流关闭
        statement.close();
        conn.close();
    }
}

4.3 删除

package com.qf.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class Demo3_delete {

    public static void main(String[] args) {
        Statement statement = null;
        Connection conn = null;
        try {
            // 1 加载驱动
            Class.forName("com.mysql.jdbc.Driver");

            // 2 获得连接
            String url = "jdbc:mysql://localhost:3306/java2311?useSSL=false";
            String username = "root";
            String password = "123456";
            conn = DriverManager.getConnection(url, username, password);

            // 3 获得语句对象
            statement = conn.createStatement( );

            // 4 执行sql
            int num = statement.executeUpdate("delete from tb_user where id = 3");

            if (num > 0) {
                System.out.println("删除成功" );
            }
        }catch (Exception e) {
            // 如果有异常,要打印出来,因为要根据异常解决问题
            e.printStackTrace();
        } finally {
            try {
                // 5 关闭连接
                statement.close( );
                conn.close( );
            }catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

五、查询结果集ResultSet【重要】

查询返回的是一种虚拟表,Java的JDBC中是使用结果集(ResultSet)来封装这个虚拟表,结果集就是一个集合,内部就存储了列名和每行数据,那么学习查询的重点是

  • 从结果集取值
package com.qf.jdbc;

import com.mysql.jdbc.Driver;

import java.sql.*;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class Demo4_select {
    public static void main(String[] args) throws Exception{

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");
        Statement statement = conn.createStatement( );
        /**
         * 执行查询方法 executeQuery()
         * 返回值是 ResultSet 结果集,其中就包含查询返回的所有数据(一张虚拟表)
         * ResultSet结果集中包含列和行数据,其中有个光标指向表头
         * next() 方法会向下移动一行,返回boolean,为true即有下一行数据,false该行没数据
         * 当指向该行后,有方法可以获取该行列值
         * getXxx()   ps:xxx是各种数据类型
         * getXxx(String columnLabel) 通过列名取值,如果有别名要使用别名
         */
        String sql = "select birthday,money,username,password,id,sex,age from tb_user";
        ResultSet rs = statement.executeQuery(sql);
        while (rs.next()){
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            String sex = rs.getString("sex");
            int age = rs.getInt("age");
            Date birthday = rs.getDate("birthday");
            double money = rs.getDouble("money");
            System.out.println(id+"-"+username+"-"+password+"-"+sex+"-"+age+"-"+birthday+"-"+money);
        }
        rs.close();
        statement.close();
        conn.close();
    }
}

image-20221121164359945

六、登录案例【重要】

需求:

  • 通过控制台用户输入用户名和密码。
  • 用户输入的用户名和密码作为条件,编写查询 SQL 语句。
    • select * from user where username = xxx and password = xxx
  • 如果该用户存在,提示登录成功,反之提示失败。
package com.qf.jdbc;

import com.mysql.jdbc.Driver;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class Demo5_Login {

    public static void main(String[] args) {

        // 1 输入用户名和密码
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:" );
        String username = scanner.nextLine( );

        System.out.println("请输入密码:" );
        String password = scanner.nextLine( );

        // 2 根据用户名和密码查人
       boolean isOk =  findUserByLogin(username,password);

        // 3 结果
        if (isOk) {
            System.out.println("登录成功!" );
        } else {
            System.out.println("用户名或密码错误!" );
        }
    }

    // 使用捕获代码完成
    private static boolean findUserByLogin(String username, String password) {
        Connection conn = null;
        Statement statement = null;
        boolean isOk = false;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/2311?useSSL=false", "root", "123456");

            statement = conn.createStatement( );

            // 根据用户名和密码查询,注意字符串拼接.特别注意单引号
            ResultSet rs = statement.executeQuery("select * from tb_user where username = '"+username+"' and password = '"+password+"'");

            // 只要有值,就说明数据库有这个信息,登录成功
            if (rs.next()) {
               // System.out.println("登录成功!" );
                int id = rs.getInt("id");
                String uname= rs.getString("username");
                // ...

                System.out.println(id+"-"+username);
                isOk = true;
            } else {
               // System.out.println("用户名或密码错误!!" );
            }
        }catch (Exception e) {
            System.out.println("SQL操作出错!" );
            e.printStackTrace();// 打印异常
        } finally {
            try{
                statement.close();
                conn.close();
            }catch (Exception e) {
                System.out.println("关流异常" );
                e.printStackTrace();// 打印异常
            }
        }
        return isOk;
    }
}

七、ORM【重要】

7.1 什么是ORM

目前使用JDBC完成了CRUD,但是现在是进行CRUD,增删改方法要设计很多参数,查询的方法需要设计集合才能返回.


在实际开发中,我们需要将零散的数据封装到对象处理.

ORM (Object Relational Mapping) 对象关系映射

是指数据库表Java的实体类有关系,可以进行映射

  • 数据库表 --> Java的类
    • tb_user —> User.java
  • 字段 --> 类的属性
    • id int --> private int id;
    • username varchar --> private String username;
  • 一行数据 --> 类的对象
  • 一行数据内每个列的值 --> 对象的属性值

7.2 实体类

实体类: 数据表中零散数据的载体,用来封装数据.

  • 表名 设计 类名
  • 将列名设计成属性名
    • id --> id
    • create_time --> createTime (下划线转驼峰)
  • 将列的数据类型设计成属性的数据类型
  • 给类提供对应set get

一般项目中一个表就会对应一个实体类,所有的实体类都会放在model/entity/pojo/javabeen包结构中


将来写项目,数据库设计完,搭建完项目,第一件事件就是根据表结构,创建实体类

package com.qf.model; // 包
public class User {   // 实体类,是表名
	// 属性是字段名
    private int id;
    private String username;
    private String password;
    private String phone;
    private Date createTime;
    private double money;
    private int sex;
    
    // setter getter...
}

image-20221122160619448

7.3 ORM改造登录案例

package com.qf.jdbc;

import com.qf.model.User;

import java.sql.*;
import java.util.Scanner;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 使用orm改造login登录案例
 */
public class Demo6_login_orm {
    public static void main(String[] args) {
        input();
    }
    // 1 键盘输入
    public static void input() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = scanner.nextLine( );

        System.out.println("请输入密码:");
        String password = scanner.nextLine( );

        // 调用方法执行查询
        User user = findUserByUsernameAndPassword(username, password);

        if (user != null) {
            System.out.println("用户登录成功" );
            System.out.println("用户信息: " + user );
        } else {
            System.out.println("用户名或密码错误!" );
        }
    }

    // 2 执行登录
    public static User findUserByUsernameAndPassword(String username, String password) {
        Connection conn = null;
        Statement s = null;
        ResultSet rs = null;
        // 声明user,赋值为null,下方如果登录成功,创建user对象
        // 即将来,可以通过user是否为空判断是否登录成功
        User user = null;
        try {
            // 1 驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2 连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");
            // 3 语句
            s = conn.createStatement( );

            // 4 查询
            String sql = "select * from tb_user where username = '"+username+"' and password = '"+password+"'";

            // 执行
            rs = s.executeQuery(sql);

            // 判断成功,说明查询到用户
            if (rs.next()) {
                // 取出数据
                int id = rs.getInt("id");
                String username1 = rs.getString("username");
                String password1 = rs.getString("password");
                String phone = rs.getString("phone");
                Date createTime = rs.getDate("createTime");
                double money = rs.getDouble("money");
                int sex = rs.getInt("sex");

                // 封装数据
                user = new User();
                user.setId(id);
                user.setUsername(username1);
                user.setPassword(password1);
                user.setPhone(phone);
                user.setCreateTime(createTime);
                user.setMoney(money);
                user.setSex(sex);
            }

        } catch (Exception e) {
            System.out.println("出错了!" + e.getMessage( ));
        } finally {

            // 5 关流
            try {
                rs.close();
                s.close( );
                conn.close( );

            } catch (SQLException e) {
                System.out.println("关流时有异常" + e.getMessage( ));
            }
        }
        return user;
    }
}

八、SQL注入

8.1 什么是SQL注入

select * from tb_user where username = ‘111’ and password = ‘111

select * from tb_user where username = ‘111’ and password = ‘111' or '1=1

用户输入的数据中有SQL关键词,导致在执行SQL语句时出现一些不正常的情况.这就是SQL注入!


出现SQL注入是很危险

image-20230322084643699

8.2 避免SQL注入

问题出现在用户输入数据时,里面有关键词,再配合字符串拼接导致出现SQL注入.所以为了避免SQL注入,可以在用户输入数据到SQL之前,先把SQL语句预编译,预处理后,JDBC就会知道此SQL需要几个参数,后续再将用户输入的数据给参数填充.

这就是PreparedStatement

九、PreparedStatement【重点】

PreparedStatement是Statement的子接口,用来预处理SQL语句

PreparedStatement使用

  • 先写SQL语句,SQL语句中的参数不能直接拼接,而是使用?占位
  • 使用ps预处理SQL语句,处理的?号,ps内部就会知道此SQL语句需要几个参数
  • 再动态给?处填充值
  • 执行sql

image-20230322084657336

package com.qf.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 预处理语句
 */
public class Demo3 {

    public static void main(String[] args) throws Exception {

        // 1加载驱动
        // 2获得连接
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");

        // 3获得[预处理语句]对象
        /**
         * 使用预处理对象有步骤
         * 1 先写sql,语句中需要拼接参数的地方用?占位
         * 2 通过连接对象,调用处理语句的方法,传入sql参数,对语句处理后
         *   获得一个含有处理过sql的语句对象
         * 3 给处理过的?处赋值
         * 4 执行
         */
        String sql = "select * from tb_user where username = ? and password = ?";
        System.out.println("处理前:" + sql );
        PreparedStatement ps = conn.prepareStatement(sql);
        System.out.println("处理后:" + ps );
        // 3 给?赋值
        ps.setString(1,"uzi");
        ps.setString(2,"123456");
        System.out.println("赋值后:" + ps );

        // 4执行sql语句
        ResultSet rs = ps.executeQuery( );// 【特别注意: 不需要再传参数】
        while(rs.next()) {
            User user = new User( );
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setPassword(rs.getString("password"));
            user.setPhone(rs.getString("phone"));
            user.setCreateTime(rs.getDate("create_time"));
            user.setMoney(rs.getDouble("money"));
            user.setSex(rs.getInt("sex"));

            System.out.println(user );
        }

        // 5关流
        rs.close();
        ps.close();
        conn.close();
    }
}

使用预处理语句改造登录案例

package com.qf.jdbc;

import java.sql.*;
import java.util.Scanner;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 使用预处理语句完成登录
 */
public class Demo4_login_plus {

    public static void main(String[] args) {
        input();
    }

    // 设计方法完成输入
    public static void input() {
        System.out.println("欢迎登录LPL选手管理系统" );
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:" );
        String username = scanner.nextLine( );
        System.out.println("请输入密码:" );
        String password = scanner.nextLine( );

        User user = login(username, password);

        if (user != null) {
            System.out.println("欢迎进入系统:" + user );
        } else {
            System.out.println("用户名或密码错误!" );
        }

    }


    public static User login(String username,String password){
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        User user = null; // 初始值
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");
            // 1 先写sql,条件写?
            String sql = "select * from tb_user where username = ? and password = ?";
            // 2 获得预处理语句对象
            ps = conn.prepareStatement(sql);
            // 3 给?赋值
            ps.setString(1,username);
            ps.setString(2,password);
            System.out.println(ps );
            // 4 执行
            rs = ps.executeQuery( );
            while (rs.next()) {
                user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setPhone(rs.getString("phone"));
                user.setCreateTime(rs.getDate("create_time"));
                user.setMoney(rs.getDouble("money"));
                user.setSex(rs.getInt("sex"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
                ps.close();
                conn.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        return user;
    }
}

十、预处理语句完成CRUD

10.1 插入

// 插入
    public static void insert() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");

        // 1 sql
        String sql = "insert into tb_user values (?,?,?,?,?,?,?)";
        // 2 预处理
        PreparedStatement ps = conn.prepareStatement(sql);
        // 3 给?赋值
        ps.setInt(1,6);
        ps.setString(2,"JK");
        ps.setString(3,"123456");
        ps.setString(4,"5555");
        /**
         * setDate() 需要传入java.sql.Date包下的日期对象
         * java.sql.Date没有无参构造,只有一个有参构造,传入是毫秒值
         */
        // 方案1: 获得当前时间毫秒值
        // java.util.Date date = new java.util.Date( );// 创建当前日期对象
        // long time = date.getTime( );// 获得当前毫秒值

        // 方案2: 获得指定时间的毫秒值
        LocalDate localDate = LocalDate.of(2020, 10, 1);
        java.util.Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        long time = date.getTime();

        // 方案3: 获得系统毫秒值
        //long time = System.currentTimeMillis( );// 获得当前毫秒值

        ps.setDate(5,new java.sql.Date(time));
        ps.setDouble(6,4800);
        ps.setInt(7,1);

        // 4 执行
        int i = ps.executeUpdate( );
        System.out.println(i > 0 ?"OK":"ERR" );

        ps.close();
        conn.close();
    }

10.2 更新

  public static void main(String[] args) throws Exception {
        LocalDate localDate = LocalDate.of(1999, 10, 1);
        java.util.Date date = java.util.Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        User user = new User(1,"mlxg","6666","1111",date,6300,1);
        update(user);
    }

    // 更新
    public static void update(User user) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");

        // 1 sql
        String sql = "update tb_user set username = ?,password = ? ," +
                "phone = ?,create_time = ?,money = ?,sex = ? " +
                "where id = ?";
        // 2 预处理
        PreparedStatement ps = conn.prepareStatement(sql);
        // 3 给?赋值
        ps.setString(1,user.getUsername());
        ps.setString(2,user.getPassword());
        ps.setString(3,user.getPhone());
        ps.setDate(4,new java.sql.Date(user.getCreateTime().getTime()));
        ps.setDouble(5,user.getMoney());
        ps.setInt(6,user.getSex());
        ps.setInt(7,user.getId());

        // 4 执行
        int i = ps.executeUpdate( );
        System.out.println(i > 0 ?"OK":"ERR" );

        ps.close();
        conn.close();
    }

10.3 删除

// 删除
    public static void delete() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");

        // 1 先写sql
        String sql = "delete from tb_user where id = ?";
        // 2 预处理
        PreparedStatement ps = conn.prepareStatement(sql);
        // 3 ?赋值
        ps.setInt(1,4);
        // 4 执行
        int i = ps.executeUpdate( );
        System.out.println(i > 0 ?"OK":"ERR" );

        ps.close();
        conn.close();
    }

10.4 查询

// 根据id从数据库查询出用户信息
    public static User getUserById(int id) throws Exception {
        // 1 注册驱动
        Class.forName("com.mysql.Driver");
        // 2 获得连接
        String url = "jdbc:mysql://localhost:3306/java2301?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, username, password);
        User user = null;
        // 3 预处理
        // 3.1 写sql,参数用?占位
        String sql = "select  * from tb_user where id = ?";
        // 3.2 预处理?号
        PreparedStatement ps = conn.prepareStatement(sql);
        // 3.3 给?赋值
        ps.setInt(1,id);

        // 4 执行sql
        ResultSet rs = ps.executeQuery( );

        if(rs.next()) {
            // 取出数据
            String username1 = rs.getString("username");
            String password1 = rs.getString("password");
            String phone = rs.getString("phone");
            Date createTime = rs.getDate("createTime");
            double money = rs.getDouble("money");
            int sex = rs.getInt("sex");

            // 封装数据
            user = new User();
            user.setId(id);
            user.setUsername(username1);
            user.setPassword(password1);
            user.setPhone(phone);
            user.setCreateTime(createTime);
            user.setMoney(money);
            user.setSex(sex);
        }

        return user;
    }
 // 设计方法,查询全部数据,返回值是List集合,集合中是全部用户数据
    public static List<User> findAll() throws Exception{
        // 1 注册驱动
        Class.forName("com.mysql.Driver");
        // 2 获得连接
        String url = "jdbc:mysql://localhost:3306/java2301?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, username, password);
        ArrayList<User> list = new ArrayList<>( );
        User user = null;
        // 3.1 写sql
        String sql = "select * from tb_user";
        // 3.2 处理sql
        PreparedStatement ps = conn.prepareStatement(sql);

        // 4 执行
        ResultSet rs = ps.executeQuery( );


        while(rs.next()) {
            // 取出数据
            int id = rs.getInt("id");
            String username1 = rs.getString("username");
            String password1 = rs.getString("password");
            String phone = rs.getString("phone");
            Date createTime = rs.getDate("createTime");
            double money = rs.getDouble("money");
            int sex = rs.getInt("sex");

            // 封装数据
            user = new User();
            user.setId(id);
            user.setUsername(username1);
            user.setPassword(password1);
            user.setPhone(phone);
            user.setCreateTime(createTime);
            user.setMoney(money);
            user.setSex(sex);

            // 【重点】 将对象存储入集合
            list.add(user);
        }

        return list;
    }

十一、DbUtils【重点,理解,会用】

11.1 介绍

Apache DBUtils是一个流行的数据库工具库,它提供了一组简单、轻量级的工具和接口,用于简化与关系型数据库进行交互的过程。


  • ResultSetHandler接口:转换类型接口
    • BeanHandler类:实现类,把一条记录转换成对象
    • BeanListHandler类:实现类,把多条记录转换成List集合。
    • ScalarHandler类:实现类,适合获取一行一列的数据。
  • QueryRunner:执行sql语句的类
    • 增、删、改:update();
    • 查询:query();

11.2 依赖

	<dependency>
         <groupId>commons-dbutils</groupId>
         <artifactId>commons-dbutils</artifactId>
         <version>1.7</version>
    </dependency>

11.3 使用

package com.qf.jdbc;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 使用DbUtils完成crud
 *
 * 扩展: java实体类,叫做javabean
 *  bean即对象
 *
 */
public class Demo6 {

    public static void main(String[] args) throws Exception {
        // delete( );
        // insert();
        // selectOne();
        selectAll();
    }

    private static void delete() throws SQLException {
        // 加载驱动不再需要
        // 通过驱动管理器获得连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2313?useSSL=false", "root", "123456");
        // 创建sql执行器
        QueryRunner queryRunner = new QueryRunner( );
        /**
         * 参数1: 数据库连接对象
         * 参数2: sql语句字符串,也需要参数变?
         * 参数3: 给?赋值
         */
        int i = queryRunner.update(conn, "delete from tb_user where id = ?", 6);
        System.out.println(i );
        DbUtils.closeQuietly(conn);
    }

    private static void insert() throws SQLException {
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");
        QueryRunner queryRunner = new QueryRunner( );
        Object[] params = {6,"zzz","123456","1111",new java.sql.Date(1),1000.0,1};
        /**
         * update()方法的第三个参数是不定长参数
         * 即可以传入任意个数的参数值
         * 不定长参数本质上其实是数组
         * -----------------------
         * 需要注意数组中的值的顺序需要和?的顺序一致
         */
        int i = queryRunner.update(conn, "insert into tb_user values (?,?,?,?,?,?,?)", params);
        System.out.println(i );

        DbUtils.closeQuietly(conn);
    }


  
    // 查一个,封装
    private static void selectOne() throws SQLException {
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");
        // sql执行器
        QueryRunner queryRunner = new QueryRunner( );
        // 查询结果的对象处理器,作用是将查询结果直接封装成指定对象
        BeanHandler<User> handler = new BeanHandler<>(User.class);
        /**
         * 执行查询调用query方法
         * 参数1: 数据库连接
         * 参数2: sql语句,如果有参数用?
         * 参数3: 查询结果封装处理器
         * 参数4: 不定长参数,对?赋值
         */
        User user = queryRunner.query(conn, "select * from tb_user where id = ?", handler, 1);

        System.out.println(user );

        DbUtils.closeQuietly(conn);

    }

    // 查询全部,使用集合存储对象
    private static void selectAll() throws SQLException {
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");
        // sql执行器
        QueryRunner queryRunner = new QueryRunner( );
        // 查询[多个结果]的对象处理器
        BeanListHandler<User> handler = new BeanListHandler<>(User.class);
        List<User> list = queryRunner.query(conn, "select * from tb_user", handler);

        list.forEach(s -> System.out.println(s ));
        DbUtils.closeQuietly(conn);
    }
}

Connection conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/java2311?useSSL=false”, “root”, “123456”);
// sql执行器
QueryRunner queryRunner = new QueryRunner( );
// 查询结果的对象处理器,作用是将查询结果直接封装成指定对象
BeanHandler handler = new BeanHandler<>(User.class);
/**
* 执行查询调用query方法
* 参数1: 数据库连接
* 参数2: sql语句,如果有参数用?
* 参数3: 查询结果封装处理器
* 参数4: 不定长参数,对?赋值
*/
User user = queryRunner.query(conn, “select * from tb_user where id = ?”, handler, 1);

    System.out.println(user );

    DbUtils.closeQuietly(conn);

}

// 查询全部,使用集合存储对象
private static void selectAll() throws SQLException {
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2311?useSSL=false", "root", "123456");
    // sql执行器
    QueryRunner queryRunner = new QueryRunner( );
    // 查询[多个结果]的对象处理器
    BeanListHandler<User> handler = new BeanListHandler<>(User.class);
    List<User> list = queryRunner.query(conn, "select * from tb_user", handler);

    list.forEach(s -> System.out.println(s ));
    DbUtils.closeQuietly(conn);
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/149957.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于MS16F3211芯片的触摸控制灯的状态变化和亮度控制(11.15)

1.任务所需实现基本功能 关机状态时白灯亮蓝灯灭&#xff0c;此时长按按键无反应&#xff0c;白灯亮度降低的状态&#xff0c;蓝灯保持灭的状态。点按按键一次&#xff0c;白灯熄灭&#xff0c;蓝灯亮此时W引脚控制的灯亮。继续点按按键。蓝灯亮&#xff0c;此时W引脚控制的灯…

9.3 【MySQL】系统表空间

了解完了独立表空间的基本结构&#xff0c;系统表空间的结构也就好理解多了&#xff0c;系统表空间的结构和独立表空间基本类似&#xff0c;只不过由于整个MySQL进程只有一个系统表空间&#xff0c;在系统表空间中会额外记录一些有关整个系统信息的页面&#xff0c;所以会比独立…

python之 flask 框架(2)项目拆分的 执行逻辑

项目的结构图 app.py # 导入__init__.py 比较特殊 from APP import create_appapp create_app() if __name__ __main__:app.run(debugTrue)init.py # __inti__.py # 初始化文件&#xff0c;创建Flask应用 from flask import Flask from .views import bluedef create_ap…

多媒体播放器Infuse mac中文版软件特点

Infuse mac是一款多媒体播放器应用&#xff0c;它支持播放多种格式的视频文件、音频文件和图片文件&#xff0c;并且可以通过AIrPlay将媒体内容投放到其他设备上。Infuse还支持在线视频流媒体播放和本地网络共享&#xff0c;用户可以通过它来访问家庭网络上的媒体文件。 Infuse…

【银行测试】支付功能、支付平台、支持渠道如何测试?

有朋友提问&#xff1a;作为一个支付平台&#xff0c;接入了快钱、易宝或直连银行等多家的渠道&#xff0c;内在的产品流程是自己的。业内有什么比较好的测试办法&#xff0c;来测试各渠道及其支持的银行通道呢&#xff1f; 作为产品&#xff0c;我自己办了十几张银行卡方便测…

Python数据容器(字典)

字典 1.字典的定义2.字典数据的获取3.字典的嵌套4.嵌套字典的内容获取5.字典的常用操作6.常用操作总结7.遍历字典8.练习 1.字典的定义 同样使用{}&#xff0c;不过存储的元素是一个一个的&#xff1a;键值对&#xff0c;语法如下 # 定义字典字面量 {key:value,key:value,...,…

2年博士后|心外医生赴美国耶鲁大学开展研究

G医生决定放弃申报CSC&#xff0c;改为自费出国&#xff0c;并在美国密歇根大学安娜堡分校和耶鲁大学两所名校中选择了更为出名的后者。因为不是CSC出资&#xff0c;G医生得以通过签证&#xff0c;顺利出国&#xff0c;实现了在世界知名高校从事2年博士后的个人职业规划目标。 …

IDEA安装配置SceneBuilder

1、下载 SceneBuilder 地址&#xff1a; Scene Builder - Gluon ​​​​​​​ Scene Builder | JavaFX中文官方网站 选择符合自己系统版本&#xff0c;JAVA版本的下载 2、安装SceneBuilder 执行下载的 SceneBuilder 安装程序&#xff0c;并按照安装向导的指示进行…

Oracle(17)Managing Roles

目录 一、基础知识 1、基础介绍 2、Predefined Roles 预定义的角色 3、各种角色的介绍 二、基础操作 1、创建角色 2、修改用户默认role 3、回收role 4、删除role 5、为角色授权 6、授予角色给用户 7、查看用户包含的角色&#xff1a; 8、查看角色所包含的权限 9、…

深入解析JavaScript中的变量作用域与声明提升

JS中的变量作用域 背景&#xff1a; ​ 之前做js逆向的时候&#xff0c;有一个网站很有意思&#xff0c;就是先出现对其赋值&#xff0c;但是后来的变量赋值没有对其发生修改&#xff0c;决定说一下js中的作用域问题. 全局作用域&#xff1a; ​ 全局作用域的变量可以在任何…

python 基础语法 (常常容易漏掉)

同一行显示多条语句 python语法中要求缩进&#xff0c;但是同一行可以显示多条语句 在 Python 中&#xff0c;可以使用分号 (;) 将多个语句放在同一行上。这样可以在一行代码中执行多个语句&#xff0c;但需要注意代码的可读性和维护性。 x 5; y 10; z x y; print(z) 在…

官网下载tomcat

1、Tomcat官网地址&#xff1a; https://tomcat.apache.org/ 2、下载以及安装步骤

基于乌鸦算法优化概率神经网络PNN的分类预测 - 附代码

基于乌鸦算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于乌鸦算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于乌鸦优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

LeetCode - 142. 环形链表 II (C语言,快慢指针,配图)

如果你对快慢指针&#xff0c;环形链表有疑问&#xff0c;可以参考下面这篇文章&#xff0c;了解什么是环形链表后&#xff0c;再做这道题会非常简单&#xff0c;也更容易理解下面的图片公式等。 LeetCode - 141. 环形链表 &#xff08;C语言&#xff0c;快慢指针&#xff0c;…

想买GPT4会员却只能排队?来看看背后的故事!

文章目录 &#x1f9d0; 为什么要进候选名单&#xff1f;&#x1f50d; 究竟发生了什么&#xff1f;&#x1f62e; IOS端还能买会员&#xff01;&#x1f914; 网页端为啥不能订会员&#xff1f;第一点&#xff1a;防止黑卡消费第二点&#xff1a;当技术巨头遇上资源瓶颈&#…

原力CEO赵锐:ToDesk是国内唯一适合高精远程办公需求的解决方案

随着数字办公在各行业的渗透&#xff0c;远程办公也逐渐成为一种常态。2000多名艺术家员工遍布全球各地的江苏原力数字科技股份有限公司&#xff08;下称&#xff1a;原力&#xff09;&#xff0c;是一家国内业务范围、规模均遥遥领先的数字业务内容提供商。一直以来&#xff0…

JZ22:链表中倒数第k个结点

JZ22&#xff1a;链表中倒数第k个结点 题目描述&#xff1a; 输入一个链表&#xff0c;输出该链表中倒数第k个结点。 示例1 输入&#xff1a; 1,{1,2,3,4,5} 返回值&#xff1a; {5} 分析&#xff1a; 快慢指针思想&#xff1a; 需要两个指针&#xff0c;快指针fast&…

计算机毕业设计 基于SpringBoot的在线考试系统的研究与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

C语言不可不敲系列:跳水比赛排名问题

目录 1题干&#xff1a; 2解题思路&#xff1a; 3代码: 4运行结果: 5总结: 1题干&#xff1a; 5位运动员参加了10米台跳水比赛&#xff0c;有人让他们预测比赛结果 A选手说&#xff1a;B第二&#xff0c;我第三&#xff1b; B选手说&#xff1a;我第二&#xff0c;E第四&am…

8.查询数据

一、单表查询 MySQL从数据表中查询数据的基本语为SELECT语。SELECT语的基本格式是: SELECT {* | <字段列名>} [ FROM <表 1>, <表 2>… [WHERE <表达式> [GROUP BY <group by definition> [HAVING <expression> [{<operator>…