Hibernate Native SQL Queries

Bài viết được sự cho phép của tác giả Giang Phan

Trong Hibernate, HQL hoặc Criteria Query cho phép chúng ta thực hiện hầu hết mọi truy vấn SQL mong muốn. Tuy nhiên, đôi khi về câu lệnh SQL được tạo ra bởi Hibernate chậm hoặc cần viết câu lệnh phức tạp và thích tạo câu lệnh SQL (SQL gốc) của riêng mình hơn. Với Hibernate cho chúng ta sử dụng Native SQL để thao tác với cơ sở dữ liệu, bao gồm các stored procedures, và tất cả các thao tác create, update, delete và select.

Tương tự như HQL hay Creteria, để tạo đối tượng Native Query chúng ta sẽ sử dụng phương thức createNativeQuery() từ đối tượng Session:

org.hibernate.query.NativeQuery createNativeQuery(java.lang.String s); <R> org.hibernate.query.NativeQuery<R> createNativeQuery(java.lang.String s, java.lang.Class<R> aClass);

Scalar queries

Các truy vấn SQL cơ bản nhất là để có được một danh sách các giá trị scalars (column) từ một hoặc nhiều bảng.

Ví dụ lấy tất cả các column của bảng user.

NativeQuery query = session.createNativeQuery("SELECT * FROM user" ); List<Object[]> users = query.getResultList();

Ví dụ lấy fullname và email của 10 user từ vị trí thứ 5

NativeQuery query = session.createNativeQuery("SELECT username, password FROM user ORDER BY username" ); List<Object[]> users = query.setFirstResult(5).setMaxResults(10).getResultList(); users.forEach( user -> { System.out.println("username: " + user[0] + " | password: " + user[1]); });

Ví dụ lấy username và password của một user có id là 1

NativeQuery query = session.createNativeQuery("SELECT username, password FROM user where id = :id" ); Object[] user = (Object[]) query.setParameter("id", 1).uniqueResult(); System.out.println("username: " + user[0] + " | password: " + user[1]);
  "Làm PM, theo anh không cần biết về code, nhưng phải hiểu về SQL, database, những khái niệm cơ bản của code"
  Các thao tác cơ bản với Database trong Microsoft SQL Server

Entity queries

Các truy vấn ở trên là về trả về các giá trị vô hướng từ ResultSet.

Ví dụ sử dụng JPA native query để có được các đối tượng Entity từ một truy vấn Native SQL

NativeQuery query = session.createNativeQuery("SELECT * FROM user", User.class ); List<User> users = query.getResultList();

Sau đây là cú pháp để có được các đối tượng Entity từ một truy vấn Native SQL thông qua addEntity().

NativeQuery query = session.createNativeQuery("SELECT * FROM user" ); List<User> users = query.addEntity(User.class).list();

Tìm việc làm lập trình SQL lương cao

DTOs (Data Transfer Objects)

Đôi khi chúng ta cần truy vấn một vài column và trả về trực tiếp cho đối tượng DTO, không cần phải thông qua Entity.

Ví dụ:

UserDTO.java

@Data public class UserDTO {     private String fullname;     private String username; }

Sử dụng ResultTransformer để trả về đượng tượng non-entity.

NativeQuery query = session.createNativeQuery("SELECT fullname, username FROM user" ); List<UserDTO> users = query.setResultTransformer( Transformers.aliasToBean( UserDTO.class ) ).list();

Nếu không muốn trả về DTO, có thể trả về một Map<String, Object> như sau:

NativeQuery query = session.createNativeQuery("SELECT fullname, username FROM user" ); List<Map<String,Object>> mapUsers = query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE).list(); mapUsers.forEach( user -> { System.out.println(user.get("fullname")); });

Handling associations and collections

Ví dụ lấy thông tin user và user profile.

List<Object[]> tuples = session.createNativeQuery(         "SELECT * " +                 "FROM user u " +                 "INNER JOIN user_profile p ON u.id = p.user_id" )         .addEntity("user", User.class )         .addJoin( "p", "user.userProfile")         .list(); for(Object[] tuple : tuples) {     User user = (User) tuple[0];     UserProfile userProfile = (UserProfile) tuple[1];     System.out.println("fullname " + user.getFullname() + " | address " + userProfile.getAddress()); }

Mặc định khi sử dụng addJoin(), kết quả trả về sẽ bao gồm tất cả các entity được join trong 1 array. Để trả về một đối tượng entity hierarchy, chúng ta cần sử dụng ROOT_ENTITY hoặc DISTINCT_ROOT_ENTITY ResultTransformer.

Chi tiết về các truy vấn khác, các bạn tham khảo thêm link bên dưới.

Tài liệu tham khảo:

Bài viết gốc được đăng tải tại gpcoder.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev