java quartz 数据库_SpringBoot+Quartz+数据库存储

Spring整合Quartz

a、quartz调度框架是有内置表的

进入quartz的官网http://www.quartz-scheduler.org/,点击Downloads,

下载后在目录\docs\dbTables下有常用数据库创建quartz表的脚本,例如:“tables_mysql.sql”

table_mysql.sql

table_mysql_innodb.sql

org.quartz-scheduler

quartz-jobs

2.2.1

org.springframework.boot

spring-boot-starter-quartz

com.mchange

c3p0

0.9.5.2

更换成Druid连接池

A、 引入依赖

com.alibaba

druid-spring-boot-starter

1.1.10

B、 导入DruidConnectionProvider.java

C、修改quartz.properties配置

#配置数据库源

org.quartz.dataSource.qzDS.connectionProvider.class:

com.lingerqi.项目名.util.DruidConnectionProvider

在项目中添加quartz.properties文件(这样就不会加载自带的properties文件)

此文件的内容主要分为:scheduler,ThreadPool,JobStore,plugin,Datasources等部分,

覆盖properties文件的目的是覆盖默认的数据源,更换为druid的数据配置

#

#============================================================================

# Configure Main Scheduler Properties 调度器属性

#============================================================================

org.quartz.scheduler.instanceName: DefaultQuartzScheduler

org.quartz.scheduler.instanceId = AUTO

org.quartz.scheduler.rmi.export: false

org.quartz.scheduler.rmi.proxy: false

org.quartz.scheduler.wrapJobExecutionInUserTransaction: false

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount= 10

org.quartz.threadPool.threadPriority: 5

org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true

org.quartz.jobStore.misfireThreshold: 60000

#============================================================================

# Configure JobStore

#============================================================================

#存储方式使用JobStoreTX,也就是数据库

org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX

org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate

#使用自己的配置文件

org.quartz.jobStore.useProperties:true

#数据库中quartz表的表名前缀

org.quartz.jobStore.tablePrefix:qrtz_

org.quartz.jobStore.dataSource:qzDS

#是否使用集群(如果项目只部署到 一台服务器,就不用了)

org.quartz.jobStore.isClustered = true

#============================================================================

# Configure Datasources

#============================================================================

#配置数据库源(org.quartz.dataSource.qzDS.maxConnections: c3p0配置的是有s的,druid数据源没有s)

org.quartz.dataSource.qzDS.connectionProvider.class:com.lingerqi.quartz02.utils.DruidConnectionProvider

org.quartz.dataSource.qzDS.driver: com.mysql.jdbc.Driver

org.quartz.dataSource.qzDS.URL: jdbc:mysql://localhost:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8

org.quartz.dataSource.qzDS.user: root

org.quartz.dataSource.qzDS.password: 123

org.quartz.dataSource.qzDS.maxConnection: 10

要搞清楚一个问题:从数据库读取任务信息动态生成定时任务,和把quartz持久化到数据库是没有关系的。前者是我们自己定义的业务表,而后者是quartz使用自己的表来存储信息。持久化到数据库后,就算服务器重启或是多个quartz节点也没关系,因为他们共享数据库中的任务信息。

自定义的业务表:

-- 注意:job_name存放的任务类的全路径,在quartz中通过jobName和jobGroup来确定trigger的唯一性,所以这两列为联合唯一索引

create table t_schedule_trigger

(

id int primary key auto_increment, -- ID

cron varchar(200) not null, -- 时间表达式

status char(1) not null, -- 使用状态 0:禁用 1:启用

job_name varchar(200) not null, -- 任务名称

job_group varchar(200) not null, -- 任务分组

unique index(job_name,job_group)

);

-- 额外添加到任务中的参数

create table t_schedule_trigger_param

(

param_id int primary key auto_increment, -- ID

name varchar(200) not null, -- 参数名

value varchar(512), -- 参数值

schedule_trigger_id int not null, -- 外键:引用t_schedule_trigger(id)

foreign key(schedule_trigger_id) references t_schedule_trigger(id)

);

package com.lingerqi.quartz02.utils;

import com.alibaba.druid.pool.DruidDataSource;

import org.quartz.SchedulerException;

import org.quartz.utils.ConnectionProvider;

import java.sql.Connection;

