工作之余,总结了下Java8的相关运用,主要是关于Stream流的。还有一些工作总结笔记。

Java8
Java8

Stream流操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//map集合获取value 获取新方式
map.getOrDefault(goodsId, 0L)
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue;
}
//flatMap使用
List<OrderSetDetail> setDetails = order.getDetails().stream()
.filter(x -> CollectionUtils.isNotEmpty(x.getOrderSetDetails()))
.flatMap(orderDetail -> orderDetail.getOrderSetDetails().stream())
.collect(Collectors.toList());
//distinct
distinct主要用来去重,以下代码片段使用 distinct 对元素进行去重:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
numbers.stream().distinct().forEach(System.out::println);
//3,2,7,5
//groupingBy&count分组统计
Map<String, Long> collect = lists.stream().collect(Collectors
.groupingBy(Student::getName, Collectors.counting()));
//Java8 Map集合遍历
Map<String, Integer> updateStockMap = Optional.ofNullable(updateActivityStockList).orElseGet(ArrayList::new)
.stream().collect(Collectors.groupingBy(UpdateActivityStock::getId,
Collectors.reducing(Integer.valueOf(0), UpdateActivityStock::getStock, Integer::sum)));
updateStockMap.forEach((id, stockNum) -> {
ActivityStock oldStock = stockMap.get(id);
if (oldStock != null) {
ActivityStock stock = new ActivityStock();
stock.setId(id);
stock.setStock(stockNum);
}
});
//Java8 Map集合遍历2
public class IterateHashMapExample {
public static void main(String[] args) {
Map < Integer, String > coursesMap = new HashMap < Integer, String > ();
coursesMap.put(1, "C");
coursesMap.put(2, "C++");
coursesMap.put(3, "Java");
coursesMap.put(4, "Spring Framework");
coursesMap.put(5, "Hibernate ORM framework");
// 5. 使用 Stream API 遍历 HashMap
coursesMap.entrySet().stream().forEach((entry) - > {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
});
}
}
// java8之后。上面的操作可以简化为一行,若key对应的value为空,会将第二个参数的返回值存入并返回
Object key2 = map.computeIfAbsent("key", k -> new Object());
//相当于:
if(map.get("key") == null) {
map.put("key", new Object());
}
//List转Map(key去重)
Map<String, Student> studentMap = list1.stream().collect(Collectors.toMap(Student::getName, value -> value, (a1, a2) -> a1));

Example条件查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public Activity getEffectiveActivity() {
Date now = new Date();
Example example = new Example(Activity.class);
example.createCriteria().andEqualTo("isEnable", SystemConstants.YES)
.andEqualTo("activityType", ActivityType.RUN)
.andLessThanOrEqualTo("startDate", now)
.andGreaterThanOrEqualTo("endDate", now);
List<Activity> activities = listAllByExample(example);
if(!activities.isEmpty()) {
return activities.get(0);
} else {
return null;
}
}
//单一计算
SpokesmanUser entity = new SpokesmanUser();
entity.setParentId(userId);
return this.dao.selectCount(entity);// 租户之间用户id保证唯一
//多条件统计
Example example = new Example(SpokesmanUser.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("parentId", userId);
criteria.andNotEqualTo("id", excludChildId);
return this.dao.selectCountByExample(example);// 租户之间用户id保证唯一
//sql拼接
if (query.getStartTime() != null && query.getEndTime() != null
&& query.getEndTime().after(query.getStartTime())) {
String startTime = DateTimeUtils.formatDateTime(query.getStartTime());
String endTime = DateTimeUtils.formatDateTime(query.getEndTime());
criteria.andCondition(String.format(
"((start_time >= '%s' AND '%s' >= start_time) OR ('%s' >= start_time AND end_time >= '%s') OR (end_time >= '%s' AND '%s' >= end_time))",
startTime, endTime, startTime, endTime, startTime, endTime));
}
public List<Entity> listByCsId(String csId) {
Example example = new Example(Entity.class);
example.createCriteria().andEqualTo("csId", csId)
.andEqualTo("isAssignCs", SystemConstants.YES)
.andEqualTo("isEndSession", SystemConstants.NO);
example.setOrderByClause("update_date DESC");
return this.listAllByExample(example);
}
//updateByExample使用
ChatSession updateEntity = new ChatSession();
updateEntity.setId(chatSession.getId());
updateEntity.setServiceEndDate(new Date());
updateEntity.setIsEndSession(SystemConstants.YES);
updateEntity.setRemark(remark);
updateEntity.setUpdateDate(new Date());
updateEntity.setUpdateBy(operator);
Example example = new Example(ChatSession.class);
example.createCriteria().andEqualTo("id", chatSession.getId()).andEqualTo("isEndSession", SystemConstants.NO);
int result = chatSessionRepository.updateByExample(updateEntity, example);

使用SecureRandom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
由于java.util.Random类依赖于伪随机数生成器,因此该类和相关的java.lang.Math.random()方法不应用于安全关键应用程序或保护敏感数据。 在这种情况下,应该使用依赖于加密强随机数生成器(RNG)的java.security.SecureRandom类。
PRNG(伪随机数):
伪随机数, 计算机不能生成真正的随机数,而是通用一定的方法来模拟随机数。伪随机数有一部分遵守一定的规律,另一部分不遵守任何规律。
RNG(随机数):
随机数是由“随机种子”产生的,“随机种子”是一个无符号整形数。
反例:
Random random = new Random(); // Questionable use of Random
byte bytes[] = new byte[20];
random.nextBytes(bytes);
正例:
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];

