前面已经说了一个动态的根据当前时间创建表和插入数据的示例,那么如何进行动态的查询呢?
我写了这样一个公共方法,仅供参考!
这里需要传递两个时间间隔参数,根据时间间隔判断相差的月数,然后从起始时间开始递增月份,然后动态拼装表的名称,如果存在该表则标记需要查询
所有的SQL通过 union all 来连接,最后增加分页的参数,分页只适合MySQL数据库
当然这个示例也只是适合于按月份来存储的情况
代码并不是很复杂,希望大家还是通过代码来理解一下:
package com; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; /** * @说明 进行测试 * @author cuisuqiang * @version 1.0 * @since */ public class DbTest { private static ApplicationContext context = null; @SuppressWarnings("unchecked") public static void main(String[] args) { context = new ClassPathXmlApplicationContext("applicationContext.xml"); String sql = "select * from :TABLE_NAME"; String key = "nm_cpu_log"; String beginTime = "2012-1-1 12:12:12"; String endTime = "2014-12-1 12:12:12"; String formatkey = "yyyy_MM"; List list = getListFromEachTable(sql,key,beginTime,endTime,formatkey,1,100); if(null != list){ System.out.println(list.size()); }else{ System.out.println("没有数据!"); } } /** * 动态查询表数据 * @param sqlTemplate 要执行的单条SQL 其中表名称用 :TABLE_NAME 标识 * @param tableKey 表前缀,不包含和时间中间的 下划线 * @param dateBegin 开始时间 yyyy-MM-dd HH:mm:ss * @param dateEnd 结束时间 yyyy-MM-dd HH:mm:ss * @param dateFormat 时间格式化方式 * @param pageIndex 分页索引 从 1 开始 * @param pageCount 每页查询数量 无限制 * @return 模版查询直接返回 */ @SuppressWarnings("unchecked") public synchronized static List getListFromEachTable(String sqlTemplate, String tableKey, String dateBegin, String dateEnd, String dateFormat, int pageIndex, int pageCount) { List list = null; try { // 一共有多少需要执行的SQL List<String> sqlList = new ArrayList<String>(); JdbcTemplate jt = (JdbcTemplate) context.getBean("jdbcTemplate"); // 转为时间 Date dbegin = StringToDateTime(dateBegin); Date dend = StringToDateTime(dateEnd); // 相差的月数 int monthCount = calculateMonthIn(dend, dbegin); for (int i = 0; i <= monthCount; i++) { // 下 N 个月的时间 Date d = getNextMonth(dbegin, i); SimpleDateFormat format = new SimpleDateFormat(dateFormat); // 动态表名 String tableName = tableKey + "_" + format.format(d); // 如果有某表 if (getAllTableName(jt, tableName)) { System.out.println("存在表:" + tableName); // 替换名称获得SQL String sql = sqlTemplate.replace(":TABLE_NAME", tableName); sqlList.add(sql); } } // 实际要执行的SQL StringBuffer sqlGo = new StringBuffer(""); if (sqlList.size() > 0) { for (int i = 0; i < sqlList.size(); i++) { if (i == sqlList.size() - 1) { sqlGo.append(sqlList.get(i)); } else { sqlGo.append(sqlList.get(i) + " union all "); } } } if (sqlList.size() > 0) { // 增加分页 int cindex = (pageIndex - 1) * pageCount; sqlGo.append(" limit " + cindex + "," + pageCount); } if (!"".equals(sqlGo.toString())) { System.out.println("执行的SQL:" + sqlGo.toString()); // 执行查询 list = jt.queryForList(sqlGo.toString()); } } catch (Exception e) { e.printStackTrace(); list = null; } return list; } /** * 将传入的字符串按yyyy-MM-dd HH:mm:ss格式转换成对应的日期对象 * @param str 需要转换的字符串 */ public synchronized static Date StringToDateTime(String str) { String _pattern = "yyyy-MM-dd HH:mm:ss"; return StringToDate(str, _pattern); } /** * 将插入的字符串按格式转换成对应的日期对象 * @param str 字符串 * @param pattern 格式 */ public synchronized static Date StringToDate(String str, String pattern) { Date dateTime = null; try { if (str != null && !str.equals("")) { SimpleDateFormat formater = new SimpleDateFormat(pattern); dateTime = formater.parse(str); } } catch (Exception ex) { ex.printStackTrace(); } return dateTime; } /** * 两个时间相差的月数 * @param date1 * @param date2 * @return */ public static int calculateMonthIn(Date date1, Date date2) { Calendar cal1 = new GregorianCalendar(); cal1.setTime(date1); Calendar cal2 = new GregorianCalendar(); cal2.setTime(date2); int c = (cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR)) * 12 + cal1.get(Calendar.MONTH) - cal2.get(Calendar.MONTH); return c; } /** * 获得下几个月的时间对象 * @param date * @param count * @return */ public static Date getNextMonth(Date date, int count) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.MONTH, count); return c.getTime(); } /** * 查询数据库是否有某表 * @param jt * @param tableName * @return * @throws Exception */ @SuppressWarnings("unchecked") public static boolean getAllTableName(JdbcTemplate jt, String tableName) throws Exception { Connection conn = jt.getDataSource().getConnection(); ResultSet tabs = null; try { DatabaseMetaData dbMetaData = conn.getMetaData(); String[] types = { "TABLE" }; tabs = dbMetaData.getTables(null, null, tableName, types); if (tabs.next()) { return true; } } catch (Exception e) { e.printStackTrace(); } finally { tabs.close(); conn.close(); } return false; } }
请您到ITEYE看我的原创:http://cuisuqiang.iteye.com
或支持我的个人博客,地址:http://www.javacui.com
相关推荐
3. 创建数据源bean:在`Config`类中创建两个`DataSource` bean,并使用`@Primary`注解标记主数据源。例如: ```java @Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @...
然后,在实体类上添加`@Entity`注解,并使用`@Table`指定表名。接着,创建对应的Repository接口,Spring Data JPA会自动实现这些接口。 2. **JdbcTemplate操作**:你可以通过`@Autowired`注入特定数据源的`...
使用JdbcTemplate的`query()`方法,可以将动态生成的SQL与参数绑定,执行查询。例如: ```java public List<MyEntity> queryByPage(int pageNum, int pageSize) { String sql = "SELECT * FROM table LIMIT ? ...
2. **SQL构造工具**:提供了更友好的API来动态构建SQL语句,避免SQL注入问题,并支持参数化查询。 3. **异常处理**:封装了常见的JDBC异常,提供了更清晰的错误信息和处理机制。 4. **缓存支持**:可能集成了缓存...
- **执行SQL**:调用JdbcTemplate的execute()方法执行SQL,对于查询操作,可以使用query()方法,传入SQL、RowMapper或者ResultSetExtractor。 - **参数化查询**:使用问号?作为占位符,通过addBatch()添加参数,...
2. **创建Service**:在Service层,你可以定义业务逻辑,调用JdbcTemplate执行查询、插入、更新或删除等操作。这里也可以定义事务的边界。 3. **映射结果到模型**:JdbcTemplate提供了多种方式将查询结果映射到Java...
在上述示例中,JdbcTemplate的query方法使用RowMapper接口将结果集映射为User对象,实现了数据的自动转换。 然而,JdbcTemplate默认使用了AutoCommit模式,这意味着每个数据库操作都会立即提交,这可能会影响事务的...
本项目“springboot双数据源(oracle,mysql).rar”显然是一个使用SpringBoot实现多数据源的例子,允许应用程序同时连接并操作Oracle和MySQL两个数据库。以下将详细介绍实现这一功能的关键知识点。 1. **SpringBoot...
在图书管理系统中,JdbcTemplate被用来处理与数据库的 CRUD(创建、读取、更新、删除)操作,如添加新图书、查询图书信息、更新读者信息等。通过预编译的SQL语句和参数绑定,JdbcTemplate可以有效地防止SQL注入攻击...
在现代企业级应用开发中,数据源管理是一个关键部分,特别是在多租户或者需要根据业务需求动态切换数据库的场景下。本教程将详细介绍如何在Spring Boot项目中整合Druid数据源池与Mybatis,实现多数据源切换的功能,...
多数据源意味着应用程序可以同时连接并操作多个数据库,这在分布式系统或者需要跨数据库查询的场景中非常实用。SpringBoot允许我们轻松配置和管理多个数据源,通过Spring的DataJPA或MyBatis等持久层框架实现对不同...
在Web开发中,Servlet、JDBC以及JSP(JavaServer Pages)是常见的技术组合,用于构建动态、数据驱动的Web应用程序。在这个项目示例中,我们将深入探讨如何使用这些技术将MySQL数据库中的数据呈现到JSP页面上。 首先...
在Java编程中,构建动态表格并进行数据统计处理是一项常见的任务,特别是在数据分析、报表生成以及Web应用中。本文将深入探讨如何利用内存数据库H2来高效地实现这一目标。H2是一个轻量级、高性能的关系型数据库,它...
相比Apache POI,EasyExcel在读取大量数据时更节省内存,且支持动态解析,无需预先定义复杂的实体类。 2. **并发读取文件字段** EasyExcel提供了一种多线程并发读取Excel数据的方式,通过`readSheetHandler`和`...
在实际开发中,我们可能需要更复杂的动态生成数据库的逻辑,例如根据配置文件或API动态创建表。这时,可以使用`@PostConstruct`注解的方法在应用启动后执行特定的数据库初始化代码。例如: ```java import org....
4. **使用注解切换数据源**:在需要切换数据源的方法上添加自定义注解,例如`@UsePrimaryDataSource`和`@UseSecondaryDataSource`。然后创建一个AOP切面来处理这些注解,根据注解内容动态设置`DynamicDataSource`的...
在Spring Boot应用中,多数据源的动态配置是一项重要的任务,尤其对于那些需要处理多个数据库的应用来说。在本文中,我们将深入探讨如何实现这一功能,包括依赖管理、数据库创建、数据源配置以及测试代码的编写。 ...