SpringBoot + QueryDsl + JPA + SpringTask 实现循环查询MySQL数据库数据并插入Oracle数据库

1.前言

    因为公司业务的需要,需要写一个定时循环插入数据的脚本,本人只是个小菜鸡,所以用的技术都是基于公司的原有框架选择的较简单的技术,并且之前没有了解过QueryDsl,所以这次的blog也是记录下自己学习QueryDsl的过程.

2.需求

    定时查询MYSQL数据库的部门和人员编码List,按照部门/人员为单位插入伪数据,数据尽量真实

3.代码实现

    1.POM.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.41</version>
        </dependency>
        <!-- ojdbc驱动 -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>compile</scope>
        </dependency>
        <!--QueryDsl begin -->
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-sql</artifactId>
            <version>${querydsl.version}</version>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-sql-spring</artifactId>
            <version>${querydsl.version}</version>
        </dependency>
         <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-sql-codegen</artifactId>
            <version>${querydsl.version}</version>
            <scope>provided</scope>
        </dependency>        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

2.plugin插件

<!--实现QueryDsl的插件 红色字体为compile文件存放路径-->
<plugin>
    <groupId>com.mysema.maven</groupId>
    <artifactId>apt-maven-plugin</artifactId>
    <version>1.1.3</version>
    <executions>
        <execution>
            <goals>
                <goal>process</goal>
            </goals>
            <configuration>
                <outputDirectory>target/generated-sources/java</outputDirectory>
                <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
            </configuration>
        </execution>
    </executions>
</plugin>

3.定义实体类并编译

@Entity
@Table(name = "department")
@Data
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long create_dept_id;
    private Long create_time;
    private Long create_id;
    private Integer status;
    private Long update_time;
    private Long updater_id;
    private String create_dept_name;
    private String creator_name;
    private String updater_name;
    private Integer level;
    private String path;
    private Long sort_index;
    private String business_types;
    private String code;
    private String description;
    private String district;
    private String full_name;
    private String name;
    private String police_type;

    @ManyToOne(fetch = FetchType.EAGER, targetEntity = Department.class)
    @JoinColumn(name = "parent_id")
    private Department parent;
}
4.使用QueryDsl查询MYSQL数据库数据-定义数据源
/**
 * dsl数据源配置-mysql
 */
@Configuration
// 不加事务注解会提示Connection is not Transactional
@Transactional 
public class DataDsl {

    @Bean
    public com.querydsl.sql.Configuration querydslConfiguration() {
        /**
         * 使用mysql数据源,Oracle就使用OracleTemplate模版
         */
        SQLTemplates templates = MySQLTemplates.builder()
                .printSchema()
                .build();
        com.querydsl.sql.Configuration configuration = new com.querydsl.sql.Configuration(templates);
        /** 若是Oracle数据源就需要如下配置 MySQL不需要
         * configuration.setExceptionTranslator(new SpringExceptionTranslator());
         * configuration.register(new DateTimeType());
         * configuration.register(new LocalDateType());
         */
        return configuration;
    }

    @Bean
    public SQLQueryFactory queryFactory() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://数据库地址");
        dataSource.setUsername("用户名");
        dataSource.setPassword("密码");
        Provider<Connection> provider = new SpringConnectionProvider(dataSource);
        return new SQLQueryFactory(querydslConfiguration(), provider);
    }
}
   
5.查询MySQL数据并使用JPA+定时器插入将数据插入Oracle
    
/**
 * 定时任务中心
 */
@Slf4j
@Component
//开启springboottask的注解
@EnableScheduling
@Transactional
public class VideoDataJob {

    /**
     * 查询部门编码
     */
    @Scheduled(cron = "${sync.schedule.department.time}")
    public List<String> getDepartmentCode() {
        if (CONSTANT.equals(department)) {
            log.info("VideoDataJob.getDepartmentCode >>>>> begin");
            /**
             *此处为QueryDsl的查询代码,QDepartment为编译后的实体类
             */
            QDepartment department = QDepartment.department;
            List<String> list = sqlQueryFactory.select(department.description).from(department).fetch();
            return list;
        }
        return null;
    }