arthas命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
wget https://alibaba.github.io/arthas/arthas-boot.jar
#启动示例
java -jar arthas-boot.jar
#获取trace调用链
trace -j com.xxx.xxx.application.command.WechatLotteryRunService drawPrize '#cost > 300'
# 获取Servlet调用路径,并过滤掉JDK的函数
trace -j javax.servlet.Servlet * >> test.log
# 获取Filter调用路径,并过滤掉JDK的函数
trace -j javax.servlet.Filter * >> test.log
trace -j org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient * >> test.log
watch org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient execute "{params,target,throwExp,returnObj}" -e -x 2 -b -s -n 2
trace -j com.xxx.erp.action.autocalculate.WarehouseAction | com.xxx.erp.action.autocalculate.ExpressAction * '#cost > 100'
# 录制重放
tt -t -n 2 org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient execute
# 查看id
tt -l
# 详情
tt -i 1000
# 重放
tt -i 1000 -p
# 获取spring 容器
tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
tt -i 1000 -w 'target.getApplicationContext()'
tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'
ognl '#context=@com.yjh.mushroom.common.spring.SpringContextHolder@applicationContext, #context.getBean("idGenerator").nextId()'
# 快速排查Spring Boot应用404/401问题
stack -E javax.servlet.http.HttpServletResponse sendError|setStatus params[0]==404
# 800错误排查
watch com.xxx.xxx.framework.spring.web.GlobalExceptionHandler handleUncatchedException params[2]
#oms 异常排查
watch com.xxx.xxx.main.order.web.OrderController * "{clazz.name, params[0],throwExp}" -e -x 2
#oms调用eureka地址检查
watch com.netflix.client.ClientRequest replaceUri "params[0]"
#oms数据库连接排查
watch com.mysql.jdbc.MysqlIO doHandshake "{params[0],params[1],params[2],target.host}" -b
#oms订单任务判断
watch com.xxx.oms.sync.domain.service.PlatformDomainEventService handlePendingEvent params[0]
自动化脚本模拟并发
1
2
3
cd wrk/wrk-master/
wrk -t4 -c1000 -d60s -T10s --latency http://localhost:9016 --script=scripts/20190621/方法名.lua

时间差计算

1
long diffMinutes = ChronoUnit.MINUTES.between(Instant.now(), sendDate.toInstant());

Java8 Duration

1
2
Duration duration = Duration.ofDays(verifyDays * -1);
Instant lastValidDate = Instant.now().plus(duration);

微信接口调用实例

RestTemplate调用接口示列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
JSONObject param = new JSONObject();
param.put("type", request.getData()); // 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)
param.put("offset", (request.getPageNo() - 1) * request.getPageSize()); // 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回
param.put("count", request.getPageSize()); // 返回素材的数量,取值在1到20之间
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 处理中文乱码
ResponseEntity<String> re = restTemplate.postForEntity("https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=" + token, param, String.class);
if (HttpStatus.OK.equals(re.getStatusCode()) && re.getBody() != null) {
JSONObject result = JSONObject.parseObject(re.getBody());
if (!result.containsKey("errcode")) {
pageInfo.setTotal(result.getLong("total_count"));
List<MpMaterialVO> list = Lists.newArrayList();
JSONArray itemArr = result.getJSONArray("item");
itemArr.forEach(item -> list.add(new MpMaterialVO((JSONObject) item)));
pageInfo.setList(list);
return pageInfo;
}
}
httpclient调用实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static String sendGet(String url, PayAccountBizCodeType bizCodeType) {
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Content-Type", "application/json;charset=UTF-8");
httpGet.setHeader("Accept", "application/json");
httpGet.setHeader("User-Agent", getUserAgent());
httpGet.setHeader("Authorization", getAuthorization("GET", url, "", bizCodeType));
String result = executeRequest(httpGet);
logger.info("调用微信GET接口,url:{} ,result:{}", url, result);
return result;
}
private static String executeRequest(HttpUriRequest request) {
CloseableHttpClient client = HttpClients.createDefault();
String result = "";
try {
CloseableHttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} catch (IOException e) {
logger.error("调用微信接口失败,失败原因:" + e.getMessage(), e);
} finally {
try {
client.close();
} catch (IOException e) {
logger.error("关闭httpclient失败,失败原因:{}", e);
}
}
return result;
}

