循环中调用DAO时解决方案。(数据量比较大时应该采用的方法。)

在页面中显示的某个字段(A)是数据库中查出来的字段(B)和另一个查出来的字段(C)相关操作之后得出来的。

查出来的字段(B)是根据(C)的某个条件查出来的。

这时候不可以在(C)这个字段中循环使用C的某个字段为条件来查询出来B这个字段。

解决的方法:

在写B的方法是,查询条件和C的查询条件一直,然后相关联相关表 同时把 B中的相关字段查询出来存到集合中(DataSet,Set, arrayList或者HashMap都可以。)

public static  HashMap<Object, Object> findNotifyTotalDuebillBalance(Database db,
       String pcCode, String districtCode, String ccCode,
       String studentName,String studentCode) throws Exception
  {
    String sql = "select d.studentCode,sum(duebillBalance) as totalDuebillBalance " +
           "\n from duebill d" +
           "\n left join StudentRelation sr on sr.studentCode=d.studentCode" +
           "\n left join CountyCenter cc on cc.ccCode=sr.ccCode" +
           "\n where 1=1";
   
    if(!ccCode.equals(""))
        sql += "\n and sr.ccCode='"+ccCode+"'";
      else if(!districtCode.equals(""))
        sql += "\n and   exists (select 1 from CountyCenter cc where cc.ccCode=dd.deductCcCode and cc.pccCode like '"+districtCode+"%')";
      else if(!pcCode.equals(""))
        sql += "\n and sr.pcCode='"+pcCode+"'";
      if(!studentName.equals(""))
        sql += "\n and sr.studentName like '"+studentName+"%'";
      if(!studentCode.equals(""))
          sql += "\n and sr.studentCode = '"+studentCode+"'";
     
      sql += "\n group by d.studentCode";
     
    //执行查询
    DataSet ds = db.executeQuery(sql);
    HashMap<Object, Object> duebillMap = new HashMap<Object, Object>();
    for (int i=0;i<ds.size();i++)
    {
     duebillMap.put(ds.getString(i, "studentCode"),ds.getDouble(i, "totalDuebillBalance"));
    }
    return duebillMap;
  }

项目中的数据比较特殊是double类型的,存的时候可以转成double类型的封装类存起来,取的时候需要使用

String dubeill= duebillMap.get(cEnNotifyStudent.getStudentCode()).toString();
e_hj=Double.parseDouble(dubeill);

需要转换一下取出来。

 

批量的时候,调用 findNotifyTotalDuebillBalance方法时,传入和查询条件一致的参数,但是不传入studentCode,单个时,前面4个参数传入“”,空就可以了。

批量时根据查询出来的studentCode的hashMap就可以查找出对应的values值。

就不需要在循环中,根据每次循环的studentCode来查找对应的values值了。

 

 

