

Thư viện và tiêu chuẩn
52. Ngủ đông là gì? Sự khác biệt giữa JPA và Hibernate là gì?
Để trả lời câu hỏi này, tôi nghĩ trước tiên chúng ta cần hiểu JPA là gì. Nó là một đặc tả mô tả ánh xạ quan hệ đối tượng của các đối tượng Java đơn giản và cung cấp API để lưu trữ, truy xuất và thao tác các đối tượng đó. Nghĩa là, cơ sở dữ liệu quan hệ (DB) được biểu diễn dưới dạng tập hợp các bảng được kết nối với nhau. Và JPA là một tiêu chuẩn được áp dụng rộng rãi, mô tả cách các đối tượng có thể tương tác với cơ sở dữ liệu quan hệ. Như bạn có thể thấy, JPA là một cái gì đó trừu tượng và vô hình. Nó giống như ý tưởng, cách tiếp cận.
53. Xếp tầng là gì? Nó được sử dụng như thế nào trong Hibernate?
Như tôi đã nói trước đó, giao tiếp trong Hibernate diễn ra thông qua các đối tượng dữ liệu được gọi là thực thể. Các thực thể này đại diện cho các bảng cụ thể trong cơ sở dữ liệu và như bạn sẽ nhớ lại, các lớp Java có thể chứa các tham chiếu đến các lớp khác. Những mối quan hệ này cũng được phản ánh trong cơ sở dữ liệu. Theo quy định, chúng là khóa ngoại (đối với các mối quan hệ OneToOne, OneToMany, ManyToOne) hoặc các bảng trung gian (đối với các mối quan hệ ManyToMany). Khi thực thể của bạn có tham chiếu đến các thực thể liên quan khác, chú thích sẽ được đặt phía trên các tham chiếu này để biểu thị loại mối quan hệ: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany. Bạn có thể chỉ định loại phân tầng cho mối quan hệ này trong thuộc tính phân tầng của chú thích. JPA có các phương thức cụ thể để tương tác với các thực thể (kiên trì, lưu, hợp nhất ...). Các kiểu xếp tầng được sử dụng để hiển thị cách hoạt động của dữ liệu liên quan; những phương pháp này được sử dụng trên một thực thể mục tiêu. Vậy chiến lược xếp tầng (loại xếp tầng) là gì? Tiêu chuẩn JPA cung cấp việc sử dụng sáu loại tầng:-
KIÊN TRÌ - các hoạt động lưu xảy ra theo tầng (đối với các phương thức save() và Persist() ). Nói cách khác, nếu chúng ta lưu một thực thể được liên kết với các thực thể khác thì các thực thể đó cũng được lưu trong cơ sở dữ liệu (nếu chúng chưa có ở đó)
-
MERGE - các hoạt động cập nhật xảy ra theo tầng (đối với phương thức merge() )
-
XÓA - các thao tác xóa xảy ra theo tầng ( phương thức Remove() )
-
TẤT CẢ - chứa ba thao tác xếp tầng cùng một lúc - KIÊN TRÌ - HỢP NHẤT - XÓA
-
DETACH - các thực thể liên quan không được quản lý bởi phiên ( phương thức Detach() ). Tức là khi dữ liệu của các thực thể liên quan thay đổi, dữ liệu trong cơ sở dữ liệu không được cập nhật tự động - chúng được chuyển đổi từ Persistent sang Det Riêng (tức là thực thể không được JPA quản lý)
-
LÀM MỚI - mỗi khi một thực thể được làm mới với dữ liệu từ cơ sở dữ liệu ( Refresh() - làm mới các đối tượng tách rời), các thực thể liên quan của nó cũng được làm mới. Ví dụ: bằng cách nào đó bạn đã thay đổi dữ liệu được lấy từ cơ sở dữ liệu và bạn muốn khôi phục các giá trị ban đầu. Trong trường hợp này, bạn sẽ thấy thao tác này hữu ích.