获取Json数据

1
2
3
4
5
6
7
public MpMaterialVO(JSONObject jsonObject) {
this.mediaId = jsonObject.getString("media_id");
JSONObject news = (JSONObject) jsonObject.getJSONObject("content").getJSONArray("news_item").get(0);
this.title = news.getString("title");
this.digest = news.getString("digest");
this.thumbUrl = news.getString("thumb_url");
}
Json与VO相互转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* 对应VO转为内容json
*/
public void voToJson() {
if (type == MaterialTemplateTypeEnum.MINI_CARD) {
contentJson = JsonUtils.toJsonString(miniCardVO);
} else if (type == MaterialTemplateTypeEnum.ADVANCED_IMAGE_TEXT) {
contentJson = JsonUtils.toJsonString(advancedImageTextVO);
} else {
contentJson = JsonUtils.toJsonString(content);
}
}
/**
* 内容json转为对应VO
*/
public void jsonToVO() {
if (type == MaterialTemplateTypeEnum.MINI_CARD) {
miniCardVO = JsonUtils.toBean(contentJson, MiniCardVO.class);
} else if (type == MaterialTemplateTypeEnum.ADVANCED_IMAGE_TEXT) {
advancedImageTextVO = JsonUtils.toBean(contentJson, AdvancedImageTextVO.class);
} else {
content = JsonUtils.toBean(contentJson, String.class);
}
}

微信发送图文消息举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
"touser":"OPENID",
"msgtype":"news",
"news":{
"articles": [
{
"title":"Happy Day",
"description":"Is Really A Happy Day",
"url":"URL",
"picurl":"PIC_URL"
}
]
}
}
public JSONObject initAdvancedImageText(AdvancedImageTextVO advancedImageTextVO) {
JSONObject param = new JSONObject();
param.put(MSG_TYPE, "news");
JSONObject news = new JSONObject();
JSONArray articles = new JSONArray();
JSONObject article = new JSONObject();
article.put(TITLE, advancedImageTextVO.getTitle());
article.put("description", advancedImageTextVO.getDescription());
article.put("url", advancedImageTextVO.getHref());
article.put("picurl", advancedImageTextVO.getUrl());
articles.add(article);
news.put("articles", articles);
param.put("news", news);
return param;
}

mybatis的Sql使用

xml配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<sql id="memberColumns">
a.id AS "id",
a.card_no AS "cardNo",
a.mobile AS "mobile",
a.login_name AS "loginName",
a.password AS "password",
a.status AS "status",
a.sex AS "sex",
a.birthday AS "birthday",
a.nick_name AS "nickName",
a.icon AS "icon",
a.is_created_order AS "isCreatedOrder",
a.binding_status AS "bindingStatus",
a.province AS "province",
a.city AS "city",
a.create_date AS "createDate",
a.create_by AS "createBy",
a.update_date AS "updateDate",
a.update_by AS "updateBy",
a.del_flag AS "delFlag",
a.remarks AS "remarks",
a.tenant_id AS "tenantId",
a.ext_tenant_id AS "extTenantId"
</sql>
<select id="listMember" resultMap="memberCO">
SELECT b.channel,
<include refid="memberColumns"/>
....
</select>
java使用
1
List<memberCO> list = memberChannelExtRepository.listMember("参数");

