Có bảo giờ các bạn tự hỏi các kĩ thuật Orm trong Hibenate, hay cách mà spring data jpa thực sự hoạt động như nào không? Hãy cùng mình tìm hiểu nhé.
Có thể các bạn đã biết, trong Orm hay Object Relational Mapping trong Hibenate. ORM giúp đơn giản hoá việc tạo ra dữ liệu, thao tác dữ liệu và truy cập dữ liệu. Đó là một kỹ thuật lập trình để ánh xạ đối tượng vào dữ liệu được lưu trữ trong cơ sở dữ liệu. Chúng ta vẫn thường khai báo model trong Hibenate tương tự như UserModel dưới đây đúng không?
@Entity
@Table(name = "user")
@Data
public class UserModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @NotEmpty @Column(name = "username") private String username; @NotEmpty @Column(name = "password") private String password; @NotEmpty @Column(name = "createdDate") private Date createdDate;
}
Để hiểu được các thức để làm được điểu này thì đầu tiên ta cũng tìm hiểu về các kiến thức sau trong java.
Annotation
Dễ thấy ta cần hiểu về Annotation, vì trong ví dụ trên ta thấy có các anotation @Column, @Table, ...
Annotation (chú thích) là một loại siêu dữ liệu (metadata information) trong java có thể được áp dụng ở các phần tử mã nguồn java để sau đó một số công cụ (tool), trình gỡ lỗi (debugger) hoặc chương trình ứng dụng có thể tận dụng các chú thích này. Annotation được sử dụng cho các mục đích:
-
Chỉ dẫn cho trình biên dịch (Compiler)
-
Chỉ dẫn trong thời điểm biên dịch (Build-time)
-
Chỉ dẫn trong thời gian chạy (Runtime)
Reflection
Reflection là một kĩ thuật cho phép có thể duyệt và thay đổi các thuộc tính và phuơng thức của một class hoặc một interface tại thời điểm runtime, nó là một kĩ thuật rất mạnh và hữu ích cho các lập trình viên. Hơn nữa Reflection còn có thể đọc được cả các Annotation được chú thích trên class và trên các biến, các hàm trong class nữa.
Build simple Orm
tổng quan lại thì ta đã hiểu được đầu vào ta có những gì rồi, class và các Annotation chú thích trên Model. Công cụ ta có gì? Reflection giúp ta đọc các thông tin của Model. Đủ chưa nhỉ,... đủ rồi ta tiến hành thôi
Đầu tiên ta tạo 1 annotation Column như sau:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) // Tồn tại trong lúc chạy chương trình
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
public @interface Column { String columnName();
}
Tiếp theo ta tạo 1 annotation Table như sau:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) // Tồn tại trong lúc chạy chương trình
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
public @interface Table { String tableName();
}
Có các Annotation rồi thì tạo model thôi:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; @Data
@AllArgsConstructor
@NoArgsConstructor
@Table(tableName = "user")
public class User { @Column(columnName = "usr") String username; @Column(columnName = "pwd") String password; }
@AllArgsConstructor @NoArgsConstructor là mình dùng của thư viện lombok nhé. SimpleOrmDao như sau:
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; public class SimpleOrmDao<T> { private Connection getConnection() throws SQLException, ClassNotFoundException { try { Class.forName("com.mysql.cj.jdbc.Driver"); return DriverManager.getConnection( "jdbc:mysql://localhost:3306/simple_orm", "root", "password"); } catch (Exception e) { throw e; } } List<T> getAllUserAsOrm(Class<T> clazz) throws SQLException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { List<T> userList = new ArrayList<>(); Connection connection = getConnection(); String tableName = clazz.getAnnotation(Table.class).tableName(); ResultSet resultSet = connection.prepareStatement("SELECT * FROM " + tableName).executeQuery(); while (resultSet.next()){ T user = clazz.getConstructor().newInstance(); for (Field field : clazz.getDeclaredFields()) { if(field.isAnnotationPresent(Column.class)){ String columnName = field.getAnnotation(Column.class).columnName(); if(field.getType() == String.class){ field.set(user, resultSet.getString(columnName)); } } } userList.add(user); } return userList; } }
xonggggggg, dùng thử thôi nào:
public class Main { public static void main(String[] args) throws ClassNotFoundException, SQLException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { SimpleOrmDao simpleOrmDao = new SimpleOrmDao(); System.out.println(simpleOrmDao.getAllUserAsOrm(User.class)); }
}
Cách thức dùng và kết quả khá giống với Hibenate đấy chứ . Được rồi đến đây thôi, cùng hẹn các bạn ở các bài viết tiếp theo nhé!