Java JDBC入门之八 : DAO设计模式重构查询方法 AND 使用BeanUtils工具类操作JavaBean
程序员文章站
2023-12-22 20:05:52
...
Java JDBC入门之七 : DAO设计模式重构查询方法 AND 使用BeanUtils工具类操作JavaBean
1. DAO 设计思想 Data Access Object
为什么要存在这样的思想?
- 实现功能的模块化. 更有利于代码的维护和升级.
- DAO 可以被子类继承或直接使用
DAO是什么?
- 访问数据信息的类。包含了数据的CRUD (create,read.,update,delete).
- 不包含任何业务相关的信息的类.
使用JDBC 编写 DAO 可能会包含的方法?
//INSERT, UPDATE,DELETE 操作都可以包含在其中
void update(String sql, Object ... args )
//查询一条记录,返回对应的对象
<T> T get(Class<T> clazz, String sql, Object...args);
//查询多条记录,返回对应的对象的集合
<T> List<T> getForList(Class<T> clazz , String sql, Object...args )
//返回某条记录的某一个字段的值 或一个统计的值(一共有多少条记录等。)
<E> E getForValue(String sql,Object ... args);
2. Java 类的属性:
- 在JavaEE 中,Java 类的属性通过 getter,setter来定义 , 也就是说get(或 set)方法,去除get(或set)后,后字母小写即为Java 类的属性。 因为我们有单独操作getter和setter的技术。
- 而以前叫的那个属性,即成员变量,称之为字段。
- 一般情况下,字段名和属性名都一致。
- 操作Java 类的属性有一个工具包: beanUtils
- BeanUtils主要是用于将对象的属性封装到对象中
- 搭建环境:需要同时加入: commons-beanutils-1.x.x.jar 和 commons-logging-1.x.x.jar
- ①.setProperty(bean, name, value) : 其中bean是指你将要设置的对象,name指的是将要设置的属性(写成”属性名”),value(属性的值)
- BeanUtils设置属性的时候也是依赖于底层的getter和setter方法
- BeanUtils设置属性值,如果属性是基本数据类型,BeanUtils会自动帮我们进行数据类型的转换
- 注意:如果设置的属性值是其他的引用数据类型,此时必须要注册一个类型转换器才能实现自动的转换
- ②.getProperty(bean,name) :获取Bean对象属性名为name的值
3.Demo
- DAO.java类运行前,需要JDBCTools.java,而这个类可在之前博客找到。
- 测试代码
public class DAOTest {
DAO dao = new DAO();
@Test
public void testUpdate() {
String sql = "INSERT INTO customers(name, "
+ " email,birth) VALUES(?,?,?);";
dao.update(sql, "xiaoming","[email protected]",new Date(new java.util.Date().getTime()));
}
@Test
public void testGet() {
String sql = "SELECT flow_id flowId, type,exam_card examCard, "
+ "id_card idCard,student_name studentName, location, "
+ "grade FROM examstudent WHERE flow_id = ?";
Student student = dao.get(Student.class, sql, 5);
System.out.println(student);
}
@Test
public void testGetForList() {
String sql = "SELECT flow_id flowId, type,exam_card examCard, "
+ "id_card idCard,student_name studentName, location, "
+ "grade FROM examstudent";
List<Student> students = dao.getForList(Student.class, sql);
System.out.println(students);
}
@Test
public void testGetForValue() {
String sql = "SELECT exam_card FROM examstudent "
+ "WHERE flow_id = ?";
String str = dao.getForValue(sql,1);
System.out.println(str);
}
}
import org.apache.commons.beanutils.BeanUtils;
public class DAO {
//INSERT, UPDATE,DELETE 操作都可以包含在其中
public void update(String sql, Object ... args ){
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JDBCTools.getConnection();
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i+1, args[i]);
}
preparedStatement.executeUpdate();
}catch (Exception e) {
e.printStackTrace();
}finally {
JDBCTools.releaseDB(null, preparedStatement, connection);
}
}
//查询一条记录,返回对应的对象
public <T> T get(Class<T> clazz, String sql, Object...args) {
List<T> result = getForList(clazz, sql, args);
if( 0 < result.size()) {
return result.get(0);
}
return null;
}
//查询多条记录,返回对应的对象的集合
public <T> List<T> getForList(Class<T> clazz , String sql, Object...args ){
List<T> list = new ArrayList<>();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//1. 得到结果集
connection = JDBCTools.getConnection();
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i+1, args[i]);
}
resultSet = preparedStatement.executeQuery();
// 2. 处理结果集,得到Map 的List,其中一个Map对象
//就是一条记录,Map 的 key 为 resultSet 中的别名, Map 的 value 为列的值
List<Map<String, Object>> values = handleResultSetToMapList(resultSet);
// 3.把 Map 的 List 转化为 clazz 对应的 List
// 其中Map 的 key 即为 clazz 对应的对象的propertyName
// 而 Map 的 value 即为 clazz 对应的对象的 propertyValue
list = transferMapListToBeanList(clazz, values);
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCTools.releaseDB(resultSet, preparedStatement, connection);
}
return list;
}
/**
*转换MapList为BeanList
* @param clazz
* @param values
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private <T> List<T> transferMapListToBeanList(Class<T> clazz, List<Map<String, Object>> values)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
//12. 判断List 是否为空集合, 若不为空,则遍历List,得到一个一个的Map的对象,
// 在把一个Map对象转为一个Class参数对应的Object对象
List<T> result = new ArrayList<>();
T bean = null;
if (0 < values.size()) {
for(Map<String,Object> m : values) {
bean = clazz.newInstance();
for (Map.Entry<String, Object> entry: m.entrySet()) {
String propertyName = entry.getKey();
Object propertyValue = entry.getValue();
//BeanUtils.工具类的使用,为封装的对象的属性赋值
BeanUtils.setProperty(bean, propertyName, propertyValue);
}
//13. 把Object 对象放入到List<T> list 中。
result.add(bean);
}
}
return result;
}
/**
* 处理结果集,得到Map的一个List,其中一个Map对应一条记录。
* @param resultSet
* @return
* @throws Exception
* @throws SQLException
*/
private List<Map<String, Object>> handleResultSetToMapList(ResultSet resultSet) throws Exception, SQLException {
//5. 若ResultSet 中有记录 ,准备 一个List<Map<String,Object>>:
//建:存放列的别名 , 值: 存放列的值.其实一个Map 对象对应一条记录
List<Map<String, Object>> values = new ArrayList<Map<String,Object>>();
List<String> columnLabels = getColumnLabels(resultSet);
Map<String,Object> map = null;
//7. 处理ResultSet,使用while循环
while(resultSet.next()) {
map = new HashMap<>();
for(String columnLabel : columnLabels ) {
Object value = resultSet.getObject(columnLabel);
map.put(columnLabel, value);
}
//11. 把一条记录的一个Map对象 放入 5 准备的List中
values.add(map);
}
return values;
}
/**
* 获取结果集的ColumnLabel 对应的List
* @param rs
* @return
* @throws Exception
*/
private List<String> getColumnLabels(ResultSet rs) throws Exception{
List<String> labels = new ArrayList<>();
ResultSetMetaData rsmd = rs.getMetaData();
for(int i = 0; i < rsmd.getColumnCount(); i ++) {
labels.add(rsmd.getColumnLabel( i + 1 ));
}
return labels;
}
//返回某条记录的某一个字段的值 或一个统计的值(一共有多少条记录等。)
public <E> E getForValue(String sql,Object ... args) {
//1. 得到结果集 : 该结果集应该只有一行,且只有一列
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//1. 得到结果集
connection = JDBCTools.getConnection();
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i+1, args[i]);
}
resultSet = preparedStatement.executeQuery();
//2. 取得结果
if (resultSet.next()) {
return (E) resultSet.getObject(1);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCTools.releaseDB(resultSet, preparedStatement, connection);
}
return null;
}
}