java-spring-boot-1

试着跟着教程写了个超级简单的 CRUD api

自上而下是 API Layer, Service Layer, Data Access Layer,

DB 用了 PostgreSQL

API Layer: Controller

@RestController

@RequestMapping(path = "api/v1/student")

1
2
3
4
@Autowired
public StudentController(StudentService studentService) {
this.studentService = studentService
}

CRUD 四天王:

@GetMapping

@PostMapping

@DeleleMapping

@PutMapping

注解的类里面调用 service类对象的方法,把参数传过去执行

为啥需要特地分一层出来?

可能是因为这一层描述需要做什么,而 Service 层用来定义具体怎么做

Service Layer: Service

需要用到 @Service 注解整个类

同样的,@Autowired 注解构造方法,然后喂给它一个 Repository 对象当参数

repository 对象有好多省力的方法,existsById,findById,findAll 啥的

这里用到了 @Transactional 注解,然后原来 java 也有箭头函数的糖吃?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Transactional
public void updateStudent(Long studentId, String name, String email) {
Student student = studentRepository.findById(studentId).orElseThrow(
() -> new IllegalStateException(
"student with id " + studentId + " does not exists"
)
);
if (name != null && name.length() > 0 && !Objects.equals(student.getName(), name)) {
student.setName(name);
}
if (email != null && email.length() > 0 && !Objects.equals(student.getEmail(), email)) {
Optional<Student> studentOptional = studentRepository.findStudentByEmail(email);
if (studentOptional.isPresent()) {
throw new IllegalStateException("email taken");
}
student.setEmail(email);
}
}

Data Access Layer: Repository, Config, Student

@Repository 注解也是需要的

StudentRepository 是个接口而不是具体的类,扩展 JpaRepository<对象类, 主键类>

可能是为了方便写 sql 吧… 第一次见到的语法

1
2
3
4
5
6
7
8
9
@Repository
public interface StudentRepository
extends JpaRepository<Student, Long> {

// SELECT * FROM STUDENT WHERE EMAIL=email;
@Query("SELECT s FROM Student s WHERE s.email = ?1")
Optional<Student> findStudentByEmail(String email);

}

Config 需要注解 @Configuration

这个示例里面,是用了 CommandLineRunner 去返回一个箭头函数,里面写死了两个 Student 类的对象,再用了 repository.saveAll 去保存 Student 类的数组

Student 类本身需要 @Entity@Table

1
2
3
4
5
6
7
8
9
10
@Id
@SequenceGenerator(
name = "student_sequence",
sequenceName = "student_sequence",
allocationSize = 1
)
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "student_sequence"
)

这段没看懂… 有点序列化那意思?后面再去看看 JPA 的教程

另外,age 是在 Getter 里算出来的,注解了 @Transient

杂项

application.properties 里面可以指定端口 server.port

可以指定 datasource url,username,pswd,

还有涉及到 hibernate 的 ddl-auto, show-sql, dialect 之类

idea 可以在 controller 里面当场测 api,但如果跑在本地还设置了代理会 500

postgres 建库完需要给用户授予权限

grant all privileges on database "student" to postgres;

pom 可以认为是后端用到的 mvn package.json

好在 mvn repository 不会像 node_modules 每个 repo 到处都是

db 没配置好之前 spring-boot-starter-data-jpa 会在运行的时候报错

后面也许可以做个大的玩具看看了

