synchronized修饰的作用:
让多个线程排队依次获取某个资源,保证数据不会出错(原子性)。
synchronized锁定的元素:
/**
* 根据hash中的键模糊删除
* @param key key redis的key
* @param item item hash的键
*/
public void removeHashItem(String key, String item){
ArrayList<String> items = new ArrayList<>();
// 模糊查询出准确的item
redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
Cursor<Map.Entry<byte[], byte[]>> entryCursor = connection.hScan(key.getBytes(), ScanOptions.scanOptions().match("*" + item + "*").count(1800).build());
while(entryCursor.hasNext()){
Map.Entry<byte[], byte[]> next = entryCursor.next();
String key = new String(next.getKey());
// 将查询出的item放入list
items.add(key);
}
connection.close();
return null;
}
});
// 批量删除对应key中的item
for (String str: items){
redisTemplate.opsForHash().delete(key, str);
}
}
每条字句都使用order by会报错。
方法一:只在最后一条字句使用order by,意思是对整个结果集进行order by
参考代码如下:
select * from t1 where username like 'l%'
union
select * from t1 where username like '%m%'
order by score asc
方法二:union后整体改为临时表
参考代码如下:
select * from
(select * from t1 where username like 'l%'
union
select * from t1 where username like '%m%')tmp
order by tmp.score asc
方法三:每一层都改为临时表再union
select * from (select * from t1 where username like 'l%') t1
union
select * from (select * from t1 where username like '%m%') t2
order by score asc
参考代码:
spring:
application:
name: innovation
cloud:
config:
name: reward-innovation-v1,common
profile: test
uri: http://10.12.7.124:8888
failFast: true
enabled: true
main.allow-bean-definition-overriding: true
该代码读取配置中心的common-test.yml和reward-innovation-v1-test.yml文件
查重管理的时候,在测试环境碰到一模一样的问题。
1、jps命令查看当前进程id
[award_dev@localhost reward_taskjob]$ jps -l
32496 reward-taskjob-202209151113-SNAPSHOT.jar
4931 award-webbas-config-2022-08-29-122959.jar
3187 reward-innovation-202209172040-SNAPSHOT.jar
2、jinfo -flags 进程id 命令查看当前进程使用的JVM参数
[award_dev@localhost reward_taskjob]$ jinfo -flags 32496
Attaching to process ID 32496, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13
Non-default VM flags: -XX:CICompilerCount=12 -XX:ConcGCThreads=3 -XX:G1HeapRegionSize=1048576 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=null -XX:InitialHeapSize=1289748480 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=2147483648 -XX:MaxNewSize=1287651328 -XX:MinHeapDeltaBytes=1048576 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC
Command line: -Dlog4j2.formatMsgNoLookups=true -DENV_CONFIG_IP=10.12.7.181 -DENV_CONFIG_PORT=9888 -DENV_TYPE=dev -Dname=reward-taskjob-202209151113-SNAPSHOT.jar -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Duser.timezone=Asia/Shanghai -Djava.io.tmpdir=/opt/aspire/product/award_dev/reward_taskjob/data/tmp -Xms1230m -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./logs/java_heapdump.hprof -XX:+PrintGCDateStamps -Xloggc:/opt/aspire/product/award_dev/reward_taskjob/logs/gclog/gc-reward-taskjob-202209151113-SNAPSHOT.jar-20220919102315.log -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+UseG1GC
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
直接通过服务名调用,Eureka会去找。
restTemplate.postForObject("http://webbas32-manage-v1/web/login/findemployeebyphone", formEntity, String.class);
其中webbas32-manage-v1为接口提供方的服务名
调用方的Eureka配置需要添加,fetchRegistry: true //表示可以从Eureka Server获取注册的服务信息
问题:

如上图所示,data类型本应该为MemberInfoVo,但是泛型丢失变为LinkedHashMap。
解决方法:
参考代码如下:
ParameterizedTypeReference<ResponseMsg<MemberInfoVo>> typeRef = new ParameterizedTypeReference<ResponseMsg<MemberInfoVo>>() {};
ResponseEntity<ResponseMsg<MemberInfoVo>> result = restTemplate.exchange(findEmployeeUrl, HttpMethod.POST, formEntity, typeRef);
ResponseMsg<MemberInfoVo> responseMsg = result.getBody();
成功效果:

参考链接
SpringBoot的默认使用的日志框架为logback,且默认的日志级别均为INFO。
为了打印sql日志信息,我们只需把对应dao层包下的日志级别改为DEBUG。
示例代码如下:
# log
logging:
config: classpath:log4j2-dev.xml
level:
root: info
# dao层包下的日志级别修改
com:
aspirecn:
rewardmanagement:
mapper: debug
1、通过git status命令查看信息(关键):
All conflicts fixed but you are still merging(use “git commit” to conclude merge)
2、根据第一步的信息提示做操作
示例操作如下:
git add -A
git commit -m '合并master'
配置文件代码:
myList: item1,item2,item3
myMap: "{key1: 'value1', key2: 'value2'}"
Java代码:
@Value("#{'${myList}'.split(',')}")
private List<String> myList;
@Value("#{${myMap}}")
private Map<String,String> myMap;
注意:
上面的list配置中,一定不要用""把list所有的成员value包起来,要不然解析报错。
上面的map配置中,一定要用"" 把map所对应的value包起来,要不然解析解析报错。
多个ControllerAdvice,优先级由@Order决定,order的数值越小 则优先级越高。
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MsControllerAdvice {
}
注意:@ControllerAdvice只能对controller抛出的异常处理
多个@ControllerAdvice全局异常处理(含多个实用场景)、
@ControllerAdvice优先级设定
示例代码:
zuul:
routes:
api-a:
path: /api-a/**
serviceId: service-ribbon
api-b:
path: /api-b/**
serviceId: service-feign
zuul路由配置说明:api-a、api-b是路由名称可以随便取,serviceId是服务的id(对应spring.application.name)。
上面配置表示,以/api-a/ 开头的请求都转发给service-ribbon服务;以/api-b/开头的请求都转发给service-feign服务。
zuul可以自动根据Eureka服务器中所注册的服务自动完成路由映射、负载均衡。
在Eureka上注册了两个服务:
1、服务名management,端口18081
2、服务名gateway,端口7001
请求路径,127.0.0.1:7001/management/addressBook/getList,网关zuul会把请求转发给management服务,
实际请求路径127.0.0.1:18081/addressBook/getList
在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器。
jar的版本判断的两种途径:
示例代码如下:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>3.2.7version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
dependency>
dependencies>