CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.
Bài viết trên blog CFSDN này triển khai một cách tinh tế quá trình xử lý liệt kê toàn cầu trong các ứng dụng Java được tác giả sưu tầm và biên soạn. Nếu bạn quan tâm đến bài viết này, hãy nhớ thích nó.
Mô tả nền.
Để thể hiện một thuộc tính nhất định bằng một tập hợp các phạm vi tùy chọn, chúng ta thường sử dụng hai phương pháp. Các lớp liệt kê và từ điển dữ liệu đều có những ưu điểm riêng. Lớp liệt kê được viết bằng mã Java, tạo điều kiện thuận lợi cho việc viết logic phán đoán tương ứng. Mã này rất dễ đọc và các thuộc tính trong lớp liệt kê có thể được ước tính và xác định trước. Từ điển dữ liệu thường được lưu trong cơ sở dữ liệu, điều này gây bất tiện cho việc ghi phán đoán và logic nhánh, bởi vì nếu dữ liệu thay đổi, logic mã tương ứng có thể trở nên không hợp lệ. Nó phụ thuộc rất nhiều vào tính chính xác của dữ liệu cơ sở dữ liệu. trong từ điển dữ liệu có ảnh hưởng không lớn đến doanh nghiệp. Nó thường được sử dụng để phân loại và ghi nhãn trong phát triển hàng ngày.
Hiện tại, về cơ bản không có giải pháp tốt nào để xử lý các lớp liệt kê trên toàn cầu, vì vậy tôi đã tự viết một giải pháp dựa trên nhiều thông tin khác nhau.
mã số.
Kiến trúc vẫn đang được hoàn thiện, code có thể chưa nhất thiết phải chạy. Tuy nhiên, phần config của enumeration đã hoàn thiện. Các bạn có thể đọc và tham khảo: beautiful-demo.
Lời nói đầu.
Khi hầu hết các công ty xử lý các bảng liệt kê, họ sẽ tùy chỉnh một lớp công cụ chuyển đổi bảng liệt kê hoặc viết một phương thức tĩnh trong lớp bảng liệt kê để thực hiện phương pháp chuyển đổi số nguyên thành bảng liệt kê.
Ví dụ:
?
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
|
công cộng
liệt kê
giới tính {
công cộng
tĩnh
lấy giới tính(
số nguyên
giá trị) {
vì
(mục giới tính : giới tính.values()) {
nếu như
(giá trị == mục.getvalue()) {
trở lại
mục;
}
}
trở lại
vô giá trị
;
}
}
công cộng
lớp học
enumutil {
công cộng
tĩnh
mở rộng
có thể đếm được> e của(
@khôngnull
lớp học
loại lớp,
số nguyên
giá trị) {
vì
(e enumconstant : classtype.getenumconstants()) {
nếu như
(giá trị == enumconstant.getvalue()) {
trở lại
hằng số đếm;
}
}
trở lại
vô giá trị
;
}
}
genderenum giới tính = enumutil.of(genderenum.
lớp học
,
1
);
|
Phương pháp này rất rắc rối hoặc bạn cần phải viết thủ công phương thức tĩnh tương ứng hoặc bạn cần gọi thủ công một lớp công cụ để chuyển đổi.
giải pháp.
Để thuận tiện, tôi đã thực hiện một sơ đồ chuyển đổi giá trị liệt kê toàn cầu. Lược đồ này có thể nhận ra giao diện người dùng chuyển int đến máy chủ và máy chủ sẽ tự động chuyển đổi nó thành một lớp liệt kê sau khi đưa ra các phán đoán kinh doanh tương ứng. được lưu trữ dưới dạng số vào cơ sở dữ liệu; Các số trong cơ sở dữ liệu được chuyển đổi thành các lớp liệt kê Java Sau khi xử lý logic nghiệp vụ tương ứng, thông tin liệt kê và hiển thị tương ứng với lớp liệt kê sẽ được chuyển đến quầy lễ tân không cần duy trì mối quan hệ tương ứng giữa. lớp liệt kê và thông tin hiển thị, và thông tin được hiển thị hỗ trợ xử lý quốc tế. Kế hoạch cụ thể như sau:
1. Dựa trên nguyên tắc quy ước lớn hơn cấu hình, xây dựng các quy tắc thống nhất để viết các lớp liệt kê. Các quy tắc chung như sau:
- Mỗi lớp liệt kê có hai trường: int value (được lưu trong cơ sở dữ liệu), string key (tìm thông tin văn bản i18n tương ứng thông qua key). Điều này cần được thảo luận chi tiết. Các giá trị liệt kê thường được lưu trữ trong cơ sở dữ liệu dưới dạng giá trị int hoặc giá trị chuỗi. Mỗi giá trị đều có ưu và nhược điểm riêng. Ưu điểm của việc lưu trữ int là nó có kích thước nhỏ. Nếu giá trị liệt kê chứa các quy tắc, chẳng hạn như -1 là xóa, 0 là tiền xử lý, 1 là xử lý và 2 là hoàn thành xử lý, thì chúng ta không thể sử dụng trạng thái cho tất cả các dữ liệu của mình. dữ liệu không bị xóa trong phương thức (0,1,2) và chuyển đổi sang trạng thái >= 0; nếu bạn lưu chuỗi, ưu điểm là nó rất dễ đọc và bạn có thể hiểu trực tiếp trạng thái tương ứng từ giá trị của chuỗi. cơ sở dữ liệu. Nhược điểm là nó chiếm kích thước lớn hơn. Tất nhiên, đây đều là tương đối. Khi lưu trữ int, chúng ta có thể cải thiện các nhận xét và có khả năng đọc tốt. Nếu int được thay thế bằng chuỗi, thì dung lượng lớn hơn mà nó chiếm thực sự có thể bị bỏ qua.
- Các lớp liệt kê liệt kê cần kế thừa một giao diện thống nhất và cung cấp các phương thức tương ứng để xử lý chung các bảng liệt kê.
Sau đây là giao diện liệt kê và ví dụ về liệt kê:
?
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
|
công cộng
giao diện
có thể đếm được
mở rộng
có thể đếm được> {
/**
* Lấy key tương ứng trong file i18n
* @phím return
*/
@khôngnull
chuỗi getkey();
/**
* Lấy giá trị cuối cùng được lưu vào cơ sở dữ liệu
* @return giá trị
*/
@khôngnull
số nguyên
lấy giá trị();
/**
* Lấy thông tin văn bản tương ứng với key
* @return thông tin văn bản
*/
@khôngnull
mặc định
chuỗi gettext() {
trở lại
i18nmessageutil.getmessage(
cái này
.getkey(),
vô giá trị
);
}
}
công cộng
liệt kê
giới tính
thực hiện
có thể đếm được {
/** nam giới*/
nam giới(
1
,
"nam giới"
),
/** nữ giới*/
nữ giới(
2
,
"nữ giới"
);
riêng tư
số nguyên
giá trị;
riêng tư
phím đàn;
giới tính (
số nguyên
giá trị, khóa chuỗi) {
cái này
.giá trị = giá trị;
cái này
.key = chìa khóa;
}
@ghi đè
công cộng
chuỗi getkey() {
trở lại
cái này
.chìa khóa;
}
@ghi đè
công cộng
số nguyên
lấy giá trị() {
trở lại
cái này
.giá trị;
}
}
|
Những gì chúng ta phải làm là mỗi lớp liệt kê chúng ta viết cần phải được viết theo cách này. Lớp liệt kê được xác định theo đặc tả để thuận tiện cho việc viết thống nhất dưới đây.
2. Chúng tôi phân tích dữ liệu vào và ra ở cấp bộ điều khiển để xử lý việc chuyển đổi các lớp liệt kê và giá trị int. Trong spring mvc, framework giúp chúng tôi chuyển đổi các kiểu dữ liệu, vì vậy chúng tôi sử dụng spring mvc làm điểm vào. Các yêu cầu được bộ phận lễ tân gửi đến máy chủ thường có các tham số trong URL và trong nội dung, được biểu thị bằng các yêu cầu nhận và đăng yêu cầu tương ứng với @requestbody.
[Tham số đầu vào] Phương thức get được biểu thị và loại phương tiện được yêu cầu là "application/x-www-form-urlencoded". Tại thời điểm này, int được chuyển đổi thành một bảng liệt kê. Nếu spring mvc xác định điều đó. một giá trị cần được chuyển đổi Khi chuyển đổi sang đối tượng lớp liệt kê mà chúng ta đã xác định, bộ chuyển đổi mà chúng ta đặt sẽ được gọi.
?
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
|
@cấu hình
công cộng
lớp học
cấu hình mvc
thực hiện
webmvcconfigurer, webbindinginitializer {
/**
* Trong yêu cầu [get], chuyển đổi giá trị int thành lớp liệt kê
* @param đăng ký
*/
@ghi đè
công cộng
vô hiệu
addformatters(formatterregistry registry) {
đăng ký.addconverterfactory(
mới
enumconverterfactory());
}
}
công cộng
lớp học
enumconverterfactory
thực hiện
converterfactory {
riêng tư
cuối cùng
bản đồ<
lớp học
, bộ chuyển đổi> bộ chuyển đổi bộ nhớ đệm =
mới
sơ đồ yếu<>();
@ghi đè
@suppresscảnh báo
({
"rawtypes"
,
"chưa được kiểm tra"
})
công cộng
mở rộng
enumerable> bộ chuyển đổi getconverter(
@khôngnull
lớp học
loại mục tiêu) {
trở lại
convertercache.computeifabsent(loại mục tiêu,
k -> convertercache.put(k,
mới
enumconverter(k))
);
}
được bảo vệ
lớp học
enumconverter
mở rộng
có thể đếm được>
thực hiện
bộ chuyển đổi {
riêng tư
cuối cùng
lớp học
kiểu liệt kê;
công cộng
bộ chuyển đổi enum(
@khôngnull
lớp học
kiểu liệt kê) {
cái này
.enumtype = enumtype;
}
@ghi đè
công cộng
t chuyển đổi(
@khôngnull
giá trị số nguyên) {
trở lại
enumutil. của(
cái này
.enumtype, giá trị);
}
}
}
|
[Thông số đầu vào] post thể hiện, chuyển đổi int thành kiểu liệt kê. Chúng tôi đã đạt được thỏa thuận với bộ phận lễ tân (loại ứng dụng trong ajax) và tất cả dữ liệu trong nội dung phải ở định dạng json. Tương tự, loại phương tiện yêu cầu của tham số tương ứng với nền @requestbody là "application/json". Đối với dữ liệu định dạng json trong spring mvc, jackson2httpmessageconverter được sử dụng theo mặc định. Khi chuyển đổi Jackson thành một thực thể, có hai chú thích @jsoncreator và @jsonvalue có thể được sử dụng nhưng vẫn cảm thấy hơi rắc rối. Để xử lý nó một cách thống nhất, chúng ta cần sửa đổi sự hỗ trợ của Jackson đối với việc tuần tự hóa và giải tuần tự hóa các lớp liệt kê. Cấu hình như sau:
?
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
|
@cấu hình
@slf4j
công cộng
lớp học
cấu hình jackson {
/**
* bộ chuyển đổi jackson
* @trở lại
*/
@đậu
@sơ đẳng
@suppresscảnh báo
({
"rawtypes"
,
"chưa được kiểm tra"
})
công cộng
mappingjackson2httpmessageconverter mappingjacksonhttpmessageconverter() {
cuối cùng
mappingjackson2httpmessageconverter bộ chuyển đổi =
mới
mappingjackson2httpmessageconverter();
objectmapper objectmapper = converter.getobjectmapper();
objectmapper.setserializationinclusion(jsoninclude.include.non_empty);
objectmapper.configure(deserializationfeature.fail_on_unknown_properties,
SAI
);
objectmapper.configure(jsonparser.feature.allow_unquoted_control_chars,
ĐÚNG VẬY
);
objectmapper.configure(jsonparser.feature.allow_single_quotes,
ĐÚNG VẬY
);
simplemodule khách hàngmodule =
mới
mô-đun đơn giản();
customermodule.adddeserializer(chuỗi.
lớp học
,
mới
stringtrimdeserializer(chuỗi.
lớp học
));
customermodule.adddeserializer(có thể đếm được.
lớp học
,
mới
enumdeserializer(có thể đếm được.
lớp học
));
customermodule.addserializer(có thể đếm được.
lớp học
,
mới
enumserializer(có thể đếm được.
lớp học
));
objectmapper.registermodule(customermodule);
converter.setsupportedmediatypes(immutablelist.of(mediatype.text_html, mediatype.application_json));
trở lại
bộ chuyển đổi;
}
}
công cộng
lớp học
enumdeserializer
mở rộng
có thể đếm được>
mở rộng
stddeserializer {
riêng tư
lớp học
kiểu liệt kê;
công cộng
trình liệt kê deserializer(
@khôngnull
lớp học
kiểu liệt kê) {
siêu
(kiểu enum);
cái này
.enumtype = enumtype;
}
@ghi đè
công cộng
e deserialize(jsonparser jsonparser, deserializationcontext deserializationcontext)
ném
ngoại lệ io {
trở lại
enumutil. của(
cái này
.enumtype, jsonparser.getintvalue());
}
}
|
[Đầu ra tham số] Khi chúng tôi truy vấn kết quả và hiển thị chúng ở quầy lễ tân, chúng tôi sẽ thêm chú thích @responsebody vào tập kết quả. Lúc này, phương thức tuần tự hóa của Jackson sẽ được gọi, vì vậy chúng tôi đã thêm cấu hình trình tự của lớp liệt kê. . Nếu chúng ta chỉ đơn giản chuyển đổi kiểu liệt kê thành int và đưa nó vào giao diện người dùng, thì giao diện người dùng cần duy trì mối quan hệ giữa int của lớp liệt kê này và thông tin hiển thị tương ứng. Vì vậy ở đây chúng ta trả về giá trị và hiển thị thông tin cho lễ tân để giảm bớt áp lực công việc cho lễ tân.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
customermodule.addserializer(có thể đếm được.
lớp học
,
mới
enumserializer(có thể đếm được.
lớp học
));
công cộng
lớp học
bộ đếm tuần tự
mở rộng
stdserializer {
công cộng
trình đếm tuần tự(
@khôngnull
lớp học
loại ) {
siêu
(kiểu);
}
@ghi đè
công cộng
vô hiệu
serialize(có thể đếm được, có thể đếm được, jsongenerator jsongenerator, serializerprovider serializerprovider)
ném
ngoại lệ io {
jsongenerator.writestartobject();
jsongenerator.writenumberfield(
"giá trị"
, có thể đếm được.getvalue());
jsongenerator.writestringfield(
"chữ"
, có thể liệt kê.gettext());
jsongenerator.writeendobject();
}
}
|
Bằng cách này, việc cấu hình các tham số đầu vào và tham số đầu ra đã hoàn tất. Chúng ta có thể đảm bảo rằng tất cả các int được truyền từ quầy lễ tân xuống nền sẽ được tự động chuyển đổi thành các lớp liệt kê. Nếu dữ liệu trả về có lớp liệt kê thì lớp liệt kê cũng sẽ chứa các giá trị và hiển thị văn bản, rất tiện lợi và đơn giản.
3. Lớp lưu trữ chuyển đổi các lớp liệt kê. ORM framework được chọn ở đây là Mybatis, nhưng nếu bạn nhìn vào trang web chính thức thì thông tin trên trang web chính thức chỉ cung cấp hai giải pháp, đó là chuyển đổi tên trường ẩn và thứ tự thông qua bảng liệt kê. Không có giải pháp liệt kê phổ quát. Tuy nhiên, bằng cách xem qua các bản ghi sự cố và bản phát hành trong github, chúng tôi nhận thấy rằng cấu hình xử lý liệt kê tùy chỉnh tương ứng đã được cung cấp trong phiên bản 3.4.5. Điều này không yêu cầu chúng tôi thực hiện quá nhiều cấu hình. Chúng tôi trực tiếp thêm mybatis-spring-boot -. phụ thuộc khởi động, hãy định cấu hình trực tiếp tệp Yaml tương ứng để triển khai chức năng.
?
1
2
3
4
5
|
ứng dụng.yml
--
giày của tôi:
cấu hình:
mặc định
-
liệt kê
-trình xử lý kiểu: github.shiyajian.pretty.config.enums.enumtypehandler
|
?
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
|
công cộng
lớp học
trình xử lý enumtype
mở rộng
có thể đếm được>
mở rộng
trình xử lý kiểu cơ sở {
riêng tư
lớp học
kiểu liệt kê;
công cộng
enumtypehandler() {
}
công cộng
trình xử lý kiểu enum (
@khôngnull
lớp học
kiểu liệt kê) {
cái này
.enumtype = enumtype;
}
@ghi đè
công cộng
vô hiệu
setnonnullparameter(preparedstatement preparedstatement,
số nguyên
tôi, ee, jdbctype jdbctype)
ném
ngoại lệ sql {
preparedstatement.setint(i, e.getvalue());
}
@ghi đè
công cộng
e getnullableresult(resultset rs, string tên cột)
ném
ngoại lệ sql {
số nguyên
value = rs.tinted(tên cột);
trở lại
rs.wasnull() ?
vô giá trị
: enumutil. của(
cái này
.enumtype, giá trị);
}
@ghi đè
công cộng
e getnullableresult(resultset rs,
số nguyên
chỉ số cột)
ném
ngoại lệ sql {
số nguyên
value = rs.tinted(columnindex);
trở lại
rs.wasnull() ?
vô giá trị
: enumutil. của(
cái này
.enumtype, giá trị);
}
@ghi đè
công cộng
e getnullableresult(callablestatement cs,
số nguyên
chỉ số cột)
ném
ngoại lệ sql {
số nguyên
giá trị = cs.getint(columnindex);
trở lại
cs.wasnull() ?
vô giá trị
: enumutil. của(
cái này
.enumtype, giá trị);
}
}
|
Bằng cách này, chúng tôi đã hoàn thành việc lưu trữ từ trang giao diện người dùng sang mã doanh nghiệp sang cơ sở dữ liệu và từ truy vấn cơ sở dữ liệu sang mã doanh nghiệp sang chuyển đổi lớp liệt kê của trang. Không cần phải xử lý thủ công các lớp liệt kê trong toàn bộ dự án. Quá trình phát triển của chúng tôi đơn giản hơn nhiều.
Phần kết luận.
Một giải pháp tốt không đòi hỏi công nghệ tiên tiến, chẳng hạn như nhiều phản xạ khác nhau và các mẫu thiết kế khác nhau, miễn là thiết kế hợp lý, đơn giản và dễ sử dụng, tương tự như mộng và mộng của Trung Quốc cổ đại.
Tóm tắt.
Trên đây là toàn bộ nội dung bài viết mong rằng nội dung bài viết có giá trị tham khảo nhất định cho quá trình học tập, làm việc của mọi người. Nếu có thắc mắc gì có thể để lại tin nhắn để trao đổi.
Liên kết gốc: https://www.cnblogs.com/shiyajian/p/10363554.html.
Cuối cùng, bài viết này về phương pháp triển khai xử lý liệt kê toàn cục một cách tinh tế trong các ứng dụng Java kết thúc ở đây. Nếu bạn muốn biết thêm về phương pháp triển khai xử lý liệt kê toàn cục một cách tinh tế trong các ứng dụng Java, vui lòng tìm kiếm các bài viết của CFSDN hoặc tiếp tục duyệt qua các bài viết liên quan. mong bạn sẽ ủng hộ blog của mình trong tương lai nhé! .
Tôi là một lập trình viên xuất sắc, rất giỏi!