多几个对象的 CRUD 啥的(

JPA - Java Persistence API

ORM - Object Relational Mapping

好处是不用手写 sql

……这件事情大一就该开始干了

没事想不开去陪跑什么蓝桥杯啊真的是……

csapp-01-datalab

Environment

hp2570p running Ubuntu 22.04 LTS

with i7-3630QM and 16GB DDR3

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
➜  datalab-handout git:(master) ✗ make btest
gcc -O -Wall -m32 -lm -o btest bits.c btest.c decl.c tests.c
In file included from btest.c:16:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
27 | #include <bits/libc-header-start.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
In file included from decl.c:1:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
27 | #include <bits/libc-header-start.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
In file included from /usr/lib/gcc/x86_64-linux-gnu/11/include/limits.h:203,
from /usr/lib/gcc/x86_64-linux-gnu/11/include/syslimits.h:7,
from /usr/lib/gcc/x86_64-linux-gnu/11/include/limits.h:34,
from tests.c:3:
/usr/include/limits.h:26:10: fatal error: bits/libc-header-start.h: No such file or directory
26 | #include <bits/libc-header-start.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:11: btest] Error 1
➜ datalab-handout git:(master) ✗ make clean
rm -f *.o btest fshow ishow *~
➜ datalab-handout git:(master) ✗ make btest
gcc -O -Wall -m32 -lm -o btest bits.c btest.c decl.c tests.c
In file included from btest.c:16:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
27 | #include <bits/libc-header-start.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
In file included from decl.c:1:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
27 | #include <bits/libc-header-start.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
In file included from /usr/lib/gcc/x86_64-linux-gnu/11/include/limits.h:203,
from /usr/lib/gcc/x86_64-linux-gnu/11/include/syslimits.h:7,
from /usr/lib/gcc/x86_64-linux-gnu/11/include/limits.h:34,
from tests.c:3:
/usr/include/limits.h:26:10: fatal error: bits/libc-header-start.h: No such file or directory
26 | #include <bits/libc-header-start.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:11: btest] Error

solved by running

1
sudo apt install gcc-multilib

test-day-150

Today’s Task

  • Catalog Clear DB Pipelines AWS support
  • Upgrade Nucleus

Additional Task

  • Sanity Check

Thought

1

WFH 实属效率黑洞

我也讨厌那些看起来很圣洁的自我成长术语,啥正念啊延迟满足啊

玩的时候放开玩,干活的时候专注干

但我想把手上事情做完,还想做点能提升自己的事情

test-day-140

Today’s Task

  • Fix Solr Release Script
  • Hadar Script Modify
  • Investigate on Unknown component when deploying STG

Additional Task

  • Resolve Merge Conflict when merging retro into release
  • Manually deploy latest logstash indexer to STG
  • Delete old image release jenkins pipeline
  • Failure Tracking

Thought

test-day-139

Today’s Task

  • Fix Solr Release Script
  • Hadar Script Modify
  • Investigate on Unknown component when deploying STG

Additional Task

  • Redeploy player-control manually on IAD2
  • Delete pipelines and create numerous MRs about deleting groovy scripts from original repo

Thought

1

WFH 的效率低下,需要用什么办法来解决呢?

test-day-138

Today’s Task

  • Fix Solr Release Script
  • Hadar Script Modify
  • Investigate on Unknown component when deploying STG

Additional Task

Thought

1

Release Script deleting progress

  • access
  • catalog
  • crypto
  • customerportal
  • dynamic-config-ui
  • hyas
  • kakapo
  • keymaster
  • liquibase-deploy
  • nam
  • nexus
  • nucleus
  • nucleussolr
  • playercard ( no need to build )
  • playerownership-cassandra
  • playerownership
  • porpoise
  • saola
  • sloth
  • tos
  • vaquita

2

WFH 第二天

感觉每天时间多了好多!

省下了路上的通勤开销,每天可以多两个小时

反正平时周末一样也是闷在家里不出门

但相应的,手机的使用时长也高出太多

进程切换需要极大开销

test-day-137

Today’s Task

  • Investigate on Catalog Clear DB Issue
  • Investigate on Nucleus Solr Building Script

Additional Task

  • Manually build image for solr series

Thought

clear-catalog-stg-tips

啥时候需要做

每次 CM 铺 Cataglog STG 前

做什么

会用魔法登上 MySQL 删库

再重新创建一份新的

重启一下 pod

然后往里面塞很多数据

为什么需要

容易卡,导致别的 component regression 败一大堆

比如说 rating, commerce, subscription v2 三巨头

怎么做

如果执行失败了,或者执行中止,需要手动从断掉的地方登上去执行

如果卡在删库那一步,不要中止,直接去重铺一次 catalog stg

test-day-136

Today’s Task

  • Investigate on Sox Audit

Additional Task

Thought

1

昨晚试着往 sox audit 里面加了几行 log.debug()

发现它并没有删掉任何一行 cassandra log

但是找到了 24497 条记录……

等下回 CM 再执行看看

2

发现 Jenkins Credentials 是有问题的…

如果通过 withCredentials 定义在 groovy 脚本的 top level

在 step 里面 echo 可以直接拿到明文???

3

Groovy 里面的 def 额可以用来声明变量和函数,而类型会在运行时根据值来推断出来

test-day-135

Today’s Task

  • Investigate on Sox Audit Code and Cassandra

Additional Task

  • Saola Kafka Release Support
  • Nucleus Liquibase Cassandra on AWS Image Support
  • Learned how to update ChromeDriver Version on Web Hub from Peter Xin

Thought

1

Web Hub 上 ChromeDriver 的版本需要人工手动更新,万恶的 Google Auto Update

它会自动更新 Chrome 版本,而 ChromeDriver 版本必须和 Chrome 匹配

selenium/lib 下的 chromedriver,下下来的新版本先拖进去一份备份,后缀是版本号

然后再替换掉原来的那份 chromedriver

Chrome 没法固定住版本,在 Win 下用 Chrome 跑也是为了测试的时候更贴近用户使用场景

毕竟没有神仙会从 Linux 用 Chromium 访问……