Java ES api相关使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//范围查询
if (null != query.getCancelTimeStart()) {
RangeQueryBuilder cancelTimeStartQuery = QueryBuilders.rangeQuery("cancelTime")
.gte(DateTimeUtils.formatDateTime(query.getCancelTimeStart()));
filter.must(cancelTimeStartQuery);
}
if (null != query.getCancelTimeEnd()) {
RangeQueryBuilder cancelTimeEndQuery = QueryBuilders.rangeQuery("cancelTime")
.lte(DateTimeUtils.formatDateTime(query.getCancelTimeEnd()));
filter.must(cancelTimeEndQuery);
}
//集合查询
if (ValidateUtils.isNotEmptyCollection(query.getPaymentStatuses())) {
List<String> paymentStatuses = query.getPaymentStatuses().stream()
.map(paymentStatus -> paymentStatus.toString()).collect(Collectors.toList());
TermsQueryBuilder paymentStatusesQuery = QueryBuilders.termsQuery("paymentStatus", paymentStatuses);
filter.must(paymentStatusesQuery);
}
//精确查询
TermsQueryBuilder originalExpressIdQuery = QueryBuilders
.termsQuery("originalExpressId", query.getOriginalExpressId());
filter.must(originalExpressIdQuery);
//
QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("user", "ki*hy");
//模糊查询
RegexpQueryBuilder externalCodeQuery = QueryBuilders.regexpQuery("externalCode",
“*”+ query.getExternalCode() + “*”);
WildcardQueryBuilder externalCodeQuery = QueryBuilders.wildcardQuery("externalCode",
"*"+query.getExternalCode()+"*");

parseInt与valueOf

1
2
3
Integer dailySignPointToInt = Integer.parseInt(resultData);
//推荐2,有缓存
Integer dailySignPointToInt = Integer.valueOf(resultData);

Arrays.asList()与Collections.singletonList()

1
2
Arrays.asList(strArray)返回值是仍然是一个可变的集合,但是返回值是其内部类,不具有add方法,可以通过set方法进行增加值,默认长度是10
Collections.singletonList()返回的同样是不可变的集合,但是这个长度的集合只有1,可以减少内存空间。但是返回的值依然是Collections的内部实现类,同样没有add的方法,调用add,set方法会报错

@Transient

1
@Transient表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性. 如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic

本地导出文件测试

1
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/octet-stream' --header 'X-Client-Id: swagger' --header 'X-Client-Token: 852311eac642cbf8059928c371784461' --header 'X-Tenant-Id: newretail' --header 'X-Ext-Tenant-Id: 1275854953286784' -d '{}' 'http://localhost:9017/api/earningRuleRetail/exportExcel' -o aa.xlsx

Kafka操作

1
2
3
4
5
//消费者
bin/windows/kafka-console-consumer.bat --zookeeper localhost:2181 --topic lvshen_demo_test --from-beginning
//生产者
bin/windows/kafka-console-producer.bat --broker-list localhost:9092 --topic lvshen_demo_test

判断小程序或h5

1
String clientType = ServletUtils.getRequest().getHeader("X-Client-Type");

InitializingBean

1
2
3
4
5
6
7
8
9
10
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
//示例
public class SensitiveWordFilterHelper implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
refreshAllWord();
}
...
}

kafka重试

1
2
3
4
5
1. new KafkaProducer()后创建一个后台线程KafkaThread扫描RecordAccumulator中是否有消息;
2. 调用KafkaProducer.send()发送消息,实际上只是把消息保存到RecordAccumulator中;
3. 后台线程KafkaThread扫描到RecordAccumulator中有消息后,将消息发送到kafka集群;
4. 如果发送成功,那么返回成功;
5. 如果发送失败,那么判断是否允许重试。如果不允许重试,那么返回失败的结果;如果允许重试,把消息再保存到RecordAccumulator中,等待后台线程KafkaThread扫描再次发送;

ArrayDeque方法(双队列)

addFirst(E e)
1
2
3
4
5
6
7
8
//addFirst(E e)
public void addFirst(E e) {
if (e == null)//不允许放入null
throw new NullPointerException();
elements[head = (head - 1) & (elements.length - 1)] = e;//2.下标是否越界
if (head == tail)//1.空间是否够用
doubleCapacity();//扩容
}

时间单位转换

1
2
3
4
5
6
7
8
//3600分钟 转换成 小时 是多少
System.out.println(TimeUnit.HOURS.convert(3600, TimeUnit.MINUTES));
//3600分钟 转换成 天 是多少
System.out.println(TimeUnit.DAYS.convert(3600, TimeUnit.MINUTES));
//3600分钟 转换成 秒 是多少
System.out.println(TimeUnit.SECONDS.convert(3600, TimeUnit.MINUTES));

事务结束后代码处理逻辑

1
afterTransactionExecutor.execute(() -> clearCacheCommodityByIds(ids));

地址路径为方法参数

