工作日记

参加工作将满3个月,也算是真正地参与到一个项目中。
这个项目的主要功能是数据交换,即在省政府各个部门之间搭建一个交换系统,实现数据库与文件的共享;

我负责实现的功能:

  • 性能监控(micrometer+prometheus+grafana)

  • 表列功能探测,探测表的列信息

	//表类
	public class TableMetaDto {
	    private String tableName;
	    private List columnMetas;
	}
	//列类
	public class ColumnMetaDto {
	    private String name;
	    private String type;
	    private int DisplaySize;

	    public ColumnMetaDto(String name, String type, int displaySize) {
	        this.name = name;
	        this.type = type;
	        DisplaySize = displaySize;
	    }
	}
	/**
     * 探测列定义信息
     */
    private final static String PROB_SQL = "select * from %s where 1=2";

    @Override
    public TableMetaDto probeColumns(ColumnProbeVo probeVo) throws DissException {
        TableMetaDto tmd = new TableMetaDto();
        ColumnMetaDto cmd;
        //通过数据库类型获取驱动
        String driver = DbDriverUtil.driverClassName(probeVo.getDbType().name());

        //通过数据库信息获取url
        String url = JdbcUrlUtil.buildUrl(probeVo.getDbType().name()
                , probeVo.getHost(), probeVo.getPort()
                , probeVo.getDatabase(), probeVo.getSid());

        String sql = StringUtil.format(PROB_SQL, probeVo.getTableName());

        PreparedStatement st = null;
        ResultSet rs = null;
        ResultSetMetaData md;
        Connection conn = null;
        try {
            conn = JdbcUtil.getConnection(url, probeVo.getUsername(), probeVo.getPassword(), driver);
            st = JdbcUtil.getPreStatement(conn, sql);
            rs = st.executeQuery();
            md = rs.getMetaData();
            //列数
            int cols = md.getColumnCount();
            //读所有字段的信息
            List list = new ArrayList<>();
            for (int i = 1; i <= cols; i++) {
                cmd = new ColumnMetaDto(md.getColumnName(i), md.getColumnTypeName(i), md.getColumnDisplaySize(i));
                list.add(cmd);
            }
            tmd.setTableName(probeVo.getTableName());
            tmd.setColumnMetas(list);
        } catch (SQLException e) {
            throw new DissException(DB_SQL_EXE_ERROR, e);
        } finally {
            JdbcUtil.close(conn, st, rs);
        }

        return tmd;
    }
  • 定时任务的增删改查(quartz),全局定义一个jobDetial,通过trigger绑定请求参数,设置job的触发时间以及增量还是全量的交换。jobDataMap中绑定了各种请求参数,cron是触发时间表达式。在持久化job,trigger和scheduler的信息到数据库的时候,遇到了一个大坑,在初始化scheduler时,我采用了Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();的方式,运行完之后,发现只有quartz_locks表有数据,其他表都没有数据。经过认真思考,冷静分析,发现scheduler既然已经在配置文件中声明了,如果用上述方式创建scheduler,那不就是两个不一样的scheduler了吗,如果quartz默认是持久化配置文件中的scheduler,那trigger和job表中没有数据也就解释通了。所以,我们应该用@Autowired Scheduler scheduler;的方式,将配置文件中的scheduler注入,就可以实现持久化了。
	@Autowired
    Scheduler scheduler;
    ---------------------------
	/**
     * 全局只有一个 交换 jobDetail
     *
     * @return
     */
    @Bean(name = "ECH-ENTRY-JOB")
    JobDetail newEchEntryJob() {
        return JobBuilder.newJob(EchEntryJob.class)
                .withIdentity(ENTRY_JOB_KEY, DISS_JOB_GROUP)
                .storeDurably(true) 				//设置job没有绑定trigger也能保存
                .withDescription("所有定时交换任务的入口JOBDETAIL,全局只有一个实例")
                .build();
    }