import java.sql.SQLException;

/*

#============================================================================

# JDBC

#============================================================================

org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate

org.quartz.jobStore.useProperties:false

org.quartz.jobStore.dataSource:qzDS

#org.quartz.dataSource.qzDS.connectionProvider.class:org.quartz.utils.PoolingConnectionProvider

org.quartz.dataSource.qzDS.connectionProvider.class:com.zking.q03.quartz.DruidConnectionProvider

org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver

org.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8

org.quartz.dataSource.qzDS.user:root

org.quartz.dataSource.qzDS.password:root

org.quartz.dataSource.qzDS.maxConnections:30

org.quartz.dataSource.qzDS.validationQuery: select 0

*/

/**

* [Druid连接池的Quartz扩展类]

*

* @ProjectName: []

* @Author: [xuguang]

* @CreateDate: [2015/11/10 17:58]

* @Update: [说明本次修改内容] BY[xuguang][2015/11/10]

* @Version: [v1.0]

*/

public class DruidConnectionProvider implements ConnectionProvider {

/*

* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*

* 常量配置,与quartz.properties文件的key保持一致(去掉前缀),同时提供set方法,Quartz框架自动注入值。

*

* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*/

//JDBC驱动

public String driver;

//JDBC连接串

public String URL;

//数据库用户名

public String user;

//数据库用户密码

public String password;

//数据库最大连接数

public int maxConnection;

//数据库SQL查询每次连接返回执行到连接池,以确保它仍然是有效的。

public String validationQuery;

private boolean validateOnCheckout;

private int idleConnectionValidationSeconds;

public String maxCachedStatementsPerConnection;

private String discardIdleConnectionsSeconds;

public static final int DEFAULT_DB_MAX_CONNECTIONS = 10;

public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = 120;

//Druid连接池

private DruidDataSource datasource;

/*

* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*

* 接口实现

*

* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*/

public Connection getConnection() throws SQLException {

return datasource.getConnection();

}

public void shutdown() throws SQLException {

datasource.close();

}

public void initialize() throws SQLException{

if (this.URL == null) {

throw new SQLException("DBPool could not be created: DB URL cannot be null");

}

if (this.driver == null) {

throw new SQLException("DBPool driver could not be created: DB driver class name cannot be null!");

}

if (this.maxConnection < 0) {

throw new SQLException("DBPool maxConnectins could not be created: Max connections must be greater than zero!");

}

datasource = new DruidDataSource();

try{

datasource.setDriverClassName(this.driver);

} catch (Exception e) {

try {

throw new SchedulerException("Problem setting driver class name on datasource: " + e.getMessage(), e);

} catch (SchedulerException e1) {

}

}

datasource.setUrl(this.URL);

datasource.setUsername(this.user);

datasource.setPassword(this.password);

datasource.setMaxActive(this.maxConnection);

datasource.setMinIdle(1);

datasource.setMaxWait(0);

datasource.setMaxPoolPreparedStatementPerConnectionSize(this.DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION);

if (this.validationQuery != null) {

datasource.setValidationQuery(this.validationQuery);

if(!this.validateOnCheckout)

datasource.setTestOnReturn(true);

else

datasource.setTestOnBorrow(true);

datasource.setValidationQueryTimeout(this.idleConnectionValidationSeconds);

}

}

/*

* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*

* 提供get set方法

*

* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*/

public String getDriver() {

return driver;

}

public void setDriver(String driver) {

this.driver = driver;

}

public String getURL() {

return URL;

}

public void setURL(String URL) {

this.URL = URL;

}

public String getUser() {

return user;

}

public void setUser(String user) {

this.user = user;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public int getMaxConnection() {

return maxConnection;

}

public void setMaxConnection(int maxConnection) {

this.maxConnection = maxConnection;

}

public String getValidationQuery() {

return validationQuery;

}

public void setValidationQuery(String validationQuery) {

this.validationQuery = validationQuery;

}

public boolean isValidateOnCheckout() {

return validateOnCheckout;

}

public void setValidateOnCheckout(boolean validateOnCheckout) {

this.validateOnCheckout = validateOnCheckout;

}

public int getIdleConnectionValidationSeconds() {

return idleConnectionValidationSeconds;

}

public void setIdleConnectionValidationSeconds(int idleConnectionValidationSeconds) {

this.idleConnectionValidationSeconds = idleConnectionValidationSeconds;

}

public DruidDataSource getDatasource() {

return datasource;

}

public void setDatasource(DruidDataSource datasource) {

this.datasource = datasource;

}

}

QuartzConfiguration.java(quartz调度框架与spring框架整合的配置类,主要是要将org.quartz.Scheduler交给spring进行管理)

package com.lingerqi.quartz02.config;

import com.lingerqi.quartz02.utils.MyJobFactory;

import org.quartz.Scheduler;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.config.PropertiesFactoryBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.core.io.ClassPathResource;

import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.io.IOException;

import java.util.Properties;

@Configuration

public class QuartzConfiguration {

@Autowired

private MyJobFactory myJobFactory;

//创建调度器工厂

@Bean

public SchedulerFactoryBean schedulerFactoryBean(){

//1.创建SchedulerFactoryBean

//2.加载自定义的quartz.properties配置文件

//3.设置MyJobFactory

SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();

try {

factoryBean.setQuartzProperties(quartzProperties());

factoryBean.setJobFactory(myJobFactory);

return factoryBean;

} catch (IOException e) {

throw new RuntimeException(e);

}

}

@Bean

public Properties quartzProperties() throws IOException {

PropertiesFactoryBean propertiesFactoryBean=new PropertiesFactoryBean();

propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));

propertiesFactoryBean.afterPropertiesSet();

return propertiesFactoryBean.getObject();

}

