一、JDBC
1、JDBC概述
JDBC提供了以下功能:
- 连接到数据库:JDBC提供了一种标准的、可移植的方式来连接各种关系型数据库,这使得应用程序可以在不同的数据库之间移植和重用。
- 执行SQL语句:JDBC提供了一种标准的方式来执行SQL语句,包括查询、插入、更新和删除操作。
- 处理事务: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
- 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();
}
}
}