OR-Mapping 设计改进(主键查询改进) | 学习笔记

简介: 简介:快速学习 OR-Mapping 设计改进(主键查询改进)

开发者学堂课程【DAO 开发实战业务分析:OR-Mapping 设计改进(主键查询改进】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/399/detail/5181


OR-Mapping 设计改进(主键查询改进)


内容介绍:

一、简述

二、具体内容


一、简述

在整个 JDBC 的开发之中对于数据的取出实际上是有一个严重的性能问题的,理论上不需要的数据不应该取出,如果要想达到这样的目的,就必须针对于整体操作进行一些规划,如果需要设置要查询的列,则这个设置过程应该交由用户处理,也就是说用户要负责生成 SQL 语句。


二、具体内容

1、在 AbstractDAO 类里面追加一个处理的方法。找到 findById,返回的一定是位型,跟上public <T> T findByIdSupport(String sql,String Value,Class<T> cls) throws Exception {},要求能接收 sql 与value,Class 是一定要有的,否则值不能返回。

首先要改的部分在于return super.findByIdSupport(sql,id,Member.class);

再在上方写出注释,而在将查询结果自动转为VO类流程的过程中的关键因素为查询全部的操作也要经过这种转换。

如下:

/**

* 对数据的查询进行控制

* @param sql 要执行的根据ID查询的SQL语句

* @param value 要查询的id数据

* @param cls 要处理的VO类型

* @return 查询到数据则将ResultSet的内容自动转换为VO对象返回

* @throws Exception

*/

public <T,V> T findByIdSupport(String sql,V value,Class<T> cls) throws Exception {

return null 

}

2、在子类里面需要负责好要使用的 SQL 语句。

Iterator<?> iter = ids. iterator() ;

int foot = 1 ;

while (iter.hasNext()) {

buf.append(“?,”) ;

this.valueMap.put(foot ++,iter.next()) ;

}

buf.delete(buf.length() - 1, buf.length()) ;

buf. append(“(“) ;

return buf.toString() ;

}

}

3、在 AbstractDAO 父类里面实际上对于 SQL 不再需要自动生成了,而后只需要考虑设置内容即可,而且主键的类型往往是 String 或者是 Integer(Int)。

FindSupport 中,在追加处理方法的部分中,并不知道主键的类型,但是可以通过 Class 资源文件找到主键的列与属性,再通过属性找到属性的类型。

而在这个地方并不能跟String而是跟泛型,即改为 public <T,V> T findByIdSupport(String sql,V value,Class<T> cls) throws Exception {,而有了 T 和 value 则不需要通过反射去寻找,而能够直接找到位型。

通过 System.out.println(value.getClass().getSimpleName());来进行验证是可以找到位型的。

然后将值给 FIndSupport 来执行,如下:

package cn.mldn.util.dao.support;

import java.sql.PreparedStatement ;

public class FindSupport {

public <V> void setPreparedStatement(PreparedStatement pstmt,V value) {

String type = value.getClass().getSimpleName() ;

if (“String”.equals(type)) {

pstmt.setString(1,value.toString()) ;

}else if (“Int”.equals(type) || “Integer”.equals(type))

pstmt.setInt(2,parseInt(value.toString())) ;

}

}

}

4、但是现在不是一个查询可以解决的问题,整个过程之中需要将 ResultSet 的数据变为 VO 数据保存,所以此处就需要一个 ResultToVO 的工具类。

知道元数据的目的是为了得到列名称,有了列名称就可以找到属性名称。而数据取出要通过对象来进行实例化控制,

如下:

package cn.mldn.util.dao

