一、JDBC

1、JDBC概述

JDBC提供了以下功能:

  • 连接到数据库:JDBC提供了一种标准的、可移植的方式来连接各种关系型数据库,这使得应用程序可以在不同的数据库之间移植和重用。
  • 执行SQL语句:JDBC提供了一种标准的方式来执行SQL语句,包括查询、插入、更新和删除操作。
  • 处理事务:JDBC支持事务处理,这是管理数据库操作的一种重要机制,以确保数据的一致性和完整性。
  • 处理元数据:JDBC提供了一种标准的方式来处理数据库元数据,例如表和列的信息,从而使应用程序可以更加灵活地操作数据库

JDBC

需要导入依赖:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.21</version>
</dependency>

Java连接数据库 :

/**
 * @document: Java连接数据库
 * 1、加载数据库驱动
 * 2、建立数据库连接
 * 3、创建Statement对象 用于加载SQL语句
 * 4、执行SQL语句
 * 5、如果执行查询操作 处理查询结果
 * 6、关闭连接
 * @Author:SmallG
 * @CreateTime:2023/8/24+9:19
 */

public class JDBCTest {
    public static void main(String[] args) {
        test1();

    }

    /**
     * 加载数据库驱动
     */
    public static void test1() {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String url = "jdbc:mysql://localhost:3306/hedu" +
                "?useSSL=false&serverTimeZone=Asia/Shanghai"; //数据库连接字符串 关闭证书验证
        String username = "root"; //数据库用户名
        String password = "root"; //数据库密码
        //创建数据库连接
        Connection connection = null;
        // 创建Statement对象
        Statement statement = null;
        // 定义sql语句
        String sql = "SELECT name FROM teacher ";
        //创建接收查询操作返回值的对象
        ResultSet res = null;
        try {
            connection = DriverManager.getConnection(url, username, password);
            // 创建Statement对象 用于加载SQL语句
            statement = connection.createStatement();
            //执行sql语句 查询语句 返回查询结果
            res = statement.executeQuery(sql);
            //处理查询结果(只针对查询操作)
            while (res.next()) {
                String s = res.getString(1); //取出第一个数据 jdbc下标是从1开始

                System.out.println(s);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if (connection != null){
                try {
                    connection.close(); //关闭数据库连接
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }
}

2、执行SQL

通过以下三种方法来执行SQL语句:

  • execute():该方法可以执行任意SQL语句,包括SELECT、INSERT、UPDATE、DELETE等,返回一个boolean值,true的时候,表示执行结果包含ResultSet对象。一般情况下,可以用于执行DDL、DCL语句。
  • executeUpdate():该方法用于执行INSERT、UPDATE或DELETE等数据修改语句,返回一个int值,表示受影响的行数。
  • executeQuery():该方法用于执行SELECT语句,返回一个ResultSet对象,包含查询结果的行和列。
/**
 * @document: Java连接数据库
 * 1、加载数据库驱动
 * 2、建立数据库连接
 * 3、创建Statement对象 用于加载SQL语句
 * 4、执行SQL语句
 * 5、如果执行查询操作 处理查询结果
 * 6、关闭连接
 * @Author:SmallG
 * @CreateTime:2023/8/24+9:19
 */

public class JDBCTest {
    private static Connection connection;

    /**
     * 静态代码块中初始化connection对象
     */
    static {
        //加载数据库驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String url = "jdbc:mysql://localhost:3306/hedu?useSSL=false" +
                "&serverTimeZone = Asia/Shanghai";
        String username = "root";
        String password = "root";
        try {
            connection = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            test2();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行DDL语句创建一个表(了解)
     */
    public static void test2() throws SQLException {
        Statement statement = connection.createStatement();
        String sql = "CREATE TABLE userinfo(" +
                "   id INT PRIMARY KEY AUTO_INCREMENT," +
                "   username VARCHAR (30)," +
                "   password VARCHAR (30)," +
                "   nickname VARCHAR (30)," +
                "   age INT (3))";
         // 执行DDL语句 返回false(表示没有结果集)
        boolean execute = statement.execute(sql);
        System.out.println(execute);
        connection.close();
    }  
    
     //执行DML语句 往userinfo表中插入一条数据
    public static void test3() throws SQLException {
        Statement statement = connection.createStatement();
        String sql = "INSERT INTO userinfo  (username, password, nickname, age)" +
                "VALUES ('张三', '123456', '阿三', 20)";
        int i = statement.executeUpdate(sql); //返回受影响的行数 数据库改变了几行
        if (i>0){
            System.out.println("保存数据成功,数据库改变了"+i+"行");
        }else {
            System.out.println("保存数据失败!");
        }
       
    }
}

public static void test4() throws SQLException {
    Scanner sc = new Scanner(System.in);
    Statement statement = connection.createStatement();
    System.out.println("欢迎注册!");
    System.out.println("请输入用户名:");
    String username = sc.next();
    System.out.println("请输入密码:");
    String password = sc.next();
    System.out.println("请输入昵称:");
    String nickName = sc.next();
    System.out.println("请输入年龄:");
    int age = sc.nextInt();
    String sql = "INSERT INTO userinfo  (username, password, nickname, age)" +
            "VALUES('" + username + "','" + password + "','" + nickName + "','" + age + "')";
    int i = statement.executeUpdate(sql);
    if (i>0){
        System.out.println("插入数据成功");
    }else{
        System.out.println("插入数据失败");
    }
    connection.close();
}

 /**
 * 执行DML修改操作
 */
 public static void test5() throws SQLException {
    Statement statement = connection.createStatement();
    String sql = "UPDATE userinfo SET password = '628161' WHERE username = '张三'";
    int i = statement.executeUpdate(sql);
    if (i>0){
        System.out.println("修改密码成功");
    }else{
        System.out.println("修改密码失败");
    }
     connection.close();
 }

    /**
     * 执行DML删除语句
     */
    public static void test6() throws SQLException {
        Statement statement = connection.createStatement();
        String sql = "DELETE FROM userinfo WHERE username='张三'";
        int i = statement.executeUpdate(sql);
        if (i>0){
            System.out.println("删除成功");
        }else{
            System.out.println("删除失败");
        }
        connection.close();
    }

3、连接管理

/**
 * @document: 数据库连接
 * @Author:SmallG
 * @CreateTime:2023/8/24+14:03
 */

public class DBUtil {
    private DBUtil() {

    }

    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 返回数据库连接
    public static Connection getConnection() throws SQLException {
        String url = "jdbc:mysql://localhost:3306/hedu?useSSL=false&" +
                "serverTimeZone=Asia/Shanghai&characterEncoding=utf-8";
        String username = "root";
        String password = "root";
        return DriverManager.getConnection(url, username, password);
    }
}

4、JDBC关联查询

/**
 * @document: JDBC关联查询
 * @Author:SmallG
 * @CreateTime:2023/8/24+14:38
 */

public class JDBCTest4 {
    public static void main(String[] args) throws SQLException {
        //查询刘苍松带的所有学生
        Connection connection = DBUtil.getConnection();
        Statement statement = connection.createStatement();
        String sql = "SELECT s.name, s.gender, s.age, c.name, t.name " +
                "FROM student s " +
                "         JOIN class c on c.id = s.class_id " +
                "         JOIN teacher t on t.id = c.teacher_id " +
                "WHERE t.name = '刘苍松'";
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()) {
            String sName = resultSet.getString("s.name");
            String sGender = resultSet.getString("s.gender");
            int sAge = resultSet.getInt("s.age");
            String cName = resultSet.getString("c.name");
            String tName = resultSet.getString("t.name");
            System.out.println(sName +"\t"+ sGender +"\t"+ sAge +"\t"+ sName +"\t"+ cName +"\t"+ tName);
        }
    }
}

/**
 * @document: 使用别名作为查询结果列名
 * 查询刘苍松所带班级的人数
 * @Author:SmallG
 * @CreateTime:2023/8/24+15:12
 */

public class JDBCTest5 {
    public static void main(String[] args) {
        try (
                Connection connection = DBUtil.getConnection();
        ) {
            Statement statement = connection.createStatement();
            String sql = "SELECT COUNT(*) `count`\n" +
                    "FROM student s\n" +
                    "         JOIN class c on c.id = s.class_id\n" +
                    "         JOIN teacher t on t.id = c.teacher_id\n" +
                    "WHERE t.name = '刘苍松'";
            ResultSet resultSet = statement.executeQuery(sql);
            //当结果集中只有一行数据 可以使用if语句让结果集中的游标移动
            if (resultSet.next()) {
                System.out.println("刘苍松所带班级人数:" + resultSet.getInt("count"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

二、SQL注入与预编译SQL

1、SQL注入攻击

攻击者通过在输入框中输入恶意的SQL代码,绕过认证,从而获取系统的权限,进而获取、篡改或破坏数据库中的数据。

2、预编译SQL

在JDBC中可以使用PreparedStatement执行预编译的SQL语句,原理是将需要执行的 SQL 语句先传到数据库服务器端,然后让数据库服务器编译成可执行计划并缓存起来。当下一次需要执行同样的 SQL 语句时,就可以直接使用已经编译好的缓存执行计划,而不必重新编译。这样可以提高数据库的执行效率。

预编译 SQL 还有一个好处是防止 SQL 注入攻击。预编译SQL可以将SQL语句的功能通过执行计划固定下来,后期的SQL参数就无法改变先期的固定的执行计划,即便是SQL成分的参数,也不会被编译执行。所以预编译 SQL可以防止攻击者通过向 SQL 语句中插入恶意代码来破坏数据库。

(1)PreparedStatement 执行预编译的SQL语句

具体的执行流程如下:

1、应用程序通过数据库连接Connection.prepareStatement()向数据库发送 SQL 语句。此时,数据库对 SQL 语句进行预编译,解析分析语法,然后生成 SQL 执行计划。数据库会将 SQL 执行计划存储在缓存中,返回预编译PreparedStatement 对象。

2、应用程序通过 PreparedStatement 对象设置 SQL 语句中的参数,然后调用 PreparedStatement 对象的 execute() 方法执行 SQL 语句。数据库会从缓存中获取对应的 SQL 执行计划并执行,然后返回查询结果给应用程序。

3、在应用程序需要多次执行同样的 SQL 语句时,只需要更改所需要的参数值,然后重复执行 PreparedStatement 对象的 execute() 方法即可。

/**
 * @document: 预编译sql语句执行
 * @Author:SmallG
 * @CreateTime:2023/8/24+16:17
 */

public class JDBCTest7 {
    public static void main(String[] args) {
        System.out.println("欢迎登录");
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入用户名:");
        String username = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine();
        try (
                Connection connection = DBUtil.getConnection();
        ) {
            // ?表示占位符
            String sql = "SELECT id, username, password, nickname, age\n" +
                    "FROM userinfo\n" +
                    "WHERE username = ?\n" +
                    "  AND password = ?";
            //加载预编译SQL语句
            PreparedStatement ps = connection.prepareStatement(sql);
            // 在执行sql语句之前要将占位符替换为真实的数据
            ps.setString(1, username);
            ps.setString(2, password);
            ResultSet rs = ps.executeQuery(); //执行查询语句
            if (rs.next()) {
                System.out.println("登录成功");
            } else {
                System.out.println("登录失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

(2)PreparedStatement

  • void setBoolean(int parameterIndex, boolean x) 设置指定参数的占位符的值为布尔类型
  • void setDouble(int parameterIndex, double x)设置指定参数的占位符的值为double类型
  • void setInt(int parameterIndex, int x) 设置指定参数的占位符的值为整型
  • void setLong(int parameterIndex, long x) 设置指定参数的占位符的值为长整型
  • void setString(int parameterIndex, String x) 设置指定参数的占位符的值为字符串类型
  • ResultSet executeQuery():执行给定的 SQL 查询,并返回 ResultSet 对象
  • int executeUpdate():执行给定的 SQL 语句,该语句可能是 INSERT、UPDATE 或 DELETE 语句
/**
 * @document: 用户信息实体类:对应数据库表userinfo
 * 类中的属性要对应数据库表中的字段
 * @Author:SmallG
 * @CreateTime:2023/8/24+16:34
 */

public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private String nickname;
    private Integer age;

       构造方法....

    toString() 
        
    get....set...
}

/**
 * @document:
 * @Author:SmallG
 * @CreateTime:2023/8/24+16:40
 */

public class JDBCTest8 {
    public static void main(String[] args) {
        // 先创建userinfo对象
        UserInfo userInfo = new UserInfo(null, "王五", "123456", "啊呜", 21);
        //保存数据
        new JDBCTest8().save(userInfo);
    }

    //保存用户信息
    public void save(UserInfo userInfo) {
        try (
                Connection connection = DBUtil.getConnection();
        ) {
            String sql = "INSERT INTO userinfo (username, password, nickname, age)\n" +
                    "VALUES (?, ?, ?, ?)";
            PreparedStatement ps = connection.prepareStatement(sql);
            //替换占位符
            ps.setString(1, userInfo.getUsername());
            ps.setString(2, userInfo.getPassword());
            ps.setString(3, userInfo.getNickname());
            ps.setInt(4, userInfo.getAge());

            int i = ps.executeUpdate();
            if (i > 0) {
                System.out.println("保存数据成功");
            } else {
                System.out.println("保存数据失败");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

三、数据库连接池

数据库连接池是维护着数据库连接的一个缓冲池,它允许多个线程从中获取连接对象并使用,使用完毕后再将连接对象返回池中以备下一次使用。

数据库连接池

DataSource

DataSource

  • Apache Commons DBCP:这是一个开源的JDBC连接池实现,属于Apache项目库的一部分。它提供了许多特性,如连接池大小的配置、连接验证、超时限制等。
  • c3p0:c3p0是一个可以作为JDBC连接池使用的开源库。它提供了许多查看、调整和控制连接池行为的功能,并支持JNDI和JDBC3规范。(据说开发者是一个星球大战影迷)
  • HikariCP:HikariCP是一个非常快速和轻量级的JDBC连接池。它在性能上比其他的连接池更加优秀,特别是在高负载条件下。它还提供了可配置的线程池和实时监控等功能。也是Spring Boot框架内嵌的数据库连接池。
  • Druid:Druid是阿里巴巴开发的一个开源的高性能数据库连接池。它具有功能齐全、监控性强、可扩展性好等特点。企业中被广泛采用的数据库连接池。

Druid连接池

依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.21</version>
</dependency>
/**
 * @document: 数据库连接
 * @Author:SmallG
 * @CreateTime:2023/8/24+14:03
 */

public class DBUtil {
    private static DruidDataSource pool;

    private DBUtil() {

    }

    //初始化数据库连接池
    static {
        pool = new DruidDataSource();
        pool.setUrl("jdbc:mysql://localhost:3306/hedu?useSSL=false&" +
                "serverTimeZone=Asia/Shanghai&characterEncoding=utf-8");
        pool.setUsername("root");
        pool.setPassword("root");
        pool.setInitialSize(5);
        pool.setMaxActive(20);
        pool.setMinIdle(5);    //空闲时期的最小连接数
        pool.setMaxWait(5000); //单位毫秒
    }

    // 返回数据库连接
    public static Connection getConnection() throws SQLException {
        return pool.getConnection();
    }
}
    /**
     * 查询数据
     */
    public UserInfo getById(Integer id) {
        UserInfo userInfo = null;
        try (
                Connection connection = DBUtil.getConnection();
        ) {
            String sql = "SELECT id, username, password, nickname, age\n" +
                    "FROM userinfo\n" +
                    "WHERE id = ?";
            //加载sql语句
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                //创建用户对象
                userInfo = new UserInfo();
                //为对象赋值
                userInfo.setId(rs.getInt("id"));
                userInfo.setUsername(rs.getString("username"));
                userInfo.setPassword(rs.getString("password"));
                userInfo.setNickname(rs.getString("nickname"));
                userInfo.setAge(rs.getInt("age"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return userInfo;
    }

四、练习

1 使用JDBC执行DML语句

完成如下操作:

1、编写JDBC代码实现给学生信息表插入一条学生记录,包括学生名、年龄、性别、职位、生日、城市编号、班级编号。

2、编写JDBC代码实现删除学生信息表中某个特定班级编号的所有学生记录

3、编写JDBC代码实现更新班级信息表中某个班级的老师编号字段

要求:

  • 使用DBUitl管理数据库连接池,通过DBUtil获得数据库链接
  • 使用PreparedStatement执行有参数的预编译SQL语句,更新参数使用Scanner输入

工具类:

/**
 * @document: 数据库连接
 * @Author:SmallG
 * @CreateTime:2023/8/24+18:33
 */

public class DBUtil {
    private static DruidDataSource pool;

    /**
     * 初始化数据库连接池
     */
    static {
        pool = new DruidDataSource();
        pool.setUrl("jdbc:mysql://localhost:3306/hedu?useSSL=false&" +
                "serverTimeZone=Asia/Shanghai&characterEncoding=utf-8");
        pool.setUsername("root");
        pool.setPassword("root");
        pool.setInitialSize(5); //核心连接池数
        pool.setMaxActive(20);
        pool.setMaxWait(5000);
        pool.setMinIdle(5);
    }

    public static Connection getConnection() throws SQLException {
        return pool.getConnection();
    }
}

实体类:

/**
 * @document: 班级实体类
 * @Author:SmallG
 * @CreateTime:2023/8/24+19:26
 */

public class Class {
    private Integer id;
    private String name;
    private Integer floor;
    private Integer teacher_id;

    public Class() {
    }

    public Class(Integer id, String name, Integer floor, Integer teacher_id) {
        this.id = id;
        this.name = name;
        this.floor = floor;
        this.teacher_id = teacher_id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getFloor() {
        return floor;
    }

    public void setFloor(Integer floor) {
        this.floor = floor;
    }

    public Integer getTeacher_id() {
        return teacher_id;
    }

    public void setTeacher_id(Integer teacher_id) {
        this.teacher_id = teacher_id;
    }

    @Override
    public String toString() {
        return "Class{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", floor=" + floor +
                ", teacher_id=" + teacher_id +
                '}';
    }
}

/**
 * @document: 学生实体类
 * @Author:SmallG
 * @CreateTime:2023/8/24+18:51
 */

public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String gender;
    private String job;
    private String birth;
    private Integer location_id;
    private Integer team_leader;
    private Integer class_id;

    public Student() {
    }

    public Student(Integer id, String name, Integer age, String gender, String job, String birth, Integer location_id, Integer team_leader, Integer class_id) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.job = job;
        this.birth = birth;
        this.location_id = location_id;
        this.team_leader = team_leader;
        this.class_id = class_id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public String getBirth() {
        return birth;
    }

    public void setBirth(String birth) {
        this.birth = birth;
    }

    public Integer getLocation_id() {
        return location_id;
    }

    public void setLocation_id(Integer location_id) {
        this.location_id = location_id;
    }

    public Integer getTeam_leader() {
        return team_leader;
    }

    public void setTeam_leader(Integer team_leader) {
        this.team_leader = team_leader;
    }

    public Integer getClass_id() {
        return class_id;
    }

    public void setClass_id(Integer class_id) {
        this.class_id = class_id;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", job='" + job + '\'' +
                ", birth='" + birth + '\'' +
                ", location_id=" + location_id +
                ", team_leader=" + team_leader +
                ", class_id=" + class_id +
                '}';
    }
}

核心代码:

/**
 * @document: 使用JDBC执行DML语句
 * @Author:SmallG
 * @CreateTime:2023/8/24+18:30
 */

public class HomeWork01 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Student student = new Student();

        System.out.println("-----------信息操作系统-----------");
        System.out.println("           1 添加学生信息");
        System.out.println("           2 删除整班学生");
        System.out.println("           3 更新班级教师");

        System.out.println("请选择:");
        int n = scanner.nextInt();
        switch (n) {
            case 1:
                System.out.println("请输入学生姓名:");
                String name = scanner.next();
                student.setName(name);

                System.out.println("请输入学生年龄:");
                Integer s_age = scanner.nextInt();
                student.setAge(s_age);

                System.out.println("请输入学生性别:");
                String s_gender = scanner.next();
                student.setGender(s_gender);

                System.out.println("请输入学生职位:");
                String s_job = scanner.next();
                student.setJob(s_job);

                System.out.println("请输入学生生日:");
                String s_birth = scanner.next();
                student.setBirth(s_birth);

                System.out.println("请输入学生城市编号:");
                Integer s_location_id = scanner.nextInt();
                student.setLocation_id(s_location_id);

                System.out.println("请输入学生班级编号:");
                Integer s_class_id = scanner.nextInt();
                student.setClass_id(s_class_id);

                save(student);
                break;

            case 2:
                System.out.println("请输入要删除的班级编号:");
                Integer s_class_ids = scanner.nextInt();
                delete(s_class_ids);
                break;

            case 3:
                System.out.println("请输入班级id:");
                Integer class_id = scanner.nextInt();
                System.out.println("请输入要更新的教师id:");
                Integer teacher_id = scanner.nextInt();
                update(class_id, teacher_id);
                break;

            default:
                break;

        }
    }

    /**
     * 编写JDBC代码实现给学生信息表插入一条学生记录
     * 包括学生名、年龄、性别、职位、生日、城市编号、班级编号
     */
    public static void save(Student student) {
        try (
                Connection connection = DBUtil.getConnection()
        ) {
            String sql = "INSERT INTO student (name, age, gender, job, birth, location_id, class_id)\n" +
                    "VALUES (?, ?, ?, ?, ?, ?, ?)";
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setString(1, student.getName());
            ps.setInt(2, student.getAge());
            ps.setString(3, student.getGender());
            ps.setString(4, student.getJob());
            ps.setString(5, student.getBirth());
            ps.setInt(6, student.getLocation_id());
            ps.setInt(7, student.getClass_id());

            int i = ps.executeUpdate();
            if (i > 0) {
                System.out.println("添加成功");
            } else {
                System.out.println("添加失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 编写JDBC代码实现删除学生信息表中某个特定班级编号的所有学生记录
     */
    public static void delete(Integer s_class_id) {
        try (
                Connection connection = DBUtil.getConnection();
        ) {
            String sql = "DELETE FROM student WHERE class_id = ?";
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setInt(1, s_class_id);
            int i = ps.executeUpdate();
            if (i > 0) {
                System.out.println("删除成功");
            } else {
                System.out.println("删除失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 编写JDBC代码实现更新班级信息表中某个班级的老师编号字段
     */
    public static void update(Integer class_id, Integer t_id) {
        try (
                Connection connection = DBUtil.getConnection();
        ) {
            String sql = "UPDATE class\n" +
                    "SET teacher_id = ?\n" +
                    "WHERE id = ?";
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setInt(1, t_id);
            ps.setInt(2, class_id);
            int i = ps.executeUpdate();
            if (i > 0) {
                System.out.println("更新成功");
            } else {
                System.out.println("更新失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

2 使用JDBC执行DQL语句

完成如下操作:

1、编写JDBC代码实现查询学生信息表中某个特定城市的所有学生信息(包括城市名、学生名、年龄、性别、职位、生日、班级名)。

2、编写JDBC代码实现查询老师信息表中某个特定上司的所有下属老师的名字、年龄、职称、工资、科目名。

3、编写JDBC代码实现查询学生信息表中某个特定组长负责的所有学生姓名、学生职位、科目名、成绩情况。

要求:

  • 使用DBUitl管理数据库连接池,通过DBUtil获得数据库链接
  • 使用PreparedStatement执行有参数的预编译SQL语句,特定参数使用Scanner输入
/**
 * @document:
 * @Author:SmallG
 * @CreateTime:2023/8/24+19:36
 */

public class HomeWork02 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Student student = new Student();

        System.out.println("-----------信息操作系统-----------");
        System.out.println("           1 查询某个城市的所有学生");
        System.out.println("           2 查询某个上司的下属");
        System.out.println("           3 更新班级教师");


        System.out.println("请选择:");
        int n = scanner.nextInt();
        switch (n) {
            case 1:
                System.out.println("请输入城市名:");
                String location = scanner.next();
                city(location);
                break;
            case 2:
                System.out.println("请输入上司的姓名:");
                String name = scanner.next();
                teacher(name);
                break;
            case 3:
                System.out.println("请输入组长编号:");
                Integer team_id = scanner.nextInt();
                team_id(team_id);
                break;
            default:
                break;

        }
    }

    /**
     * 1、编写JDBC代码实现查询学生信息表中某个特定城市的所有学生信息
     * (包括城市名、学生名、年龄、性别、职位、生日、班级名)。
     */
    public static void city(String city) {
        try (
                Connection connection = DBUtil.getConnection();
        ) {
            String sql = "SELECT l.name, s.name, s.age, s.gender, s.job, s.birth,c.name\n" +
                    "FROM student s\n" +
                    "         JOIN class c on c.id = s.class_id\n" +
                    "         JOIN location l on l.id = s.location_id\n" +
                    "WHERE l.name =?";
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setString(1, city);
            ResultSet resultSet = ps.executeQuery();
            System.out.println("城市名" + "\t" + "学生名" + "\t" + "年龄" + "性别" + "\t" + "职位" + "\t\t" + "生日" + "\t\t" + "班级名");
            while (resultSet.next()) {
                System.out.println(resultSet.getString("l.name") + "\t" +
                        resultSet.getString("s.name") + "\t" +
                        resultSet.getInt("s.age") + "\t" +
                        resultSet.getString("s.gender") + "\t" +
                        resultSet.getString("s.job") + "\t\t" +
                        resultSet.getString("s.birth") + "\t" +
                        resultSet.getString("c.name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    /**
     * 2、编写JDBC代码实现查询老师信息表中某个特定上司的
     * 所有下属老师的名字、年龄、职称、工资、科目名。
     */
    public static void teacher(String name) {
        try (
                Connection connection = DBUtil.getConnection();
        ) {
            String sql = "SELECT t.name, t.age, t.title, t.salary,s.name\n" +
                    "FROM teacher t\n" +
                    "         JOIN teacher m ON t.manager = m.id\n" +
                    "         JOIN subject s on s.id = t.subject_id\n" +
                    "WHERE m.name = ?";
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setString(1, name);
            ResultSet resultSet = ps.executeQuery();
            System.out.println(name + "的下属有:");
            while (resultSet.next()) {
                System.out.println(
                        resultSet.getString("t.name") + "\t" +
                                resultSet.getInt("t.age") + "\t" +
                                resultSet.getString("t.title") + "\t\t" +
                                resultSet.getDouble("t.salary") + "\t" +
                                resultSet.getString("s.name")
                );
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 3、编写JDBC代码实现查询学生信息表中某个特定组长
     * 负责的所有学生姓名、学生职位、科目名、成绩情况。
     */
    public static void team_id(Integer team_id) {
        try (
                Connection connection = DBUtil.getConnection()
        ) {
            String sql = "SELECT s.name, s.job, s2.name,tsss.score\n" +
                    "FROM student s\n" +
                    "         JOIN student t on s.team_leader = t.id\n" +
                    "         JOIN t_stu_subject_score tsss on tsss.stu_id = s.id\n" +
                    "         JOIN subject s2 on s2.id = tsss.subject_id\n" +
                    "WHERE t.id = ?\n" +
                    "GROUP BY s.name,s2.name";
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setInt(1, team_id);
            ResultSet resultSet = ps.executeQuery();
            while (resultSet.next()) {
                System.out.println(
                        resultSet.getString("s.name") + "\t" +
                                resultSet.getString("s.job") + "\t" +
                                resultSet.getString("s2.name") + "\t" +
                                resultSet.getDouble("tsss.score") + "\t"
                );
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
最后修改:2023 年 08 月 24 日
如果觉得我的文章对你有用,请随意赞赏