-
REPLICATE - được sử dụng khi chúng tôi có nhiều nguồn dữ liệu và chúng tôi muốn dữ liệu được đồng bộ hóa (phương pháp sao chép của Hibernate). Tất cả các thực thể phải có số nhận dạng (id) để đảm bảo rằng chúng có thể được tạo mà không gặp vấn đề gì (để đảm bảo rằng cùng một thực thể không có id khác nhau cho các cơ sở dữ liệu khác nhau)
-
SAVE_UPDATE - lưu/xóa xếp tầng (đối với phương thức saveOrUpdate của Hibernate )
-
LOCK - ngược lại với hoạt động DETACHED : chuyển đổi một thực thể tách rời trở lại trạng thái liên tục, tức là phiên hiện tại sẽ theo dõi thực thể đó một lần nữa
54. Một lớp Thực thể có thể trừu tượng được không?
Theo 2.1 Lớp thực thể của đặc tả JPA , " Cả hai lớp trừu tượng và cụ thể đều có thể là thực thể. " Vì vậy, câu trả lời là có, một lớp trừu tượng có thể là một thực thể và có thể được đánh dấu bằng chú thích @Entity.55. Người quản lý thực thể là gì? Nó chịu trách nhiệm về việc gì?
Trước hết, tôi muốn lưu ý rằng EntityManager là thành phần quan trọng của JPA . Nó được sử dụng để tương tác giữa các thực thể với cơ sở dữ liệu. Nói chung, các phương thức tương tác của thực thể với cơ sở dữ liệu được gọi trên thực thể (kiên trì, hợp nhất, xóa, tách)... Nhưng tôi cũng lưu ý rằng thành phần này thường không phải là thành phần đơn lẻ cho toàn bộ ứng dụng. Nó thường nhẹ, một cái sẽ bị xóa và một cái mới được tạo bằng cách sử dụng EntityManagerFactory . Nếu chúng ta so sánh với JDBC , trong đó EntityManagerFactory tương tự như DataSource thì EntityManager tương tự như Connection . Trước đó, tôi đã đề cập rằng thực thể liên tục là thực thể được quản lý bởi kết nối hiện tại. Thực thể này được quản lý bởi EntityManager , có liên quan chặt chẽ với kết nối hiện tại và TransactionManager , chịu trách nhiệm mở/đóng giao dịch. Trong hình bên dưới, bạn có thể thấy vòng đời của thực thể:
56. Lớp Assert là gì? Tại sao nó được sử dụng?
Tôi chưa từng nghe nói về một lớp như vậy trong JPA , vì vậy tôi sẽ cho rằng câu hỏi này đề cập đến một lớp được tìm thấy trong thư viện JUnit được sử dụng cho các bài kiểm tra đơn vị. Trong thư viện này, lớp Assert được sử dụng để kiểm tra kết quả thực thi mã (ở đây khẳng định có nghĩa là xác nhận rằng bạn có trạng thái/dữ liệu cụ thể tại một vị trí cụ thể trong mã). Ví dụ: giả sử bạn đang thử nghiệm một phương pháp được cho là tạo ra một con mèo. Bạn chạy phương thức và bạn nhận được một số kết quả:Cat resultOfTest = createCat();
Nhưng bạn cần chắc chắn rằng nó được tạo chính xác, phải không? Vì vậy, bạn tạo thủ công một con mèo cụ thể ( expectedCat ) với chính xác các tham số mà bạn mong đợi thấy ở con mèo thu được từ phương thức createCat() . Sau đó bạn sử dụng lớp Assert để xác minh kết quả:
Assert.assertEquals(resultOfTest, expectedCat);
Nếu những con mèo khác nhau thì AssertionError sẽ được ném ra, điều này cho chúng ta biết rằng chúng ta không nhận được kết quả như mong đợi. Lớp Assert có nhiều phương thức khác nhau bao gồm nhiều thao tác hữu ích trong việc xác minh kết quả mong đợi. Dưới đây là một vài trong số họ:
-
khẳng địnhTrue(<boolean>) - giá trị được truyền vào dưới dạng đối số được mong đợi là đúng
-
khẳng địnhFalse(<boolean>) - giá trị được truyền vào dưới dạng đối số dự kiến là sai
-
khẳng địnhNotEquals(<object1>, <object2>) - các đối tượng được truyền dưới dạng đối số phải khác nhau khi so sánh bằng cách sử dụng bằng ( false )
-
khẳng địnhThrows(<ClassNameOfException>.class, <ExceptionObject>) — đối số thứ hai dự kiến sẽ là một ngoại lệ do đối số thứ nhất đưa ra (tức là đối số thứ hai thường là một lệnh gọi phương thức sẽ đưa ra một ngoại lệ của loại được yêu cầu)
Sợi dây
57. Mô tả lớp String của Java
Chuỗi là một lớp Java tiêu chuẩn chịu trách nhiệm lưu trữ và thao tác các giá trị chuỗi (chuỗi ký tự). Nó là một lớp bất biến (tôi đã viết về bất biến trước đây ở đây ), tức là dữ liệu của các đối tượng của lớp này không thể thay đổi sau khi chúng được tạo. Tôi muốn lưu ý ngay rằng các lớp StringBuilder và StringBuffer về cơ bản giống hệt nhau - điểm khác biệt duy nhất là một trong số chúng được thiết kế để sử dụng trong môi trường đa luồng ( StringBuffer ). Các lớp này giống như String nhưng khác ở chỗ chúng có thể thay đổi được . Ngay cả sau khi chúng được tạo, chúng vẫn cho phép bạn sửa đổi các chuỗi mà chúng đại diện mà không cần tạo đối tượng mới. Các phương thức của chúng khác với các phương thức Chuỗi tiêu chuẩn và được thiết kế để thao tác với chuỗi (có lý do khiến họ gọi nó là trình tạo).58. Có những cách nào để tạo một đối tượng String? Nó được tạo ra ở đâu?
Cách phổ biến nhất để tạo chuỗi là chỉ định giá trị chúng ta muốn trong dấu ngoặc kép một cách đơn giản:String str = "Hello World!";
Bạn cũng có thể làm điều đó một cách rõ ràng bằng cách sử dụng new :
String str = new String("Hello World!");
Bạn cũng có thể tạo một chuỗi từ một mảng ký tự:
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
Chúng ta có thể làm điều đó bằng cách gọi phương thức toString trên một số đối tượng:
String str = someObject.toString();
Chúng ta có thể làm điều đó bằng cách gọi bất kỳ phương thức nào khác trả về một chuỗi. Ví dụ:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine();
Bạn hiểu rằng có thể có rất nhiều cách để tạo ra một chuỗi. Khi một đối tượng String được tạo, nó sẽ được lưu trữ trong một nhóm chuỗi , chúng ta sẽ thảo luận chi tiết hơn về một trong các câu hỏi bên dưới.
59. Làm cách nào để so sánh hai chuỗi Java và sắp xếp chúng như thế nào?
Java sử dụng dấu bằng kép ( == ) để thực hiện so sánh. Nếu cần so sánh các giá trị đơn giản như int, chúng ta sẽ sử dụng nó. Nhưng phương pháp này không phù hợp để so sánh các đối tượng chính thức. Nó sẽ chỉ so sánh các tham chiếu, tức là các tham chiếu có trỏ đến cùng một đối tượng hay không. Điều này có nghĩa là nếu chúng ta so sánh hai đối tượng có cùng giá trị trường bằng cách sử dụng == , chúng ta sẽ nhận được sai . Các trường có cùng giá trị nhưng bản thân các đối tượng chiếm các vị trí khác nhau trong bộ nhớ. Các đối tượng chuỗi , mặc dù có vẻ đơn giản đến mức dễ nhầm lẫn, vẫn là các đối tượng. So sánh chúng bằng cách sử dụng == cũng không phù hợp (mặc dù có sự hiện diện của nhóm chuỗi). Giải pháp thích hợp là phương thức bằng tiêu chuẩn của lớp Object , cần được ghi đè để hoạt động chính xác (theo mặc định, nó sử dụng == để so sánh). Lớp String ghi đè lên nó nên chúng ta chỉ sử dụng cách triển khai của nó:String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);

TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
Đầu ra của bảng điều khiển:
60. Cung cấp thuật toán chuyển chuỗi thành ký tự. Viết mã tương ứng
Như tôi đã nói trước đó, các đối tượng String có rất nhiều phương thức hữu ích khác nhau. Một trong số đó là toCharArray . Phương thức này chuyển đổi một chuỗi thành một mảng ký tự:String str = "Hello world";
char[] charArr = str.toCharArray();
Tiếp theo, chúng ta có một mảng các ký tự mà chúng ta có thể tham chiếu theo chỉ mục:
char firstChar = charArr[0]; // H
61. Làm thế nào để chuyển đổi một chuỗi thành một mảng byte và ngược lại? Viết mã tương ứng
Lớp String có phương thức getBytes , tương tự như phương thức toCharArray và trả về chuỗi dưới dạng mảng byte:String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
Chúng tôi đã đi đến kết luận hợp lý trong bài đánh giá ngày hôm nay. Cảm ơn vì đã đọc!
GO TO FULL VERSION