@Bean(name="scheduler")

public Scheduler scheduler(){

return schedulerFactoryBean().getScheduler();

}

}

案例中需要观察表数据变化的表

-- 自定义的业务表

SELECT * FROM t_schedule_trigger;

SELECT * FROM t_schedule_trigger_param;

-- quartz调度框架自带的表

SELECT * FROM qrtz_scheduler_state;

SELECT * FROM qrtz_cron_triggers;

SELECT * FROM qrtz_simple_triggers

SELECT * FROM qrtz_triggers;

SELECT * FROM qrtz_job_details;

a19f934f851f0d63cb7f111422b4bdc8.png

9963e35320038a15aa4292179d08c086.png

创建springboot项目

568ed247e3e3085806c3968a1ca30c6a.png

pom依赖

org.quartz-scheduler

quartz-jobs

2.2.1

com.alibaba

druid-spring-boot-starter

1.1.10

src/main/java

**/*.xml

src/main/resources

*.properties

*.xml

*.yml

org.mybatis.generator

mybatis-generator-maven-plugin

1.3.2

mysql

mysql-connector-java

${mysql.version}

true

配置application.yml

server:

servlet:

context-path: /

port: 80

spring:

datasource:

#1.JDBC

type: com.alibaba.druid.pool.DruidDataSource

driver-class-name: com.mysql.jdbc.Driver

url: jdbc:mysql://localhost:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8

username: root

password: 123

druid:

#2.\u8FDE\u63A5\u6C60\u914D\u7F6E

#\u521D\u59CB\u5316\u8FDE\u63A5\u6C60\u7684\u8FDE\u63A5\u6570\u91CF \u5927\u5C0F\uFF0C\u6700\u5C0F\uFF0C\u6700\u5927

initial-size: 5

min-idle: 5

max-active: 20

#\u914D\u7F6E\u83B7\u53D6\u8FDE\u63A5\u7B49\u5F85\u8D85\u65F6\u7684\u65F6\u95F4

max-wait: 60000

#\u914D\u7F6E\u95F4\u9694\u591A\u4E45\u624D\u8FDB\u884C\u4E00\u6B21\u68C0\u6D4B\uFF0C\u68C0\u6D4B\u9700\u8981\u5173\u95ED\u7684\u7A7A\u95F2\u8FDE\u63A5\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2

time-between-eviction-runs-millis: 60000

# \u914D\u7F6E\u4E00\u4E2A\u8FDE\u63A5\u5728\u6C60\u4E2D\u6700\u5C0F\u751F\u5B58\u7684\u65F6\u95F4\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2

min-evictable-idle-time-millis: 30000

validation-query: SELECT 1 FROM DUAL

test-while-idle: true

test-on-borrow: true

test-on-return: false

# \u662F\u5426\u7F13\u5B58preparedStatement\uFF0C\u4E5F\u5C31\u662FPSCache \u5B98\u65B9\u5EFA\u8BAEMySQL\u4E0B\u5EFA\u8BAE\u5173\u95ED \u4E2A\u4EBA\u5EFA\u8BAE\u5982\u679C\u60F3\u7528SQL\u9632\u706B\u5899 \u5EFA\u8BAE\u6253\u5F00

pool-prepared-statements: true

max-pool-prepared-statement-per-connection-size: 20

# \u914D\u7F6E\u76D1\u63A7\u7EDF\u8BA1\u62E6\u622A\u7684filters\uFF0C\u53BB\u6389\u540E\u76D1\u63A7\u754C\u9762sql\u65E0\u6CD5\u7EDF\u8BA1\uFF0C'wall'\u7528\u4E8E\u9632\u706B\u5899

filter:

stat:

merge-sql: true

slow-sql-millis: 5000

#3.\u57FA\u7840\u76D1\u63A7\u914D\u7F6E

web-stat-filter:

enabled: true

url-pattern: /*

#\u8BBE\u7F6E\u4E0D\u7EDF\u8BA1\u54EA\u4E9BURL

exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"

session-stat-enable: true

session-stat-max-count: 100

stat-view-servlet:

enabled: true

url-pattern: /druid/*

reset-enable: true

#\u8BBE\u7F6E\u76D1\u63A7\u9875\u9762\u7684\u767B\u5F55\u540D\u548C\u5BC6\u7801

login-username: admin

login-password: admin

allow: 127.0.0.1

#deny: 192.168.1.100

#\u663E\u793A\u65E5\u5FD7

logging:

level:

com.lingerqi.quartz02.mapper: debug

Quartz02Application.java前面加上以下注解:

@MapperScan("com.lingerqi.quartz02.mapper")

@EnableTransactionManagement

@EnableScheduling

@SpringBootApplication

generatorConfig.xml

/p>

"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >

connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>

targetProject="src/main/java">

targetProject="src/main/java">

targetProject="src/main/java" type="XMLMAPPER">

enableCountByExample="false" enableDeleteByExample="false"

enableSelectByExample="false" enableUpdateByExample="false">

enableCountByExample="false" enableDeleteByExample="false"

enableSelectByExample="false" enableUpdateByExample="false">

ScheduleTriggerMapper.java

/**

* 查询触发器中包含的所有任务

* @return

*/