5.1. 公共需求 ◼ 需要使用 Apache HttpComponents Client 实现接口调用; ◼ A 系统接口不稳定,接口调用失败需要有重试机制,若重试 3 次仍无法正确响应,则 回滚已同步的数据,取消本次同步任务; ◼ 获取 Token 接口,在 Token 未过期前不允许重复调用; ◼ 数据同步过程中,出现错误需要能够回滚数据,不能产生脏数据。 5.2. 实现 B 系统与 A 系统企业信息的定同步,具体要求如下: ◼ 分页调用接口文档中“获取客户列表”接口,将全量数据存储到 customer 表中; ◼ 每 10 分钟同步一次企业信息; ◼ A 系统企业出现增,删,改,B 系统都能够同步; ◼ A 系统数据有重复,需要去重; 5.3. 实现 B 系统与 A 系统监测设备信息的定同步,具体要求如下: ◼ 分页调用接口文档中“获取设备列表”接口,将全量数据存储到 device 表中; ◼ 每 5 分钟同步一次监测设备信息; ◼ 共用“获取企业列表”的 token; ◼ 学习并使用 dao 层 insert 或 insertSelective 方法将数据插入 device 表; ◼ 学习并使用 dao 层 updateByExample 或 updateByPrimaryKeySelective 或 updateByP rimaryKey 方法更新 device 表数据; 5.4. 实现 B 系统调用 A 系统的设备监测数据,具体要求如下: ◼ 调用接口文档中“获取设备数据列表”接口接收数据,存储到 device_data 表中; ◼ 需要将所有设备的监测数据都存入表中; ◼ 共用“获取企业列表”的 token; ◼ 学习并使用 dao 层 insert 或 insertSelective 方法将数据插入 device_data 表; ◼ 学习并使用 dao 层 updateByExample 或 updateByPrimaryKeySelective 或 updateByP rimaryKey 方法更新 device_data 表数据; 5.5. 稳健性测试,具体要求如下: ◼ 编写新方法循环调用 5.2,5.3,5.4 方法各 30 次; ◼ 能够正常完成测试; 5.6. 完善客户列表查询接口,具体要求如下: ◼ 在 CustomerController 中的 list 方法实现; ◼ 不允许修改 list 方法的入参、出参; ◼ 需要使用 dao 层 selectByExample、countByExample 方法查询数据; ◼ 具体业务在 CustomerService 实现,service 层需要自己创建; ◼ 需要根据 CustomerPage 类实现分页、搜索功能; 5.7. 编写统计查询接口,具体要求如下: ◼ 接口路径为/api/stat/test,请求方式为 GET,无参; ◼ 接口需要创建在 StatController 中,文件需要自己新增; ◼ 统计每家企业有多少种类型的设备,每种设备有多少条监测数据; ◼ 使用自定义 SQL 实现统计; ◼ 需要能够返回客户编号、客户名称、设备类型编号、设备类型名称、设备数量、设备 监测信息数; ◼ 返回数据结构不做要求,合理即可;
最新发布
03-15
<think>好的,我现在需要帮助用户解决如何使用Apache HttpComponents Client实现多个功能的问题。首先,我得理清楚用户的需求。用户提到的包括接口调用、重试机制、Token管理、数据同步及去重、DAO层操作、稳健性测试以及查询接口的实现。这看起来是一个综合性的项目,涉及多个方面,需要分步骤来解决。 首先,我应该回顾Apache HttpComponents Client的基本用法。根据用户提供的引用,HttpClient接口是核心,负责执行HTTP请求。用户可能需要先创建CloseableHttpClient实例,然后构造请求对象,比如HttpGet或HttpPost,并执行请求。这部分是基础,必须确保正确。 接下来是重试机制。用户提到需要实现重试,可能需要使用HttpRequestRetryHandler。我记得HttpClient允许自定义重试策略,比如在发生IOException重试,但需要注意非幂等的请求(如POST)是否适合重试。引用中提到使用CloseableHttpClient,所以可能需要通过HttpClients.custom()来配置重试处理程序。 然后是Token生命周期管理。这涉及到认证和令牌的获取、刷新。通常,OAuth2流程中需要先获取Token,然后在后续请求中添加Authorization头。如果Token过期,需要能够自动刷新。这里可能需要使用HttpClient的拦截器(如HttpRequestInterceptor)来动态添加Token,并处理Token失效的刷新逻辑。例如,当收到401响应,触发Token刷新,然后重试请求。 分页数据同步方面,用户需要同步customer和device表的数据。这可能需要循环请求接口,直到所有分页数据获取完毕。通常分页参数是page和size,需要逐页请求,解析响应,并将数据存入数据库。同,数据去重可能需要根据唯一标识(如ID)来判断是否已存在,避免重复插入。 设备监测数据的处理可能涉及定任务,定期调用接口获取最新数据,并进行存储或分析。这里可能需要结合调度框架,如Quartz或Spring Scheduler,定期执行数据同步任务。 DAO方法的学习与应用,用户可能需要使用JPA、MyBatis等持久层框架。这部分需要定义实体类,编写Repository或Mapper接口,实现数据的增删改查操作。例如,使用Spring Data JPA可以简化DAO层的开发。 稳健性测试方案设计需要考虑网络波动、服务端异常等情况。使用MockServer模拟各种异常响应,测试客户端的重试、超、错误处理等机制。还需要进行压力测试,比如使用JMeter模拟高并发请求,检查系统稳定性。 客户列表查询接口的完善可能涉及过滤条件、分页、排序等功能。需要根据前端的需求,在DAO层添加相应的查询方法,并在Controller中暴露接口。统计查询接口可能需要聚合数据,使用SQL的GROUP BY或Java Stream API进行处理。 在整合这些功能,需要注意模块之间的协作。例如,Token管理模块需要与HttpClient的拦截器结合,确保每个请求都携带有效的Token。数据同步模块可能需要调用DAO层的方法来存储数据,同处理分页和去重。 可能遇到的难点包括:Token的自动刷新机制,需要正确处理并发请求下的Token状态;分页同步的终止条件,如何判断最后一页;数据去重的效率问题,尤其是在数据量;以及稳健性测试中如何模拟各种异常场景。 需要确保每一步都符合最佳实践,比如使用try-with-resources确保HttpResponse正确关闭,合理配置连接池参数以提高性能,处理各种异常情况以保证系统鲁棒性。此外,代码结构要清晰,模块化设计,便于维护和扩展。 最后,根据用户提供的引用,特别是引用[3]中提到使用CloseableHttpClient代替已弃用的DefaultHttpClient,需要确保示例代码中使用的是推荐类。同,依赖管理要正确,如引用[2]和[4]提到的HttpClient 4.5版本,需在项目中引入正确的Maven依赖。 总结来说,解决方案需要分模块实现,逐步构建每个功能,确保各部分协调工作,同进行充分的测试以保证系统的稳定性和可靠性。</think>以下分步骤说明如何基于Apache HttpComponents Client实现完整接口调用解决方案: ### 一、基础接口调用实现 1. 创建HTTP客户端实例(支持HTTPS) ```java CloseableHttpClient httpClient = HttpClients.custom() .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) .build(); ``` 2. 实现GET/POST请求模板 ```java public String executeRequest(HttpRequestBase request) throws IOException { try (CloseableHttpResponse response = httpClient.execute(request)) { return EntityUtils.toString(response.getEntity()); } } ``` ### 二、重试机制实现 ```java HttpRequestRetryHandler retryHandler = (exception, executionCount, context) -> { if (executionCount >= 3) return false; // 最重试3次 return exception instanceof SocketTimeoutException; // 仅超重试 }; CloseableHttpClient client = HttpClients.custom() .setRetryHandler(retryHandler) .build(); ``` ### 三、Token生命周期管理 1. Token缓存与刷新 ```java class TokenManager { private String token; private LocalDateTime expireTime; public synchronized String getToken() { if (token == null || LocalDateTime.now().isAfter(expireTime)) { refreshToken(); // 调用认证接口 } return token; } } ``` 2. 请求拦截器配置 ```java httpClient = HttpClients.custom() .addInterceptorFirst((HttpRequestInterceptor) (request, context) -> { request.setHeader("Authorization", "Bearer " + tokenManager.getToken()); }) .build(); ``` ### 四、分页数据同步架构 1. 分页请求模板 ```java int page = 1; while (true) { String url = String.format("/api/devices?page=%d&size=100", page); String response = executeRequest(new HttpGet(url)); List<Device> devices = parseResponse(response); if (devices.isEmpty()) break; batchUpsertDevices(devices); // DAO层批量操作 page++; } ``` 2. 数据去重策略 ```sql -- 使用ON CONFLICT子句(PostgreSQL示例) INSERT INTO devices (id, name) VALUES (:id, :name) ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name ``` ### 五、DAO层优化实践 1. MyBatis批量插入 ```xml <insert id="batchInsert" parameterType="list"> INSERT INTO customers (id, name) VALUES <foreach collection="list" item="item" separator=","> (#{item.id}, #{item.name}) </foreach> </insert> ``` 2. JPA动态查询 ```java @Query("SELECT c FROM Customer c WHERE (:name IS NULL OR c.name LIKE %:name%)") Page<Customer> findCustomers(@Param("name") String name, Pageable pageable); ``` ### 六、稳健性测试方案 1. 异常场景模拟(使用WireMock) ```java stubFor(get(urlPathEqualTo("/api/devices")) .willReturn(aResponse() .withFixedDelay(5000) // 模拟超 .withStatus(503))); ``` 2. 压力测试配置 ```java PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(200); // 最连接数 cm.setDefaultMaxPerRoute(50); // 单路由最连接 ``` ### 七、查询接口完善方案 1. 客户列表查询接口 ```java public Page<CustomerDTO> searchCustomers(SearchCriteria criteria) { return customerRepository.findAll( Specification.where(hasName(criteria.getName())) .and(hasRegion(criteria.getRegion())), PageRequest.of(criteria.getPage(), criteria.getSize()) ); } ``` 2. 统计接口实现示例 ```java @Query("SELECT deviceType, AVG(temperature) FROM DeviceData WHERE timestamp BETWEEN :start AND :end GROUP BY deviceType") List<Object[]> getAvgTemperatureStats(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值