读MySQL数据库数据字段时间多了8小时

背景:使用Java程序的java.util.Date类型读取出MySQL中的Timestamp的值时发现大了8小时。

百度了下设置MySQL的时区,如下:

set global time_zone = '+8:00';##修改mysql全局时区为北京时间,即我们所在的东8区
set time_zone = '+8:00';##修改当前会话时区
flush privileges; #立即生效
show variables like "%time_zone%";

但是未能解决。又继续查看代码中的数据库连接。发现一处地方可能是问题的原因。

多了8小时的连接设置:?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

注意到可能是这个serverTimezone的问题,将其修改为serverTimezone=Asia/Shanghai ,再试一下,擦搞定了。赶紧记下来,于是有了这篇笔记。

多线程处理任务后,继续主线程任务

业务场景:获取三个表数据,发送至三个接口,响应后删除表数据

1 读取三张表数据


/**
 * 获取所有表数据
 */
private void getAllTableData(String curentTime, JSONArray requestArray) {
       List<DeviceStatus> deviceStatusList = getDeviceStatusLists(curentTime);
        int deviceStatusListSize = 0;
        if (!CollectionUtils.isEmpty(deviceStatusList)) {
            JSONObject json = new JSONObject();
            json.put("url", deviceStatusUrl);
            JSONObject param = new JSONObject();
            param.put("list", deviceStatusList);
            json.put("data", param);
            requestArray.add(json);
            deviceStatusListSize = deviceStatusList.size();
        }
        logger.info("deviceBriefStatusList-size:{}", deviceBriefStatusListSize);
        //***另外两张表
 }

2 将数据发送到线程里

public void executeScheduleTask() {
	String curentTime = DateUtils.getNowText();
	logger.info("操作时间:{}", curentTime);
   /*
    数据和请求地址放入到requestArray中
   */
    JSONArray requestArray = new JSONArray();
    getAllTableData(curentTime, requestArray);

    if (!CollectionUtils.isEmpty(requestArray)) {
        //申明线程池
        ExecutorService exc = Executors.newFixedThreadPool(requestArray.size());
        //申明数据毁掉处理类List<Future<JSONObject>>
        List<Future<JSONObject>> futures = new ArrayList<>();
        for (int i = 0; i < requestArray.size(); i++) {
            JSONObject json = requestArray.getJSONObject(i);
            //申请单个线程执行类
            DataHandleRequest call = new DataHandleRequest(json);
            //提交单个线程
            Future<JSONObject> future = exc.submit(call);
            //将每个线程放入线程集合,这里如果任何一个线程的执行结果没有毁掉,线程后都会自动堵塞
            futures.add(future);
        }
        //所有线程执行完毕之后会执行下面的循环,然后通过循环每个线程后执行线程的get()方法,每个线程的执行结果

        List<String> succList = new ArrayList<>();
        try {
            for (Future<JSONObject> future : futures) {
                JSONObject json = future.get();
                String returnData = json.getString("returnData");
                JSONObject valueJson = JSONObject.parseObject(returnData);
                if (valueJson.containsKey("code") && "000000".equals(valueJson.getString("code"))) {
                    succList.add(valueJson.getString("data"));
                }
                logger.info("同步调用结果:{}", returnData);
            }
            exc.shutdown();
        } catch (Exception e) {
            logger.error("同步数据失败:{}", e);
        }
        //删除已同步数据表
        deleteTable(curentTime, succList);
    }

  
    logger.info("同步数据表结束,耗时:cost={}ms", cost);
}

3数据发送,创建一个执行线程任务类DataHandleRequest 继续阅读多线程处理任务后,继续主线程任务

1267 – Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation

MySQL在做表关联查询,报错,信息如下

1267 - Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '='

报错原因:字段间的编码格式不一致;

1查看表字符编码,会显示建表的字符编码

sql>show create table t_user_device_relation;

2 设置字段编码,如设置为utf8_general_ci

