软件设计之JDBC(2)
此篇应在MySQL之后进行学习:
路线图推荐:
【Java学习路线-极速版】【Java架构师技术图谱】
尚硅谷2024最新JDBC教程 | jdbc基础到高级一套通关!
资料可以去尚硅谷官网免费领取
学习内容:
- 实体类和ORM
- 主键回显
- 批量操作
- 连接池概述
- Druid编码实现
1、 实体类和ORM
实体类搭建
1、表中的每一列对应类中的对象属性
2、命名时,要根据Java的命名规范修改 比如:empAge
3、将构造器和get、set函数、toString创建好
4、小技巧:在设置中,树外观里可以展开或者压缩软件包的排列
具体意思是:
atguigu.advanced 会分别以atguigu和advanced 两个文件夹显示,而不是单独的atguigu.advanced这是不压缩空的中间软件包
Employee类搭建
package com.atguigu.advanced.pojo;
//类名就是数据库表的t_后面的单次全写
public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
private Integer empAge;
public Employee(Integer empId, String empName, Double empSalary, Integer empAge) {
this.empId = empId;
this.empName = empName;
this.empSalary = empSalary;
this.empAge = empAge;
}
public Employee() {
}
@Override
public String toString() {
return "Employee{" +
"empId=" + empId +
", empName='" + empName + '\'' +
", empSalary=" + empSalary +
", empAge=" + empAge +
'}';
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Double getEmpSalary() {
return empSalary;
}
public void setEmpSalary(Double empSalary) {
this.empSalary = empSalary;
}
public Integer getEmpAge() {
return empAge;
}
public void setEmpAge(Integer empAge) {
this.empAge = empAge;
}
}
ORM初探
将单行查询后的数据封装成对象
@Test
public void testORM() throws SQLException {
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu", "root", "root");
PreparedStatement preparedStatement = connection.prepareStatement("SELECT emp_id,emp_name,emp_salary,emp_age FROM t_emp WHERE emp_id = ?");
preparedStatement.setInt(1,1);
ResultSet resultSet = preparedStatement.executeQuery();
Employee employee = null;
if(resultSet.next()){
employee = new Employee();
int empId = resultSet.getInt("emp_id");
String empName = resultSet.getString("emp_name");
double empSalary = resultSet.getDouble("emp_salary");
int empAge = resultSet.getInt("emp_age");
employee.setEmpId(empId);
employee.setEmpName(empName);
employee.setEmpSalary(empSalary);
employee.setEmpAge(empAge);
}
System.out.println(employee);
resultSet.close();
preparedStatement.close();
connection.close();
}
ORM封装集合
将多行查询后的数据封装成对象集合
@Test
public void testORMList() throws SQLException {
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu", "root", "root");
PreparedStatement preparedStatement = connection.prepareStatement("SELECT emp_id,emp_name,emp_salary,emp_age FROM t_emp ");
ResultSet resultSet = preparedStatement.executeQuery();
Employee employee = null;
ArrayList<Employee> employees = new ArrayList<>();
while(resultSet.next()){
employee = new Employee();
int empId = resultSet.getInt("emp_id");
String empName = resultSet.getString("emp_name");
double empSalary = resultSet.getDouble("emp_salary");
int empAge = resultSet.getInt("emp_age");
employee.setEmpId(empId);
employee.setEmpName(empName);
employee.setEmpSalary(empSalary);
employee.setEmpAge(empAge);
employees.add(employee);
}
//遍历集合
for (Employee emp :employees){
System.out.println(emp);
}
resultSet.close();
preparedStatement.close();
connection.close();
}
2、主键回显
@Test
public void testReturnPK() throws SQLException {
//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu", "root", "root");
//预编译SQL语句,告知preparedStatement,返回新增数据的主键列的值
String sql = "INSERT INTO t_emp(emp_name,emp_salary,emp_age) VALUES (?,?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
//创建对象,将对象的属性值,填充在?占位符上(ORM)
Employee employee = new Employee(null, "Jack", 134.56, 29);
preparedStatement.setString(1,employee.getEmpName());
preparedStatement.setDouble(2,employee.getEmpSalary());
preparedStatement.setInt(3,employee.getEmpAge());
int result = preparedStatement.executeUpdate();
ArrayList<Employee> employees = new ArrayList<>();
ResultSet resultSet = null;
if (result > 0){
System.out.println("成功");
//获取当前新增数据的主键列,回显到Java中employee对象的empId属性上
//返回的主键值,是一个单行单列的结果存储在ResultSet里
resultSet = preparedStatement.getGeneratedKeys();
if (resultSet.next()){
int anInt = resultSet.getInt(1);
System.out.println(anInt);
}
System.out.println(employee);
}else {
System.out.println("失败");
}
if (resultSet !=null){
resultSet.close();
}
preparedStatement.close();
connection.close();
}
3、批量操作
@Test
public void testBatch() throws SQLException {
//获取连接
//允许批量操作rewriteBatchedStatements=true
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu?rewriteBatchedStatements=true", "root", "root");
//预编译SQL语句
//此处INSERT INTO t_emp(emp_name,emp_salary,emp_age) VALUES (?,?,?)结尾不能加分号,必须是VALUES而不是VALUE
String sql = "INSERT INTO t_emp(emp_name,emp_salary,emp_age) VALUES (?,?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//创建对象,将对象的属性值,填充在?占位符上(ORM)
long start = System.currentTimeMillis();
for(int i = 0;i<10000;i++){
preparedStatement.setString(1,"marry"+i);
preparedStatement.setDouble(2,100.0 + i);
preparedStatement.setInt(3,20+i);
preparedStatement.addBatch();
}
//执行批量操作
preparedStatement.executeBatch();
long end = System.currentTimeMillis();
System.out.println("消耗时间:" + (end -start));
preparedStatement.close();
connection.close();
}
4、连接池概述
现有问题:
1、每次操作数据库都要获取新连接,使用完毕后就close释放,频繁的创建和销毁造成资源浪费。
2、连接的数量无法把控,对服务器来说压力巨大
常见连接池
5、Druid编码实现
Druid硬编码实现
public class DruidTest {
@Test
public void testHardCodeDruid() throws SQLException {
/**
* 硬编码:将连接池的配置信息和Java代码耦合在一起
* 1、创建DruidDataSource连接池对象
* 2、设置连接池的信息[必须 | 非必须]
* 3、通过连接池获取连接对象
* 4、回收连接[不是释放连接,而是将连接归还给连接池,给其他线程进行复用]
*/
//1 创建DruidDataSource连接池对象
DruidDataSource druidDataSource = new DruidDataSource();
//2 设置连接池的信息[必须]
druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://localhost:3306/atguigu");
druidDataSource.setUsername("root");
druidDataSource.setPassword("root");
//2 设置连接池的信息[非必须]
//默认数量连接
druidDataSource.setInitialSize(10);
//最大数量连接
druidDataSource.setMaxActive(20);
//3 通过连接池获取连接对象
DruidPooledConnection connection = druidDataSource.getConnection();
//基于connection进行CRUD
//4 回收连接
connection.close();
System.out.println(connection);
}
Druid软编码实现
在项目目录下创建resources文件夹,标识该文件夹为
资源目录
,创建db.properties配置文件,将连接信息定义在该文件中
标记为资源根目录
创建资源包db
//配置文件代码内容
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/atguigu
username=root
password=root
initialSize=10
maxActive=20
软编码代码
@Test
public void testResourceCodeDruid() throws Exception {
//1 创建Properties集合,用于存储外部配置文件的key和value值
Properties properties = new Properties();
//2 读取外部配置文件,获取输入流,加载到Properties集合里
InputStream inputStream = DruidTest.class.getClassLoader().getResourceAsStream("db.properties");
properties.load(inputStream);
//3 基于Properties集合构建DruidDataSource连接池
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//4 通过连接池获取连接对象
Connection connection = dataSource.getConnection();
System.out.println(connection);
//5 开发CRUD
//6 回收连接
connection.close();
}