    /**
     * 查询人员编码
     */
    @Scheduled(cron = "${sync.schedule.person.time}")
    public List<String> getPersonCode() {
        if (CONSTANT.equals(person)) {
            log.info("VideoDataJob.getPersonCode >>>>> beginQuery");  
            /**
             * 使用的是原生的sql查询sleect from + 条件
             */
            QPerson person = QPerson.person;
            List<String> list = sqlQueryFactory.select(person.code).from(person).fetch();
        }
        return null;
    }

    /**
     * 插入违法案件 + 警员code
     */
    @Scheduled(cron = "${sync.schedule.violation.time}")
    public void violationData() {
        if (CONSTANT.equals(violation)) {
            long currentTimeMillis = System.currentTimeMillis();
            try {
                List<String> list = getPersonCode();
                for (String personCode : list) {
                    log.info("VideoDataJob.violationData :  INSERT ! " + new Date());
                    Violation violation = new Violation();
                    /**
                     * 新增对象的伪代码
                     */
                    log.info("VideoDataJob.violationData :  SUCCESS ! " + new Date());
                    /**
                     * 线程休眠30s
                     */
                    Thread.sleep(1000*30);
                }
            } catch (Exception e) {
                log.error("VideoDataJob.violationData exception : " + e.getMessage());
            }
            log.info("VideoDataJob.violationData cost : " + (System.currentTimeMillis() - currentTimeMillis) + "ms");
        }
    }


    /**
     * 插入警情信息 + 部门编码
     */
    @Scheduled(cron = "${sync.schedule.policeCase.time}")
    public void policeCaseData() {
        if (CONSTANT.equals(policeCase)) {
            long currentTimeMillis = System.currentTimeMillis();
            try {
                List<String> list = getDepartmentCode();
                for (String departmentCode : list) {
                    log.info("VideoDataJob.policeCaseData :  INSERT ! " + new Date());
                    PoliceCase policeCase = new PoliceCase();
                    /**
                     * 新增对象的伪代码
                     */
                    log.info("VideoDataJob.policeCaseData :  SUCCESS ! " + new Date());
                    /**
                     * 线程休眠
                     */
                    Thread.sleep(1000*30);
                }
            } catch (Exception e) {
                log.error("VideoDataJob.policeCaseData exception :" + e.getMessage());
            }
            log.info("VideoDataJob.policeCaseData cost : " + (System.currentTimeMillis() - currentTimeMillis) + "ms");
        }
    }

    private static final String CONSTANT = "true";

    @Autowired
    private ViolationDao violationDao;

    @Autowired
    private PoliceCaseDao policeCaseDao;
    
    /**
     *注入QueryDsl的数据源工厂
     */    
    @Autowired
    private SQLQueryFactory sqlQueryFactory;
    /**
     * 获取配置是否打开违法案件定时器
     */
    @Value("${sync.schedule.violation.open}")
    private String violation;
    /**
     * 获取配置是否打开警情定时器
     */
    @Value("${sync.schedule.policeCase.open}")
    private String policeCase;

    /**
     * 获取配置是否打开部门code查询
     */
    @Value("${sync.schedule.department.open}")
    private String department;

    /**
     * 获取配置是否打开警员code查询
     */
    @Value("${sync.schedule.person.open}")
    private String person;

}
6.application.yml
       
spring:
  application:
    name: videoDataSchedule
  datasource:
      name: dataSource
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: oracle.jdbc.driver.OracleDriver
      url: jdbc:oracle:thin:@10.255.229.122:11521:XE
      username: ***
      password: ***

sync:
   schedule:
      violation:
        open: true
        time: 0 */1 * * * ?
      policeCase:
        open: true
        time: 0 */1 * * *  ?
      department:
        open: true
        time: 0 */1 * * * ?
      person:
        open: true
        time: 0 */1 * * * ?  
  
7.总结
  
   总体这个脚本还是很简单的,逻辑也是很简单,只是自己针对QueryDsl还不是很了解,同时因为Demo里面需要配置MySQL和oracle两个数据源,一开始的思路错了,一直纠结在配置文件中配置多数据源,后来了解到QueryDsl需要配置数据源SqlFactory,一下子思路就打开了,现在写完发现QueryDsl还是简单方便的,SpringBoot集成的东西还是非常多的,学习的路还是非常漫长的,加油!!

        

猜你喜欢

转载自blog.csdn.net/u010005147/article/details/80208839