1
2
3
4
5
6
7
8
@PostMapping("/changeSort/{id}/{type}")
@ApiOperation(value = "调整排序 TOTOP/UP", tags = TagConstant.PC)
@RequiresPermissions("xxx-commodity:commodityParam:edit")
public void changeSort(@PathVariable("id") String id, @PathVariable("type") String type) {
Assert.hasLength(id, "属性id有误");
commodityParamQueryService.get(id);
commodityParamService.changeSort(id, type);
}

批量操作tips

java
1
2
3
4
5
6
7
8
//批量操作时,先将索引字段排序,有利于避免死锁.按顺序加锁不会产生锁环
stockAllocateList.sort(Comparator.comparing(StockAllocate::getSkuId));
stockAllocateList.forEach(item -> {
int size = this.dao.updateSubAllocateStock(item);
if (size <= 0) {
throw new BusinessException("stockSubAllocate_error", stockAllocateVOS.toString());
}
});
sql
1
2
3
4
<update id="updateSubAllocateStock" >
update stock set allocate_stock = allocate_stock - #{commodityNumber}
where sku_id=#{skuId} and allocate_stock >= #{commodityNumber}
</update>

锁查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
select * from information_schema.innodb_locks;
show engine innodb status;
SELECT * FROM information_schema.innodb_lock_waits;
SHOW VARIABLES LIKE 'optimizer_trace';
SET optimizer_trace="enabled=on";
SELECT * FROM student WHERE name = 'fly';
SELECT * FROM information_schema.OPTIMIZER_TRACE;
--MySQL监控
-- 开启标准监控
CREATE TABLE innodb_monitor (a INT) ENGINE=INNODB;
-- 关闭标准监控
DROP TABLE innodb_monitor;
-- 开启锁监控
CREATE TABLE innodb_lock_monitor (a INT) ENGINE=INNODB;
-- 关闭锁监控
DROP TABLE innodb_lock_monitor;
--在 MySQL 5.6.16 之后,可以通过设置系统参数来开启锁监控
-- 开启标准监控
set GLOBAL innodb_status_output=ON;
-- 关闭标准监控
set GLOBAL innodb_status_output=OFF;
-- 开启锁监控
set GLOBAL innodb_status_output_locks=ON;
-- 关闭锁监控
set GLOBAL innodb_status_output_locks=OFF;
--MySQL 提供了一个系统参数 innodb_print_all_deadlocks 专门用于记录死锁日志,当发生死锁时,死锁日志会记录到 MySQL 的错误日志文件中
set GLOBAL innodb_print_all_deadlocks=ON;

MySQL死锁模拟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
--事务A
mysql> begin;
Query OK, 0 rows affected
--执行顺序 1
mysql> update student set age=31
where name = 'fly';
Query OK, 1 row affected
Rows matched: 1 Changed: 1 Warnings: 0
--执行顺序 3
mysql> update student set age=32 where name = 'alan';
Query OK, 1 row affected
Rows matched: 1 Changed: 1 Warnings: 0
--事务B
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
--执行顺序 2
mysql> update student set age=31 where name = 'alan';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
--执行顺序 4
mysql> update student set age=21 where name = 'fly';
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

使用Mybatis操作

注意不要先查询再操作

删除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//推荐
@Test
public void testDelete() {
Student student = new Student();
student.setName("Hare");
int delete = studentRepository.delete(student);
log.info("删除{}条数据",delete);
}
//不推荐
public void testDelete() {
Student student = studentRepositoryg.getByName("Hare");
int delete = studentRepository.delete(student);
log.info("删除{}条数据",delete);
}
更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//更新
@Test
public void testUpdate() {
Student student = new Student();
student.setId("2073678416402304");
student.setAge(26);
studentRepository.update(student);
log.info("test is success!!!");
}
//按条件更新
@Test
public void testUpdateByExample() {
//修改内容
Student student = new Student();
student.setAge(27);
//修改条件
Example example = new Example(Student.class);
Example.Criteria criteria = example.createCriteria();
criteria.andIn("name", ImmutableList.of("fly","lvshen"));
int i = studentRepository.updateByExample(student, example);
log.info("test is success!!!{}",i);
}
//不推荐
@Test
public void testUpdate() {
Student student = studentRepository.get("2073678416402304");
studentRepository.update(student);
log.info("test is success!!!");
}

Linux命令

1
2
3
4
5
#内存信息
jmap -F -dump:format=b,file=test.bin 22829(pid)
#堆信息
jstat -gcutil 22829(pid)