JDBC高级和DbUtils
1. BaseDao方法补充
1.1 为什么要提供该方法
完成一个查询返回值类型是Object[],并且是存储于List集合中的一种方式,实际返回值类型是 List<Object[]>
处理的是查询数据结果无法映射到类对象中,ORM,所有的数据按照查询结果字段顺序要求从数据库读取数据保存到Object数组,为了能满足多行数据查询要求,Object数组存储到List中
1.2 方法分析
分析:
权限修饰符:
public
返回值类型:
List<Object[]>
方法名:
query
形式参数列表:
String sql select查询语句
对应当前SQL语句的参数
方法声明:
public List<Object[]> query(String sql, Object[] parameters)
/**
* 通用查询方法,返回值是对应字段数据的Object类型数组,并且存储于List集合
*
* @param sql Select查询SQL语句
* @param parameters 对应当前SQL语句的参数
* @return 包含数据行数据的List<Object[]> 如果没有查询到数据,返回null
*/
public List<Object[]> query(String sql, Object[] parameters) {
ResultSet resultSet = null;
Connection connection = null;
PreparedStatement preparedStatement = null;
List<Object[]> list = new ArrayList<>();
try {
connection = JdbcUtil.getConnection();
preparedStatement = connection.prepareStatement(sql);
/*
获取SQL语句参数个数!!!通过SQL语句元数据获取(ParameterMetaData)
*/
int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
/*
parameterCount 参数个数不能为0
parameters != null 参数数组不为null,因为存在当前方法没有参数,数组传入null
parameterCount == parameters.length 参数个数和传入的Object类型参数数容量一致
*/
if (parameterCount != 0 && parameters != null && parameterCount == parameters.length)
for (int i = 0; i < parameters.length; i++) {
/*
SQL语句参数下标从1开始
数组数据下标从0开始
*/
preparedStatement.setObject(i + 1, parameters[i]);
}
}
resultSet = preparedStatement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
while (resultSet.next()) {
Object[] values = new Object[columnCount];
for (int i = 1; i <= columnCount; i++) {
values[i - 1] = resultSet.getObject(i);
}
list.add(values);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(connection, preparedStatement, resultSet);
}
return list.size() != 0 ? list : null;
}
1.3 BaseDao优化
// Ctrl + Alt + M 光标选择代码块生成一个方法
/**
* 类内私有化处理PreparedStatement预处理SQL语句和参数数组赋值操作
*
* @param preparedStatement 预处理SQL语句对应的PreparedStatement对象
* @param parameters 对应当前SQL语句的Object类型数组
* @throws SQLException SQL异常
*/
private void parseSqlParameter(PreparedStatement preparedStatement, Object[] parameters) throws SQLException {
/*
获取SQL语句参数个数!!!通过SQL语句元数据获取(ParameterMetaData)
*/
int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
/*
parameterCount 参数个数不能为0
parameters != null 参数数组不为null,因为存在当前方法没有参数,数组传入null
parameterCount == parameters.length 参数个数和传入的Object类型参数数容量一致
*/
if (parameterCount != 0 && parameters != null && parameterCount == parameters.length) {
for (int i = 0; i < parameters.length; i++) {
/*
SQL语句参数下标从1开始
数组数据下标从0开始
*/
preparedStatement.setObject(i + 1, parameters[i]);
}
}
}
2. 项目使用JdbcUitl,BaseDao完成数据持久化操作
2.1 需求
使用数据库作为数据持久化操作是一个非常非常常见。剥离原本的数据保存方式,之前数据保存使用的是Json个数文件,并且使用到Dao层
项目Dao层需要继承BaseDao完成对于数据的操作CRUD。并且数据库和当前项目中的实体类是对应关系:
数据表 ==> 实体类名一致
字段名 ==> 成员变量名
数据类型 ==> 成员变量数据类型
完成一个简版Student管理系统
dao
interface StudentDao
impl(package)
StudentDaoImpl
service
interface StudentService
impl(package)
StudentServiceImpl
view
interface ProjectView
impl(package)
ProjectViewImpl
mainproject
main方法
2.2 数据库设计
字段 | 数据类型 |
---|---|
id | int PRI AI |
name | varchar(50) NN |
age | int NN |
gender | boolean NN |
score | float(5, 2) NN |
address | text NN |
2.3 Student实体类
2.4 StudentDao规范
2.5 StudentDaoImpl实现
2.6 StudentService规范
2.7 StudentServiceImpl实现
2.8 StudentView规范
2.9 StudentViewImpl实现
2.10 StudentController实现
2.11 StudentProject main方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NhWR4P7z-1585149121583)(img/项目结构图例.png)]
3. 轻量级数据库ORM框架DbUtils
3.1 DbUtils介绍
Apache组织下的一个轻量级ORM框架
Commons DbUtils: JDBC Utility Component
两个核心方法
update方法 ==> insert,update,delete
query方法 ==> select
一个核心类
QueryRunner DbUtils的核心类
3.2 DbUtils ORM工具使用
package com.qfedu.c_dbutils;
import com.qfedu.b_studentsys.entity.Student;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;
import util.JdbcUtil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* DbUtils ORM框架演示
*
* @author Anonymous 2020/3/25 16:03
*/
public class DbUtilsTest {
@Test
public void testInsert() throws SQLException {
// 1. DbUtils核心类 QueryRunner对象
QueryRunner runner = new QueryRunner();
// 2. 插入数据到Student数据表中
String sql = "insert into student(name, age, gender, score, address) value(?, ?, ?, ?, ?)";
Object[] parameters = {"老黑", 70, true, 59, "河南郑州"};
// 3. 获取数据库连接
Connection connection = JdbcUtil.getConnection();
// 4. 执行Update方法
runner.update(connection, sql, parameters);
JdbcUtil.close(connection);
}
/**
* 了解操作方式, ResultSetHandler
*/
@Test
public void testQuery1() throws SQLException {
// 1. DbUtils核心类 QueryRunner对象
QueryRunner runner = new QueryRunner();
// 2. SQL语句
String sql = "select * from student where id = 1";
Connection connection = JdbcUtil.getConnection();
/*
ResultSetHandler 核心接口
ResultSet结果集 Handler处理,
核心方法 handler(ResultSet rs)
*/
Student student = runner.query(connection, sql, rs -> {
Student stu = null;
if (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
boolean gender = rs.getBoolean("gender");
float score = rs.getFloat("score");
String address = rs.getString("address");
stu = new Student(id, name, age, gender, score, address);
}
return stu;
});
System.out.println(student);
JdbcUtil.close(connection);
}
/**
* BeanHandler
*/
@Test
public void queryBean() throws SQLException {
// 1. DbUtils核心类 QueryRunner对象
QueryRunner runner = new QueryRunner();
// 2. SQL语句
String sql = "select * from student where id = 1";
Connection connection = JdbcUtil.getConnection();
/*
BeanHandler: 处理符合JavaBean规范的类对象,传入参数是对应JavaBean规范 Class对象
*/
Student student = runner.query(connection, sql, new BeanHandler<>(Student.class));
System.out.println(student);
JdbcUtil.close(connection);
}
/**
* BeanListHandler
*/
@Test
public void queryBeanList() throws SQLException {
// 1. DbUtils核心类 QueryRunner对象
QueryRunner runner = new QueryRunner();
// 2. SQL语句
String sql = "select * from student where id > ?";
Connection connection = JdbcUtil.getConnection();
/*
BeanListHandler: 处理符合JavaBean规范的实体类,并且返回值是一个List集合
包含制定的JavaBean实体类
*/
List<Student> list = runner.query(connection, sql, new BeanListHandler<>(Student.class), 2);
for (Student student : list) {
System.out.println(student);
}
JdbcUtil.close(connection);
}
/**
* ArrayHandler
*/
@Test
public void queryArray() throws SQLException {
// 1. DbUtils核心类 QueryRunner对象
QueryRunner runner = new QueryRunner();
// 2. SQL语句
String sql = "select * from student where id = 1";
Connection connection = JdbcUtil.getConnection();
/*
ArrayHandler: 查询一个数据行,数据行中的所有数据整合成一个Object类型数组返回
*/
Object[] values = runner.query(connection, sql, new ArrayHandler());
System.out.println(Arrays.toString(values));
JdbcUtil.close(connection);
}
/**
* ArrayListHandler
*/
@Test
public void queryArrayList() throws SQLException {
// 1. DbUtils核心类 QueryRunner对象
QueryRunner runner = new QueryRunner();
// 2. SQL语句
String sql = "select * from student where id > ?";
Connection connection = JdbcUtil.getConnection();
/*
ArrayListHandler: 查询结果集中所有数据行,每一行数据对应一个Object类型数组,存储在List集合中
*/
List<Object[]> list = runner.query(connection, sql, new ArrayListHandler(), 2);
for (Object[] values : list) {
System.out.println(Arrays.toString(values));
}
JdbcUtil.close(connection);
}
/**
* MapHandler
*/
@Test
public void queryMap() throws SQLException {
// 1. DbUtils核心类 QueryRunner对象
QueryRunner runner = new QueryRunner();
// 2. SQL语句
String sql = "select * from student where id = 1";
Connection connection = JdbcUtil.getConnection();
/*
MapHandler: 处理一个数据行,数据行中字段是对应Key,字段对应数据是value,组成一个Map双边队列
*/
Map<String, Object> map = runner.query(connection, sql, new MapHandler());
System.out.println(map);
}
/**
* MapListHandler
*/
@Test
public void queryMapList() throws SQLException {
// 1. DbUtils核心类 QueryRunner对象
QueryRunner runner = new QueryRunner();
// 2. SQL语句
String sql = "select * from student where id > ?";
Connection connection = JdbcUtil.getConnection();
/*
MapListHandler: 结果集中所有的数据行,每一行对应一个Map对象,字段名为Key,字段对应的数据为value,所有数据行存储
在List中
*/
List<Map<String, Object>> mapList = runner.query(connection, sql, new MapListHandler(), 2);
for (Map<String, Object> map : mapList) {
System.out.println(map);
}
}
}
3.3 ResultHandler以及其子类
ResultSetHandler 核心接口
ResultSet结果集 Handler处理,
核心方法 handler(ResultSet rs)
BeanHandler:
处理符合JavaBean规范的类对象,传入参数是对应JavaBean规范 Class对象
BeanListHandler:
处理符合JavaBean规范的实体类,并且返回值是一个List集合包含制定的JavaBean实体类
ArrayHandler:
查询一个数据行,数据行中的所有数据整合成一个Object类型数组返回
ArrayListHandler:
查询结果集中所有数据行,每一行数据对应一个Object类型数组,存储在List集合中
MapHandler:
处理一个数据行,数据行中字段是对应Key,字段对应数据是value,组成一个Map双边队列
MapListHandler:
结果集中所有的数据行,每一行对应一个Map对象,字段名为Key,字段对应的数据为value,所有数据行存储在List中