[Thực hành] Ứng dụng quản lý danh sách khách hàng
NỘI DUNG BÀI VIẾT
Mục tiêu
Thực hành sử dụng một framework ORM phổ biến là hibernate để ánh xạ bộ nhớ của chương trình với database.
Mô tả
Bổ sung khả năng ngoại hóa cơ sở dữ liệu cho chương trình quản lý danh sách khách hàng.
Hướng dẫn
Bước 1: thăm dò chương trình có sẵn
Tải chương trình tại file đính kèm, thực hiện các bước cài đặt cần thiết để khởi động chương trình, đọc mã và thăm dò chức năng của chương trình.
Bước 2: mô tả entity
Mô tả dữ liệu cần ngoại hóa như là các entity, mỗi entity như một dòng dữ liệu trong cơ sở dữ liệu quan hệ. Mỗi trường của entity như giá trị tại một cột tương ứng của dòng dữ liệu đó.
Với Hibernate, việc mô tả một entity được thực hiện trên class, việc mô tả một class tương ứng với một entity được thực hiện bởi hành động đánh annotation cho class và cho các trường của class đó.
Trước tiên, bổ sung thư viện Hibernate:
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.4.3.Final' Đánh dấu rằng class Customer là tương ứng với một entity: import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table public class Customer implements Cloneable { // ... }
Hibernate cần biết cách gắn một đối tượng của class customer với một dòng dữ liệu cụ thể tại database, do đó nó cần biết trường nào trong class Customer là tương ứng với khóa chính:
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
Bước 3: tạo database để Hibernate kết nối tới
Bước 4: Bổ sung một triển khai khác của CustomerService
Tạo một class mới để viết triển khai mới cho CustomerService
public class HibernateCustomerServiceImpl implements CustomerService { @Override public List<Customer> findAll() { return Collections.emptyList(); } @Override public Customer findOne(Long id) { return null; } @Override public Customer save(Customer customer) { return null; } @Override public List<Customer> save(List<Customer> customers) { return null; } @Override public boolean exists(Long id) { return false; } @Override public List<Customer> findAll(List<Long> ids) { return Collections.emptyList(); } @Override public long count() { return 0; } @Override public void delete(Long id) { } @Override public void delete(Customer customer) { } @Override public void delete(List<Customer> customers) { } @Override public void deleteAll() { } }
Thay đổi bean để app chuyển sang sử dụng triển khai này:
@Bean public CustomerService customerService() { return new HibernateCustomerServiceImpl(); }
Bước 5: chuẩn bị để hibernate có thể kết nối tới database
Để việc ánh xạ có thể diễn ra, trước tiên hibernate cần khởi động phiên làm việc của nó với database. Để thực hiện việc này trước tiên cần có drive jdbc, bổ sung thư viện này, lưu ý sử dụng đúng phiên bản phù hợp với mysql đang sử dụng:
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.11'
Ngoài ra, hibernate cần có cấu hình kết nối, phương thức xác thực, cùng với tên drive jdbc. Tất cả những thông tin này có thể được mô tả trong một file cấu hình. Tạo file hibernate.conf.xml vào trong thư mục src/main/resources:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/cms</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property> <mapping class="cg.wbd.grandemonstration.model.Customer"/> </session-factory> </hibernate-configuration>
“show_sql” gợi ý rằng các câu SQL mà Hibernate sử dụng sẽ được log ra logstream của hệ thống, “hbm2ddl.auto” gợi ý rằng khi database không có bảng, hay các bảng trong database cũ hơn so với mô tả tại entity class, hibernate sẽ tiến hành cập nhật cấu trúc các bảng.
Trong jdbc URL, cms
chính là tên của database đã tạo ở bước 3
Bước 6: cho hibernate tạo kết nối tới database
Thêm đoạn mã static sau vào class service, deploy lại dự án và xác nhận rằng không có lỗi xảy ra, kiểm tra database để thấy rằng bảng Customer đã được tạo.
static { try { SessionFactory sessionFactory = new Configuration() .configure("hibernate.conf.xml") .buildSessionFactory(); sessionFactory.close(); } catch (HibernateException e) { e.printStackTrace(); } }
Bước 7: tạo entityManager
Sau khi thành công, xóa bỏ dòng lệnh đóng session, tạo một entityManager, và lưu trữ cả sessionFactory lẫn entityManager vào những biến static để dùng trong service:
private static SessionFactory sessionFactory; private static EntityManager entityManager; static { try { sessionFactory = new Configuration() .configure("hibernate.conf.xml") .buildSessionFactory(); entityManager = sessionFactory.createEntityManager(); } catch (HibernateException e) { e.printStackTrace(); } }
Bước 8: triển khai các phương thức publish của service
Dùng sessionFactory để lấy entityManager, sau đó sử dụng entityManager để chạy query cần thiết để lấy danh sách customer:
@Override public List<Customer> findAll() { String queryStr = "SELECT c FROM Customer AS c"; TypedQuery<Customer> query = entityManager.createQuery(queryStr, Customer.class); return query.getResultList(); }
Tương tự, triển khai phương thức lấy thông tin customer:
@Override public Customer findOne(Long id) { String queryStr = "SELECT c FROM Customer AS c WHERE c.id = :id"; TypedQuery<Customer> query = entityManager.createQuery(queryStr, Customer.class); query.setParameter("id", id); return query.getSingleResult(); }
Bước 9: triển khai phương thức update Customer
Update là một thao tác sửa đổi dữ liệu. Các thao tác dạng này bắt buộc phải được thực hiện trong một transaction.
@Override public Customer save(Customer customer) { Session session = null; Transaction transaction = null; try { session = sessionFactory.openSession(); transaction = session.beginTransaction(); Customer origin = findOne(customer.getId()); origin.setName(customer.getName()); origin.setEmail(customer.getEmail()); origin.setAddress(customer.getAddress()); session.saveOrUpdate(origin); transaction.commit(); return origin; } catch (Exception e) { e.printStackTrace(); if (transaction != null) { transaction.rollback(); } } finally { if (session != null) { session.close(); } } return null; }
Leave a Reply