public class ResultSetToVOUtil {

private ResultSetToVOUtil() {}

/**

* 将ResultSet中的内容进行一个转换处理

* @param pstmt 包含有元数据以及可以执行查询的处理对象

* @param cls 要转换的VO对象

* @return

*/

public static <T> T convertSingle(PreparedStatement pstmt,Class<T> cls) {

ResultSetMetaData rsmd = pstmt.getMetaData ;

ResultSet rs = pstmt.executeQuery() ; // 发出查询命令

T t = cls.newInstance() ;

if(rs.next()) { // 有数据

for (int x = 1; x < rsmd.getColumnCount() ; x ++) {       

Field field = cls.getDeclaredField(rsmd.getColumnLabel(x).toLowerCase());

String type = field.fetType().getSimpleName() ;

if(“String”.equals(type)) {

BeanValueUtils.setValue(t,rsmd.getColumnLabel(x).toLowerCase(),rs.getString(rsmd.getColumnLabel(x)));

}else if(“int“.equals(type) || “integer“.equals(type)) {

BeanValueUtils.setValue(t,rsmd.getColumnLabel(x).toLowerCase(),rs.getInt(rsmd.getColumnLabel(x)));

}else if(“double“.equals(type) || Double “.equals(type)) {

BeanValueUtils.setValue(t,rsmd.getColumnLabel(x).toLowerCase(),rs.getDouble(rsmd.getColumnLabel(x)));

}else if(“Date“.equals(type) || “integer“.equals(type)) {

BeanValueUtils.setValue(t,rsmd.getColumnLabel(x).toLowerCase(),rs.getDate(rsmd.getColumnLabel(x)));

}

return null ;

}

} 

}

测试操作后,显示索引丢失,跟上FindSupport support = new FindSupport();,再跟上

support.setPreparedStatement(this.pstmt,value);后再次执行,没有出错但没有值,再跟上 system.out.println(obj);,执行成功。

5、需要在 BeanValueUtils 类中追加一个根据对象使用相应的setter方法的调用操作。通过 setValue ,即 public static void setValue(Object obj,String attributeName) {来专门设置内容,知道属性名称就可以知道参数位型。

再找到

Fieldfield = obj.getClass().getDeclaredField(attributeName);,

然后就可以知道属性位型,再找到field.getype()进行完善。此外需要完善内容的设置,跟上Object value,

再找到

setMethod.invoke(obj,value);,就可以实现setter调用操作,如下:

public static void setValue(Object obj,String attributeName) {

try {

Field field = obj.getClass().getDeclaredField(attributeName);

Method setMethod = obj.getClass().getMethod(“set” + StringUtils.initcao(attributeName())) ;

setMethod.invoke(obj,value);

} catch (Exception e) {

e.printStackTrace() ;

}

}

6、实现方法的整合调用:

/**

* 对数据的查询进行控制

* @param sql 要执行的根据ID查询的SQL语句

* @param value 要查询的id数据

* @param cls 要处理的VO类型

* @return 查询到数据则将ResultSet的内容自动转换为VO对象返回

* @throws Exception

*/

public <T,V> T findByIdSupport(String sql,V value,Class<T> cls) throws Exception {

FindSupport support = new FindSupport();\

this.pstmt = this.conn.preparedStatement(sql);

support.setPreparedStatement(this.pstmt,value);

returnResultSetToVOUtil.convertSingle(this.pstmt,cls);

}

要想实现一些自动化的控制,必须依靠元数据,而且使用反射最大的亮点在于不受到具体类型的限制。

相关文章
|
前端开发
Layout布局实现一个简单的react管理后台
Layout布局实现一个简单的react管理后台
273 0
|
存储 负载均衡 算法
哈希算法
哈希算法
|
SQL 前端开发 Java
在IDEA中使用Maven将SpringBoot项目打成jar包、同时运行打成的jar包(前后端项目分离)
这篇文章介绍了如何在IntelliJ IDEA中使用Maven将Spring Boot项目打包成可运行的jar包,并提供了运行jar包的方法。同时,还讨论了如何解决jar包冲突问题,并提供了在IDEA中同时启动Vue前端项目和Spring Boot后端项目的步骤。
在IDEA中使用Maven将SpringBoot项目打成jar包、同时运行打成的jar包(前后端项目分离)
|
存储 移动开发 算法
操作系统(16)----磁盘相关
操作系统(16)----磁盘相关
341 3
|
机器学习/深度学习 人工智能 安全
移动应用开发的未来趋势与挑战
【8月更文挑战第33天】随着移动设备成为我们日常生活中不可或缺的一部分,移动应用开发领域正经历着前所未有的增长和变革。本文将探讨移动应用开发的未来趋势,包括跨平台开发框架的兴起、人工智能和机器学习的集成、移动电商的增长以及安全性的重要性。同时,我们也将讨论开发者在这一过程中面临的挑战,如保持应用的高性能、确保数据隐私和安全、适应不断变化的市场和技术环境等。通过分析这些趋势和挑战,我们可以更好地理解移动应用开发的未来方向,并为开发者提供有价值的见解和建议。
142 5
|
Unix 大数据 Linux
【Linux is not Unix】Linux前言
【Linux is not Unix】Linux前言
|
XML Java 调度
Android App网络通信中通过runOnUiThread快速操纵界面以及利用线程池Executor调度异步任务实战(附源码 简单易懂)
Android App网络通信中通过runOnUiThread快速操纵界面以及利用线程池Executor调度异步任务实战(附源码 简单易懂)
283 0
带你读《卫星互联网:助力新基建的有硬科技》精品文章合集
带你读《卫星互联网:助力新基建的有硬科技》精品文章合集
|
Java Apache
关于处理NOClassDefFoundError-org/apache/logj4/logManager
关于处理NOClassDefFoundError-org/apache/logj4/logManager
188 0
|
Java Spring
Spring — 自动注入 ?
自动注入相对显式注入、在实际场景中确实用得比较少、但是了解其过程还是会让你收获到一些相关的知识和流程
203 0