List queryScheduleTriggerLst();

ScheduleTriggerParamMapper.java

/**

* 查询出当前任务类对应所需的参数

* @param triggerId

* @return

*/

List queryScheduleParamLst(Integer triggerId);

spring自带定时任务作业类ScheduleTriggerServiceImpl.java

package com.lingerqi.quartz02.service.impl;

import com.lingerqi.quartz02.entity.ScheduleTrigger;

import com.lingerqi.quartz02.entity.ScheduleTriggerParam;

import com.lingerqi.quartz02.mapper.ScheduleTriggerMapper;

import com.lingerqi.quartz02.mapper.ScheduleTriggerParamMapper;

import org.quartz.*;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Service;

import java.util.List;

@Service

public class ScheduleTriggerServiceImpl {

@Autowired

private ScheduleTriggerMapper scheduleTriggerMapper;

@Autowired

private ScheduleTriggerParamMapper scheduleTriggerParamMapper;

@Autowired

private Scheduler scheduler;

@Scheduled(cron = "0/10 * * * * ?")

public void refreshScheduler(){

try {

List scheduleTriggers =

scheduleTriggerMapper.queryScheduleTriggerLst();

if(null!=scheduleTriggers){

for (ScheduleTrigger scheduleTrigger : scheduleTriggers) {

String cron = scheduleTrigger.getCron(); //表达式

String jobName = scheduleTrigger.getJob_name(); //任务名称

String jobGroup = scheduleTrigger.getJob_group(); //任务分组

String status = scheduleTrigger.getStatus(); //任务状态

//JobName+JobGroup=Primary Key

//根据jobName和jobGroup生成TriggerKey

TriggerKey triggerKey =

TriggerKey.triggerKey(jobName, jobGroup);

//根据TriggerKey到Scheduler调度器中获取触发器

CronTrigger cronTrigger = (CronTrigger)

scheduler.getTrigger(triggerKey);

if(null==cronTrigger){

if(status.equals("0"))

continue;

System.out.println("创建调度器");

//创建任务详情

JobDetail jobDetail=

JobBuilder.newJob((Class extends Job>) Class.forName(jobName))

.withIdentity(jobName,jobGroup)

.build();

//往Job任务中传递参数

JobDataMap jobDataMap = jobDetail.getJobDataMap();

List params =

scheduleTriggerParamMapper.queryScheduleParamLst(scheduleTrigger.getId());

for (ScheduleTriggerParam param : params) {

jobDataMap.put(param.getName(),param.getValue());

}

//创建表达式调度器

CronScheduleBuilder cronSchedule =

CronScheduleBuilder.cronSchedule(cron);

//创建Trigger

cronTrigger=TriggerBuilder.newTrigger()

.withIdentity(jobName,jobGroup)

.withSchedule(cronSchedule)

.build();

//将jobDetail和Trigger注入到scheduler调度器中

scheduler.scheduleJob(jobDetail,cronTrigger);

}else{

//System.out.println("Quartz 调度任务中已存在该任务");

if(status.equals("0")){

JobKey jobKey = JobKey.jobKey(jobName, jobGroup);

scheduler.deleteJob(jobKey);

continue;

}

//调度器中的表达式

String cronExpression =

cronTrigger.getCronExpression();

if(!cron.equals(cronExpression)){

//创建表达式调度器

CronScheduleBuilder cronSchedule =

CronScheduleBuilder.cronSchedule(cron);

//重构

cronTrigger=cronTrigger.getTriggerBuilder()

.withIdentity(triggerKey)

.withSchedule(cronSchedule)

.build();

//刷新调度器

scheduler.rescheduleJob(triggerKey,cronTrigger);

}

}

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

读取数据库中表达式启动定时任务

数据库表t_schedule_trigger配置

440538543440131755e9eaff6834597b.png

MyJob.java

package com.lingerqi.quartz02.quartz;

import lombok.extern.slf4j.Slf4j;

import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import org.springframework.stereotype.Component;

import java.util.Date;

@Component

@Slf4j

public class MyJob implements Job {

@Override

public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

System.out.println("MyJob是一个空的任务计划,时间:"+new Date().toLocaleString());

}

}

c2af16995d0d7f73b1b1c0b8eca0e48d.png

Spring自带定时任务每10s执行一次,查询自定义触发器表,获取到具体的作业类及任务表达式,quartz的任务为每5s执行一次,所以打印如上

更改定时任务状态

更改数据库调度器表t_schedule_trigger的state状态

当禁用该触发器时,那么程序只会执行spring自带的定时任务,每10s执行一次查询

定时任务中携带参数

39d9a061b185dfc29cbc8ed495ed1fd5.png

MyJob1

@Component

@Slf4j

public class MyJob1 implements Job {

@Autowired

private ScheduleTriggerParamService scheduleTriggerParamService;

@Override

public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

JobDetail jobDetail =

jobExecutionContext.getJobDetail();

JobDataMap jobDataMap = jobDetail.getJobDataMap();

System.out.println(new Date().toLocaleString()+"-->携带参数个数:"+jobDataMap.size());

}

}

15e621ea95921776ba94919b1971f6a9.png

程序执行spring自带的定时任务,每10s执行一次查询,查询t_schedule_trigger表,调度器表中有两个调度器,都是每5s执行一次,其中一个调度器是需要携带参数的,携带的参数在t_schedule_trigger_param表中,所以一开始调度器启动的时候需要查询t_schedule_trigger_param表数据,最终打印语句如上。

更改定时任务规则

MyJob2.java

@Component

@Slf4j

public class MyJob2 implements Job{

@Override

public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

JobDetail jobDetail =

jobExecutionContext.getJobDetail();

JobDataMap jobDataMap = jobDetail.getJobDataMap();

System.out.println(new Date().toLocaleString()+"-->MyJob2参数传递name="+jobDataMap.get("name")+",score="+

jobDataMap.get("score"));

}

}

0aa78e9157174a578964af7b44e1cc68.png

程序执行spring自带的定时任务,每10s执行一次查询,查询t_schedule_trigger表,将任务3的表达式由0/3 * * * * ?改成0/20 * * * * ?,最终结果如上

@Component

@Slf4j

public class MyJob2 implements Job{

@Override

public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

JobDetail jobDetail =

jobExecutionContext.getJobDetail();

JobDataMap jobDataMap = jobDetail.getJobDataMap();

System.out.println(new Date().toLocaleString()+"-->MyJob2参数传递name="+jobDataMap.get("name")+",score="+

jobDataMap.get("score"));

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CodeForces - 1062C】Banh-mi (贪心,数学,找规律,快速幂)

题干&#xff1a; JATC loves Banh-mi (a Vietnamese food). His affection for Banh-mi is so much that he always has it for breakfast. This morning, as usual, he buys a Banh-mi and decides to enjoy it in a special way. First, he splits the Banh-mi into nn pa…

【牛客 - 练习】约数个数的和(数论,数学)

题干&#xff1a; 给个n&#xff0c;求1到n的所有数的约数个数的和~ 输入描述: 第一行一个正整数n 输出描述: 输出一个整数&#xff0c;表示答案 示例1 输入 复制 3 输出 复制 5 说明 样例解释&#xff1a; 1有1个约数1 2有2个约数1,2 3有2个约数1,3 备注: n…

mysql json 创建索引_MySQL · 最佳实践 · 如何索引JSON字段

概述MySQL从5.7.8起开始支持JSON字段&#xff0c;这极大的丰富了MySQL的数据类型。也方便了广大开发人员。但MySQL并没有提供对JSON对象中的字段进行索引的功能&#xff0c;至少没有直接对其字段进行索引的方法。本文将介绍利用MySQL 5.7中的虚拟字段的功能来对JSON对象中的字段…

mysql链路跟踪工具_EasySwoole利用链路追踪组件制作甩锅工具

前言最近前端老是反馈API调用异常&#xff0c;说请求成功但是没有数据返回&#xff01;我写的代码怎么可能有bug&#xff0c;肯定是前端调用的方式不对&#xff01;经过一番套鼓&#xff0c;直接把请求参数和响应内容打印到控制台&#xff0c;果然不出我所料&#xff0c;请求缺…

【CCFCSP- 201312-4】有趣的数(线性dp)

题干&#xff1a; 试题编号&#xff1a;201312-4试题名称&#xff1a;有趣的数时间限制&#xff1a;1.0s内存限制&#xff1a;256.0MB问题描述&#xff1a; 问题描述   我们把一个数称为有趣的&#xff0c;当且仅当&#xff1a;   1. 它的数字只包含0, 1, 2, 3&#xff0c…

java selector 源码_Java NIO核心组件-Selector和Channel

昨天我们介绍了一下SelectorProvider和IO multiplexing.特别是IO multiplexing中的epoll系统调用,是Linux版本的Java的NIO的核心实现.那今天我们就来介绍一下, Java NIO中的核心组件, Selector和Channel.这两个组件,对于熟悉Java OIO,而不熟悉Java NIO的朋友来说,理解其作用是极…

【HDU - 1542】Atlantis (线段树,扫描线)

题干&#xff1a; There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend…

python 底层原理processpoolexecutor_python 多进程并行编程 ProcessPoolExecutor的实现

使用 ProcessPoolExecutorfrom concurrent.futures import ProcessPoolExecutor, as_completedimport random斐波那契数列当 n 大于 30 时抛出异常def fib(n):if n > 30:raise Exception(can not > 30, now %s % n)if n < 2:return 1return fib(n-1) fib(n-2)准备数组…

【HDU - 5700】【51nod - 1672】 区间交(贪心,STLset 或线段树第k大)

题干&#xff1a; 小A有一个含有n个非负整数的数列与m个区间&#xff0c;每个区间可以表示为li,ri。 它想选择其中k个区间&#xff0c; 使得这些区间的交的那些位置所对应的数的和最大。&#xff08;是指k个区间共同的交&#xff0c;即每个区间都包含这一段&#xff0c;具体可…

python 爬虫 博客园_Python爬虫爬取博客园作业

分析一下他们的代码&#xff0c;我在浏览器中对应位置右键&#xff0c;然后点击检查元素&#xff0c;可以找到对应部分的代码。但是&#xff0c;直接查看当前网页的源码发现&#xff0c;里面并没有对应的代码。我猜测这里是根据服务器上的数据动态生成的这部分代码&#xff0c;…

【洛谷 - P1507 】NASA的食物计划(二维费用背包,dp)

题干&#xff1a; 题目背景 NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安全技术问题一直大伤脑筋,因此在各方压力下终止了航天飞机的历史,但是此类事情会不会在以后发生&#xff0c;谁也无法保证,在遇到这类航天问题时,解决方法也许只能让航天员出仓维修,但是多次的维修…

java 与 xml_xml与java对象转换

public static void main(String[] args) {//java bean 转 xmlDept d new Dept();List staffs new ArrayList<>();Staff s1 new Staff("wuyun", 20);Staff s2 new Staff("lilei", 22);staffs.add(s1);staffs.add(s2);d.setDeptName("开放平…

【蓝桥杯官网试题 - 算法训练 】P0502(乱搞,tricks)

题干&#xff1a; 编写一个程序&#xff0c;读入一组整数&#xff0c;这组整数是按照从小到大的顺序排列的&#xff0c;它们的个数N也是由用户输入的&#xff0c;最多不会超过20。然后程序将对这个数组进行统计&#xff0c;把出现次数最多的那个数组元素值打印出来。如果有两个…

python循环中的else_python 循环中else的简单示例

导读热词对python这个高级语言感兴趣的小伙伴&#xff0c;下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧&#xff01;众多语言中都有if else这对条件选择组合&#xff0c;但是在python中还有更多else使用的地方&#xff0c;比如说循环for&#xff0c;或者while都可以和els…

【蓝桥杯官网试题 -算法训练】素因子去重(数学,数论,因子约数)

题干&#xff1a; 问题描述 给定一个正整数n&#xff0c;求一个正整数p&#xff0c;满足p仅包含n的所有素因子&#xff0c;且每个素因子的次数不大于1 输入格式 一个整数&#xff0c;表示n 输出格式 输出一行&#xff0c;包含一个整数p。 样例输入 1000 样例输出 10 数…

【蓝桥杯官网试题 - 算法提高】 贪吃的大嘴 (多重背包转0-1背包,dp)

题干&#xff1a; 问题描述 有一只特别贪吃的大嘴,她很喜欢吃一种小蛋糕,而每一个小蛋糕有一个美味度,而大嘴是很傲娇的,一定要吃美味度和刚好为m的小蛋糕,而且大嘴还特别懒,她希望通过吃数量最少的小蛋糕达到这个目的.所以她希望你能设计一个程序帮她决定要吃哪些小蛋糕. 输…

java applet socket_Java swing applet中使用的套接字

小编典典基于此示例&#xff0c;这是一个使用Swing的简单网络客户端/服务器对。请注意与正确同步有关的一些问题&#xff1a;GUI本身是使用事件分配线程构建的invokeLater()。此外&#xff0c;代码还依赖的线程安全性append()。最后&#xff0c;它结合了文章Text Area Scrollin…

【牛客 - 370A】签到题(线段树扫描线 或 STLset)(求线段并)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/370/A 来源&#xff1a;牛客网 恭喜你找到了本场比赛的签到题&#xff01; 为了让大家都有抽奖的机会&#xff0c;只需要复制粘贴以下代码&#xff08;并且稍微填下空&#xff09;即可 AC&#xff1…

java sqlserver分页查询_SQLServer之常用的分页查询语句介绍

在SqlServer中&#xff0c;分页查询是经常用到的查询语句&#xff0c;一个好的分页查询语句&#xff0c;不能能将代码省略&#xff0c;还能提高运行效率&#xff0c;下面我们来探讨一下SQLServer中的分页查询语句。具体的业务逻辑是这样的&#xff0c;我数据库中有100条数据&am…

【牛客 - 370H】Rinne Loves Dynamic Graph(分层图最短路)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/370/H 来源&#xff1a;牛客网 Rinne 学到了一个新的奇妙的东西叫做动态图&#xff0c;这里的动态图的定义是边权可以随着操作而变动的图。 当我们在这个图上经过一条边的时候&#xff0c;这个图上所…