--------------------------------------------------------------------------------------------------------------------------------
	@Override
    public void addTrigger(JobDataMap jobDataMap, String cron, String triggerName, JobDetail jobDetail) throws SchedulerException {
        Date date;
        TriggerKey key = TriggerKey.triggerKey(triggerName);
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(key)
                .usingJobData(jobDataMap)
                .forJob(jobDetail)
                .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                .build();
        //如果trigger已存在,新的trigger取代旧的trigger
        date = scheduler.rescheduleJob(key, trigger);
        //如果date为空,则表示该trigger没有注册过
        if (date == null) {
            scheduler.scheduleJob(trigger);
        }
    }

配置文件application.properties内容如下

#任务调度
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.job-store-type=jdbc
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.quartz.jdbc.initialize-schema=NEVER
spring.quartz.auto-startup=true
spring.quartz.scheduler-name=DISS-AGENT-SCHE
spring.quartz.properties.org.quartz.scheduler.rmi.export=false
spring.quartz.properties.org.quartz.scheduler.rmi.proxy=false
spring.quartz.properties.org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
spring.quartz.properties.org.quartz.threadPool.threadCount=200

表结构:
工作日记_第1张图片

  • ftp下载文件,上传至obs,然后将ftp的已下载文件移至备份目录。这里用到了cn.hutool.extra.ftp.Ftp;这个工具类,在实现ftp文件移动的过程中,调用ftpClient.retrieveFileStream()时,发现ftp连接总是会断开,经过一番分析后发现此方法只能用作本地上传ftp调用,不能用作ftp文件移动,因为ftp服务器不能同时打开两个stream(input/output)
  • 观摩大佬的代码,发现mybatis的船新写法:,提高查询效率
    
      info_cata_id, info_cata_unit_id, info_cata, ech_type, request_id, require_subs_id, 
      require_unit_id, create_time, update_time, create_user, update_user, `status`, batch_id
    

	
  • 实习后才知道的标签
    @Transactional:事务标签,有两个参数rollbackFor和 propagation,指明回滚的异常类型与事务的传播策略
    @Value:在application.properties中给变量赋值后,用此标签进行注入@Value("${ftp.download.local.path}")
    @Data:lombok插件中的标签,对象类使用后不必再写get和set方法,已经默认有了所有变量的get和set方法
    @AllArgsConstructor:lombok插件中的标签,省去写全参构造函数的麻烦
    @NoArgsConstructor:lombok插件中的标签,省去写无参构造函数的麻烦
    @Builder:lombok插件中的标签,为了解决在某个类有很多构造函数的情况,也省去写很多构造函数的麻烦,在设计模式中的 思想是:用一个内部类去实例化一个对象,避免一个类出现过多构造函数,
    @RestController:包含了@Controller和@ResponseBody
    @Validated:校验参数类型是否符合规定
    @Slf4j:lombok插件中的标签,用于打印日志
    @MapperScan(“mapper路径”):用在启动类中,用于扫描mapper类
    @Qualifier(“name”): 当接口有多个实现类时,选择指定的实现类
    @Scope(“prototype”): 设置多例模式
    @Component: 把普通pojo实例化到spring容器中
    @Configuration: 指示一个类声明一个或多个@Bean方法,并且可以由Spring容器处理
    @ConfigurationProperties: 将配置文件中的属性值映射到使用此注解的类的属性值上
    @EnableConfigurationProperties: 与上一个标签配对使用,将使用了@ConfigurationProperties的类注入到使用 @EnableConfigurationProperties的类中,相当于在使用@ConfigurationProperties的类上再加一个@Component
  • 并发编程
  • mapper.xml无法打包到maven中时,在pom.xml中加入以下代码
	
            
                src/main/java
                
                    **/*.xml  
                
            
            
                src/main/resources
                
                    **/*
                
            
    
  • 发生mybatis绑定错误时,在配置文件yml中加入mapper.xml所在路径,或者在pom.xml的build标签下加入
mybatis-plus:
  mapper-locations: classpath:com/qqbibi/danbing/api/dao/mapper/xml/*.xml
	
            
                src/main/java
                
                    **/*.xml  
                
            
            
                src/main/resources
                
                    **/*
                
            
    
  • maven配置代理:在setting.xml中加入以下
  
    
      optional
      true
      http
      
      
      web-proxy.tencent.com
      8080
    
  

你可能感兴趣的:(项目,quartz持久化,springboot)