最近在做一个定时读取数据的功能,我的想法是能够动态的添加定时任务而不用重启系统,在网上也借阅了很多文章,但是都不够完整,因此通过网上的借鉴我自己整理了一份代码,系统采用的是Spring Boot+MyBatis。
通过Spring实现定时任务有2种方式:
一、通过注解@Scheduled,如@Scheduled(fixedRate = 1000 * 30)表示30秒执行一次,具体用法可以在网上搜索。
二、通过quartz定时配置,我这里主要是使用的注解,反射等方式实现,可能会不受Spring容器的控制
maven配置如下(主要部分):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.11</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.0.1</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j</artifactId> </dependency> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
数据库的链接方式如下, 配置的application.properties和mybatis.xml文件(这里不清楚为什么如果只是配置xml文件连接数据库启动时会报错,配置在properties文件里就不会,xml也要配置是因为后面通过反射方式读取时需要用到xml配置里的数据库):
application.properties:
mybatis.config=classpath:config/mybatis.xml spring.datasource.name=pump_valve spring.datasource.url=jdbc:mysql://localhost:3306/pump_valve spring.datasource.username=root spring.datasource.password= # 使用druid数据源 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.filters=stat spring.datasource.maxActive=20 spring.datasource.initialSize=1 spring.datasource.maxWait=60000 spring.datasource.minIdle=1 spring.datasource.timeBetweenEvictionRunsMillis=60000 spring.datasource.minEvictableIdleTimeMillis=30000 spring.datasource.validationQuery=select 'x' spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false spring.datasource.poolPreparedStatements=true spring.datasource.maxOpenPreparedStatements=20
mybatis.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.1//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias alias="scheduleJob" type="com.chinamobile.pumpValve.entity.ScheduleJob"/> <typeAlias alias="equipmentInfo" type="com.chinamobile.pumpValve.entity.EquipmentInfo" /> <typeAlias alias="project" type="com.chinamobile.pumpValve.entity.Project" /> <typeAlias alias="equipmentStatusInfo" type="com.chinamobile.pumpValve.entity.EquipmentStatusInfo" /> </typeAliases> <environments default="development"> <!-- 开发环境数据 --> <environment id="development"> <transactionManager type="jdbc"></transactionManager> <dataSource type="pooled"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/pump_valve?useSSL=false&characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value=""/> </dataSource> </environment> </environments> <mappers> <mapper resource="mapper/scheduleJob.xml"/> <mapper resource="mapper/equipmentInfo.xml" /> <mapper resource="mapper/project.xml" /> <mapper resource="mapper/equipmentStatusInfo.xml" /> </mappers> </configuration>
创建一个schedule_job定时任务表,其对应的实体类如下(省略了get/set方法):
public static final String STATUS_RUNNING = "1"; public static final String STATUS_NOT_RUNNING = "0"; public static final String CONCURRENT_IS = "1"; public static final String CONCURRENT_NOT = "0"; private Integer scheduleJobId = null; //任务名称 private String jobName = ""; //任务分组 private String jobGroup = ""; //任务状态 是否启动任务 private String jobStatus = ""; //cron表达式,定时任务运行时间 private String cronExpression = ""; //描述 private String description = ""; //任务执行时调用哪个类的方法 包名+类名 private String beanClass = ""; //任务是否有状态 private String concurrentStatus = ""; //spring bean private String springId = ""; //任务调用的方法名 private String methodName = ""; //定时任务是否有效 private String enableFlag = "";
jobName 和jobGroup 组成唯一的组合,cronExpression形式如0 0/2 * * * ? ,表示每2分钟运行一次,具体可参考网上,其他表对应的实体类就不在上传表示。
mybatis对应的scheduleJob.xml(这里只是列举了部分):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.chinamobile.pumpValve.dao.ScheduleJobDAO"> <select id="getAll" resultType="scheduleJob"> SELECT SCHEDULE_JOB_ID scheduleJobId, JOB_NAME jobName, JOB_GROUP jobGroup, JOB_STATUS jobStatus, CRON_EXPRESSION cronExpression, DESCRIPTION description, BEAN_CLASS beanClass, CONCURRENT_STATUS concurrentStatus, SPRING_ID springId, METHOD_NAME methodName, ENABLE_FLAG enableFlag, CREATED_BY createdBy, CREATION_DATE creationDate, LAST_UPDATED_BY lastUpdatedBy, LAST_UPDATE_DATE lastUpdateDate FROM schedule_job WHERE ENABLE_FLAG = 'Y' </select> </mapper>
其他的配置也不再展示。
创建DAO接口类ScheduleJobDAO,因为mybatis只需要接口就可以了,代码如下:
public interface ScheduleJobDAO { /** * 获取所有的job * @return */ public List<ScheduleJob> getAll(); /** * 获取特定job * @param scheduleJob * @return */ public ScheduleJob getJobByNameAndGroup(ScheduleJob scheduleJob); /** * 插入job * @param scheduleJob */ public void addEntity(ScheduleJob scheduleJob); /** * 更新job的corn_expression字段 * @param scheduleJob */ public void updateExpreByNameAndGroup(ScheduleJob scheduleJob); }
ScheduleJobService类:
import org.quartz.*; import org.quartz.impl.matchers.GroupMatcher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ImportResource; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * @DESCRIPTION 定时任务Service类 */ @RestController @ImportResource("config/spring.xml") public class ScheduleJobService { public final static Logger log = Logger.getLogger(ScheduleJobService.class); @Autowired private SchedulerFactoryBean schedulerFactoryBean = null; @Autowired private ScheduleJobDAO scheduleJobDAO = null; @PostConstruct public void addJobBegin() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); // 这里从数据库中获取任务信息数据 List<ScheduleJob> jobList = scheduleJobDAO.getAll(); for (ScheduleJob job : jobList) { addTimeJob(job); } } /** * 添加任务 * @param job * @throws SchedulerException */ public void addTimeJob(ScheduleJob job) throws SchedulerException { /*if(job == null || ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())){ return; }*/ if(job == null){ return; } log.info("开始添加任务-->"+job.getJobGroup()+"."+job.getJobName()+"."+job.getMethodName()); Scheduler scheduler = schedulerFactoryBean.getScheduler(); //根据任务名称和任务组组成唯一的triggerKey TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(),job.getJobGroup()); CronTrigger cronTrigger = (CronTrigger)scheduler.getTrigger(triggerKey); //查看是否已经存在该任务 if(cronTrigger == null){ Class clazz = ScheduleJob.CONCURRENT_IS.equals(job.getConcurrentStatus()) ? QuartzJobFactory.class:QuartzJobFactoryDisallowConcurrentExecution.class; JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(),job.getJobGroup()).build(); jobDetail.getJobDataMap().put("scheduleJob",job); CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronTrigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(),job.getJobGroup()).withSchedule(cronScheduleBuilder).build(); scheduler.scheduleJob(jobDetail,cronTrigger); }else { // Trigger已存在,那么更新相应的定时设置 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); // 按新的cronExpression表达式重新构建trigger cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, cronTrigger); } log.info("结束添加任务-->"+job.getJobGroup()+"."+job.getJobName()+"."+job.getMethodName()); } /** * 获取所有计划中的任务列表 * @return * @throws SchedulerException */ @RequestMapping(value = "/pumpValve/getAllJob",method = RequestMethod.GET) public List<ScheduleJob> getAllJob() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); GroupMatcher<JobKey> groupMatcher = GroupMatcher.anyJobGroup(); Set<JobKey> jobKeys = scheduler.getJobKeys(groupMatcher); List<ScheduleJob> ScheduleJobs = new ArrayList<ScheduleJob>(); for(JobKey jobKey : jobKeys){ List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey); for(Trigger trigger : triggers){ ScheduleJob jobForm = new ScheduleJob(); jobForm.setJobName(jobKey.getName()); jobForm.setJobGroup(jobKey.getGroup()); jobForm.setDescription("触发器:"+trigger.getKey()); Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); jobForm.setJobStatus(triggerState.name()); if(trigger instanceof CronTrigger){ CronTrigger cronTrigger = (CronTrigger)trigger; String cronExpression = cronTrigger.getCronExpression(); jobForm.setCronExpression(cronExpression); } ScheduleJobs.add(jobForm); } } return ScheduleJobs; } /** * 所有正在运行的job * @return * @throws SchedulerException */ public List<ScheduleJob> getRunningJob() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs(); List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size()); for (JobExecutionContext executingJob : executingJobs) { ScheduleJob job = new ScheduleJob(); JobDetail jobDetail = executingJob.getJobDetail(); JobKey jobKey = jobDetail.getKey(); Trigger trigger = executingJob.getTrigger(); job.setJobName(jobKey.getName()); job.setJobGroup(jobKey.getGroup()); job.setDescription("触发器:" + trigger.getKey()); Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); job.setJobStatus(triggerState.name()); if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; String cronExpression = cronTrigger.getCronExpression(); job.setCronExpression(cronExpression); } jobList.add(job); } return jobList; } /** * 暂停一个job * @param scheduleJob * @throws SchedulerException */ public void pauseJob(ScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.pauseJob(jobKey); } /* 恢复一个job * @param scheduleJob * @throws SchedulerException */ public void resumeJob(ScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.resumeJob(jobKey); } /** * 删除一个job * @param scheduleJob * @throws SchedulerException */ public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.deleteJob(jobKey); } /** * 立即执行job * @param scheduleJob * @throws SchedulerException */ public void runAJobNow(ScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.triggerJob(jobKey); } /** * 更新job时间表达式 * @param scheduleJob * @throws SchedulerException */ public void updateJobCron(ScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //判断时间表达式是否正确 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()); trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); scheduler.rescheduleJob(triggerKey, trigger); //更新表中的表达式 scheduleJobDAO.updateExpreByNameAndGroup(scheduleJob); } @RequestMapping(value = "/pumpValve/addExecuteJob/{jobName}/{jobGroup}") public void addExecuteJob(@PathVariable("jobName") String jobName, @PathVariable("jobGroup") String jobGroup) throws SchedulerException { ScheduleJob scheduleJobForm = new ScheduleJob(); scheduleJobForm.setJobName(jobName); scheduleJobForm.setJobGroup(jobGroup); scheduleJobForm = scheduleJobDAO.getJobByNameAndGroup(scheduleJobForm); addTimeJob(scheduleJobForm); } public void addJob(ScheduleJob scheduleJob){ scheduleJobDAO.addEntity(scheduleJob); }
这里通过注解@ImportResource导入了一个spring配置文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd "> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" /> </beans>
还有就是log4j的配置
log4j.rootLogger=DEBUG,Console,File log4j.logger.org.springframework=error log4j.logger.org.mybatis.spring=DEBUG log4j.logger.base=DEBUG log4j.logger.org.apache.ibatis=debug log4j.logger.java.sql=debug log4j.logger.java.sql.Connection=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.Target=System.out log4j.appender.Console.Threshold=DEBUG log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=[%p][%l]-%m%n log4j.appender.File=org.apache.log4j.RollingFileAppender log4j.appender.File.File=E:/log/quartz-spring_demo.log log4j.appender.File.MaxBackupIndex=10 log4j.appender.File.MaxFileSize=5MB log4j.appender.File.Threshold=ALL log4j.appender.File.layout=org.apache.log4j.PatternLayout log4j.appender.File.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c]%m%n log4j.logger.org.quartz=INFO
以及使用了另外两个类,QuartzJobFactory:
import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class QuartzJobFactory implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob"); TaskUtils.invokeMethod(scheduleJob); } }
QuartzJobFactoryDisallowConcurrentExecution类:
import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; @DisallowConcurrentExecution public class QuartzJobFactoryDisallowConcurrentExecution implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { ScheduleJob scheduleJob = (ScheduleJob)context.getMergedJobDataMap().get("scheduleJob"); TaskUtils.invokeMethod(scheduleJob); } }
这两个类中使用了TaskUtils类,代码如下:
import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @Description 用于启动任务 */ public class TaskUtils { public final static Logger log = Logger.getLogger(TaskUtils.class); public static void invokeMethod(ScheduleJob scheduleJob){ Object object = null; Class clazz = null; if(StringUtils.isBlank(scheduleJob.getSpringId())){ //根据spirng bean id 获取Java类 clazz = SpringUtils.getBean(scheduleJob.getSpringId()); }else if(StringUtils.isNotBlank(scheduleJob.getBeanClass())){ try { //根据类全路径名获取Java类 clazz = Class.forName(scheduleJob.getBeanClass()); //实例化类 object = clazz.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } if(object == null){ log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!"); return; } clazz = object.getClass(); Method method = null; try { //判断特定的方法来反射获取方法 if(scheduleJob.getMethodName().equals("testVariableJob")){ method = clazz.getDeclaredMethod(scheduleJob.getMethodName(),String.class); }else { method = clazz.getDeclaredMethod(scheduleJob.getMethodName()); } } catch (NoSuchMethodException e) { log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!"); e.printStackTrace(); } if(method != null){ try { //判断特定的方法是否传参等,同时启动方法 if(scheduleJob.getMethodName().equals("getAllEquipment")){ EquipmentInfoDAO equipmentInfoDAO = SpringUtils.getBean("equipmentInfoDAO"); method.invoke(object,equipmentInfoDAO); }else{ method.invoke(object); } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]----------启动成功"); } }
SpringUtils类:
import org.springframework.beans.BeansException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; /** * @Description 根据Spring工厂类获取Java实例 */ public class SpringUtils implements BeanFactoryPostProcessor { private static ConfigurableListableBeanFactory beanFactory; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { SpringUtils.beanFactory = configurableListableBeanFactory; } /** * 获取对象 * * @param name * @return Object 一个以所给名字注册的bean的实例 * @throws BeansException * */ public static <T> T getBean(String name) throws BeansException { return (T) beanFactory.getBean(name); } /** * 获取类型为requiredType的对象 * * @param clz * @return * @throws BeansException * */ public static <T> T getBean(Class<T> clz) throws BeansException { T result = (T) beanFactory.getBean(clz); return result; } /** * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true * * @param name * @return boolean */ public static boolean containsBean(String name) { return beanFactory.containsBean(name); } /** * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) * * @param name * @return boolean * @throws NoSuchBeanDefinitionException * */ public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { return beanFactory.isSingleton(name); } /** * @param name * @return Class 注册对象的类型 * @throws NoSuchBeanDefinitionException * */ public static Class<?> getType(String name) throws NoSuchBeanDefinitionException { return beanFactory.getType(name); } /** * 如果给定的bean名字在bean定义中有别名,则返回这些别名 * * @param name * @return * @throws NoSuchBeanDefinitionException * */ public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { return beanFactory.getAliases(name); } }
定时任务运行时将会到EquimpentInfoService类中去运行fetchData()方法(在定时任务表中需要运行method_name字段上的名字),因为mybatis只需要接口就可以使用数据库读取,因为通过反射的方式获取不能通过接口去读取数据库,因此在这里我们就接口类进行了实现,EquimpentInfoDAOImpl代码如下:
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import java.util.List; /** * @DESCRIPTION 设备dao实现类,针对反射的时候Spring注入获取不到值 */ public class EquipmentInfoDAOImpl implements EquipmentInfoDAO { private SqlSessionFactory sqlSessionFactory; public EquipmentInfoDAOImpl(SqlSessionFactory sqlSessionFactory){ this.sqlSessionFactory = sqlSessionFactory; } @Override public List<EquipmentInfo> getAllEquipment() { SqlSession session = sqlSessionFactory.openSession(); List<EquipmentInfo> equipmentInfoList = session.selectList("getAllEquipment"); session.close(); return equipmentInfoList; } }
EquimpentInfoService类实现如下(这里实现通过反射方式就会脱离了spring容器控制):
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.io.InputStream; import java.util.List; /** * @DESCRIPTION 设备信息Service类 */ @RestController public class EquipmentInfoService { public final static Logger log = Logger.getLogger(EquipmentInfoService.class); @Autowired private EquipmentInfoDAO equipmentInfoDAO = null; /** * 获取所有设备信息 * @return */ public List<EquipmentInfo> getAllEquipment(){ List<EquipmentInfo> equipmentInfoList = null; if(equipmentInfoDAO == null){ EquipmentInfoDAOImpl infoDAO = new EquipmentInfoDAOImpl(getSqlSessionFactory()); equipmentInfoList = infoDAO.getAllEquipment(); }else { equipmentInfoList = equipmentInfoDAO.getAllEquipment(); } return equipmentInfoList; } /** * 获取SqlSessionFactory * @return */ private SqlSessionFactory getSqlSessionFactory(){ SqlSessionFactory sqlSessionFactory = null; SqlSession session = null; String resource = "config/mybatis.xml"; InputStream inputStream; try { inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } return sqlSessionFactory; } public void fetchData(){ List<EquipmentInfo> equipmentInfoList = getAllEquipment(); for(EquipmentInfo equipmentInfo : equipmentInfoList){ } }
这里就是主要的代码实现了。这里主要是处理了因为反射的原因,不能读取到通过注解@Autowried注入EquipmentInfoDAO 类,换而用EquipmentInfoDAOImpl去读取数据。