sql>ALTER TABLE t_user_device_relation MODIFY COLUMN id VARCHAR(32) CHARACTER SET utf8_general_ci COLLATE utf8_unicode_ci;

备注:设置没有用,使用navicat直接修改,也没成功;就直接重新建表,导入数据,OK!

MySQL编写触发器

触发器语法示例:

CREATE TRIGGER trigger_name trigger_time trigger_event ON tb_name FOR EACH ROW trigger_stmt
trigger_name:触发器的名称
tirgger_time:触发时机,为BEFORE或者AFTER
trigger_event:触发事件,为INSERT、DELETE或者UPDATE
tb_name:表示建立触发器的表明,就是在哪张表上建立触发器
trigger_stmt:触发器的程序体,可以是一条SQL语句或者是用BEGIN和END包含的多条语句
所以可以说MySQL创建以下六种触发器:
BEFORE INSERT,BEFORE DELETE,BEFORE UPDATE
AFTER INSERT,AFTER DELETE,AFTER UPDATE

创建多个执行语句的触发器:

CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
ON 表名 FOR EACH ROW
BEGIN
    执行语句列表(用分号隔开)
END

如表:t_device_status_info

1 创建触发器

CREATE TRIGGER t_device_status_info_update 
AFTER UPDATE on t_device_status_info FOR EACH ROW
BEGIN
	insert into t_device_status_info_tmp_modify
		(id, device_id, `name`, `value`, state,
		create_time, update_time)
	values 
		(new.id, new.device_id, new.name, new.value, new.state,
		new.create_time, new.update_time);
END;

补充插入或更新

replace into t_device_status_info_tmp_modify
(id, device_id, `name`, `value`, state,
create_time, update_time)
values
(new.id, new.device_id, new.name, new.value, new.state,
new.create_time, new.update_time);

2 创建一个删除表操作的触发器

CREATE TRIGGER t_device_status_info_del 
BEFORE DELETE on t_device_status_info FOR EACH ROW
BEGIN
	insert into t_device_status_info_tmp_del
		(id, device_id, name, value, state,
		create_time, update_time)
	values 
		(old.id, old.device_id, old.name, old.value, old.state,
		old.create_time, old.update_time);
END;

3 查看触发器 继续阅读MySQL编写触发器

Springboot配置注入静态属性

1 application.properties配置文件:

http.config.connectTimeout=300000
http.config.readTimeout=300000

 

2 使用静态set方法注入:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component(value = "HttpConfig")
@ConfigurationProperties("http.config")
public class HttpConfig {

    public static int readTimeout;

    public static int connectTimeout;

    @Value("${http.config.readTimeout}")
    public static void setReadTimeout(int readTimeout) {
        HttpConfig.readTimeout = readTimeout;
    }

    @Value("${http.config.connectTimeout}")
    public static void setConnectTimeout(int connectTimeout) {
        HttpConfig.connectTimeout = connectTimeout;
    }

    public static int getReadTimeout() {
        return readTimeout;
    }

    public static int getConnectTimeout() {
        return connectTimeout;
    }
}

 

3 静态类调用 继续阅读Springboot配置注入静态属性

SpringBoot发送一个Form数据的post请求

通过post发送一个Form格式的数据请求,示例代码如下:

METHOD:POST
Content-Type:application/x-www-form-urlencoded

private String sendPostFormRequest(MultiValueMap<String, String> params) {
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        HttpMethod method = HttpMethod.POST;
        //表单方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        ResponseEntity<String> response = client.exchange(tokenUrl, method, requestEntity, String.class);
        return response.getBody();
    }

导入的包import org.springframework.*;

调用sendPostFormRequest继续阅读SpringBoot发送一个Form数据的post请求

ES实现分组查询Java API

需要对ES中的数据先过滤查询,然后分组统计,现将本人的示例代码贴在下,希望对你有用(搜索中加聚合)

/**
 * 组合查询条件:
 * 类似sql语句 select deviceId, count(1) from table where code = '0' group by deviceId
 */
private BoolQueryBuilder getSearchBuilder(Log log) {
	BoolQueryBuilder searchBuilder = transportClient.prepareSearch();
	BoolQueryBuilder builder = QueryBuilders.boolQuery();
	//类型sql的where条件
	if (!StringUtils.isBlank(log.getDeviceId())) {
        builder.must(QueryBuilders.matchQuery("deviceId",log.getDeviceId()));
    }
    if (!StringUtils.isBlank(log.getCode())) {
        if (SUCCESS.equals(log.getCode())) {
            //查询所有的请求成功的数据                		
            builder.must(QueryBuilders.matchQuery(“code”,log.getCode()));
        } else {
            //查询所有的失败的数据
            builder.mustNot(QueryBuilders.matchQuery("code", SUCCESS));
        }
    }
    //请求开始时间和请求结束时间
    String stmStart = log.getStmStart();
    String stmEnd = log.getStmEnd();

    if (!StringUtils.isBlank(stmStart) || !StringUtils.isBlank(stmEnd)) {
        stmStart = StringUtils.isBlank(stmStart) ? stmStart : stmStart + ZERO;
        stmEnd = StringUtils.isBlank(stmEnd) ? stmEnd : stmEnd + ZERO;
        rangeBuilder rangeBuilder = QueryBuilders.rangeQuery(STM);
        rangeBuilder.from(stmStart);
        rangeBuilder.to(stmEnd);
        builder.must(rangeBuilder);
    }

    searchBuilder.setQuery(builder);
    //添加分组,deviceCount为别名,deviceId为要分组的字段
    //200000为最大的分组显示条数,默认为10条
    SearchRequestBuilder termsBuilder = AggregationBuilders.terms("deviceCount").field(“deviceId”).size(200000);
    searchBuilder.addAggregation(termsBuilder);

    //此处用于使用聚合函数分页无效,需手动分页
    /*
    Integer pageNo = log.getPage();
    Integer limit = log.getLimit();
    if (null != pageNo && null != limit) {
    searchBuilder.setFrom((pageNo -1) * limit).setSize(limit);
    }
    */
    return searchBuilder;
}

 

获取查询分组后数据 继续阅读ES实现分组查询Java API

离职社保公积金问题

背景:南京离职到合肥工作

社保:
转移前需要原单位将社保进行停保,同时在合肥需要有社保账户并已缴纳社保一月,然后去南京的社保局办理社保转出。
地址:南京市中华路505号,秦淮区社保中心
材料:本人身份证,本人的银行卡(持卡人是本人)
时间:每个月的5-25号,工作时间通常是8:30-11:30/13:30-17:00
操作:取号,柜台办理,然后会给到你两个单子,一个黄色,一个白色,将单子给到现在合肥的公司人事,合肥的人事会让你填写转移申请表,填写后,合肥的单位人事会帮到你办理。

公积金: 继续阅读离职社保公积金问题

kafka2ES索引

背景:

给日志中增加了新的属性,需要新建索引,以便让新的索引生效,同时将旧索引指向到新索引中。

1 新建索引和属性(包含原已存在属性)脚本如csindex.sh,内容如下 :

curl -XPUT 'http://ip:9200/newindex-2018-03?pretty' -d
'{	
	"settings":{
		"number_of_shards":5,
		"number_of_replicas":1
	},
	"mappings": {
		"xxPlatformLog": { 
			"_all": { "enabled": true },                         	
			"properties": { 				
				"uid":{"type":"string","index":"not_analyzed","store":"yes"},
				"account":{"type":"string","index":"not_analyzed","store":"yes"},
				"respkg":{"type":"string","index":"analyzed","store":"yes"}
			}
		}
	}
}'

2 删除旧索引,指向添加新索引

curl -XPOST http://xx:9202/_aliases -d'{"actions":[{"remove":{"index":"oldindex-2018-02","alias":"indexaliases"}},{"add":{"index":"newindex-2018-03","alias":"indexaliases"}}] }'