JavaRush /Blog Java /Random-VI /Giới thiệu Maven, Spring, MySQL, Hibernate và ứng dụng CR...
Макс
Mức độ

Giới thiệu Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên (phần 3)

Xuất bản trong nhóm
Chào buổi chiều. Trong bài viết này tôi muốn chia sẻ lần đầu tiên tôi làm quen với những thứ như Maven, Spring, Hibernate, MySQL và Tomcat trong quá trình tạo một ứng dụng CRUD đơn giản. Đây là phần thứ ba của 4. Bài viết chủ yếu dành cho những người đã hoàn thành 30-40 cấp độ ở đây, nhưng chưa vượt ra ngoài Java thuần túy và mới bắt đầu (hoặc sắp bắt đầu) bước vào thế giới mở với tất cả những công nghệ, khuôn khổ này và những từ xa lạ khác. Giới thiệu Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên (phần 3) - 1Đây là phần thứ ba của bài viết “Giới thiệu về Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên”. Các phần trước có thể được xem bằng cách theo các liên kết:

Nội dung:

Tạo và kết nối cơ sở dữ liệu

Chà, đã đến lúc bắt đầu làm việc với cơ sở dữ liệu. Trước khi kết nối Hibernate và suy nghĩ xem nó sẽ hoạt động như thế nào ở đó, trước tiên chúng ta hãy xem xét chính cơ sở dữ liệu, tức là. Hãy tạo nó, kết nối nó, tạo nó và điền vào dấu hiệu. Chúng tôi sẽ sử dụng MySQL DBMS (Hệ thống quản lý cơ sở dữ liệu) (tất nhiên, trước tiên bạn phải tải xuống và cài đặt). SQL (Ngôn ngữ truy vấn có cấu trúc) là ngôn ngữ lập trình khai báo được sử dụng để tạo, sửa đổi và thao tác dữ liệu trong cơ sở dữ liệu quan hệ. Trong cơ sở dữ liệu như vậy, dữ liệu được lưu trữ dưới dạng bảng. Ứng dụng giao tiếp với cơ sở dữ liệu như thế nào (truyền truy vấn SQL đến cơ sở dữ liệu và trả về kết quả). Đối với điều này, Java có một thứ như JDBC (Kết nối cơ sở dữ liệu Java) , nói một cách đơn giản, là một tập hợp các giao diện và các lớp để làm việc với cơ sở dữ liệu. Để tương tác với cơ sở dữ liệu, bạn cần tạo kết nối; đối với điều này, gói java.sqlcó lớp Connection. Có một số cách để thiết lập kết nối, ví dụ bạn có thể sử dụng phương thức getConnectionlớp DriverManager. Tuy nhiên, việc tương tác với cơ sở dữ liệu không được thực hiện trực tiếp vì có nhiều cơ sở dữ liệu và chúng khác nhau. Vì vậy, mỗi loại đều có Trình điều khiển JDBC riêng, sử dụng trình điều khiển này sẽ thiết lập kết nối tới cơ sở dữ liệu. Vì vậy, trước hết, để không bị phân tâm vì điều này sau này, hãy cài đặt trình điều khiển MySQL . Hãy thêm pom.xmlphụ thuộc sau:
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>
Bây giờ hãy tạo cơ sở dữ liệu. Xem -> Công cụ Windows -> Cơ sở dữ liệu - bảng cơ sở dữ liệu sẽ mở ra. Mới (màu xanh +) -> Nguồn dữ liệu -> MySQL - một cửa sổ sẽ mở trong đó bạn cần chỉ định tên người dùng và mật khẩu, chúng tôi đã đặt chúng khi cài đặt MySQL (ví dụ: tôi đã sử dụng root và root). Cổng (mặc định cho MySQL 3306), tên, v.v. cứ để nguyên như vậy. Bạn có thể kiểm tra kết nối bằng nút " Test Connection ". Giới thiệu Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên (phần 3) - 2Nhấn OK và bây giờ chúng ta đã kết nối được với máy chủ MySQL. Tiếp theo, hãy tạo một cơ sở dữ liệu. Để thực hiện việc này, bạn có thể viết một tập lệnh trong bảng điều khiển mở ra:
CREATE DATABASE test
Nhấp vào Thực thi và cơ sở dữ liệu đã sẵn sàng, bây giờ bạn có thể kết nối nó. Để thực hiện việc này, hãy quay lại Thuộc tính nguồn dữ liệu và nhập tên cơ sở dữ liệu (kiểm tra) vào trường Cơ sở dữ liệu, sau đó nhập lại tên người dùng và mật khẩu và nhấp vào OK. Bây giờ chúng ta cần tạo một cái bàn. Bạn có thể sử dụng các công cụ đồ họa, nhưng đây là lần đầu tiên bạn nên viết một đoạn mã bằng tay để xem nó trông như thế nào:
USE test;

CREATE TABLE films
(
  id int(10) PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(100) NOT NULL,
  year int(4),
  genre VARCHAR(20),
  watched BIT DEFAULT false  NOT NULL
)
COLLATE='utf8_general_ci';
CREATE UNIQUE INDEX films_title_uindex ON films (title);

INSERT INTO `films` (`title`,`year`,`genre`, watched)
VALUES
  ("Inception", 2010, "sci-fi", 1),
  ("The Lord of the Rings: The Fellowship of the Ring", 2001, "fantasy", 1),
  ("Tag", 2018, "comedy", 0),
  ("Gunfight at the O.K. Corral", 1957, "western", 0),
  ("Die Hard", 1988, "action", 1);
Một bảng được tạo với tên filmscó cột id, titlev.v. Đối với mỗi cột, loại được chỉ định (kích thước đầu ra tối đa trong ngoặc đơn).
  • PRIMARY KEY- đây là khóa chính, dùng để xác định duy nhất một bản ghi trong bảng (ngụ ý tính duy nhất)
  • AUTO_INCREMENT— giá trị sẽ được tạo tự động (tất nhiên nó sẽ khác 0, vì vậy bạn không cần phải chỉ định giá trị này)
  • NOT NULL- ở đây mọi thứ cũng rõ ràng rồi, không thể để trống được
  • DEFAULT- đặt giá trị mặc định
  • COLLATE- mã hóa
  • CREATE UNIQUE INDEX- làm cho lĩnh vực này trở nên độc đáo
  • INSERT INTO- thêm bản ghi vào bảng
Kết quả là một dấu hiệu như thế này: Có lẽ đáng để thử kết nối với nó, ngay bây giờ, tách biệt với ứng dụng web của chúng ta. Điều gì sẽ xảy ra nếu một số vấn đề phát sinh với việc này thì chúng tôi sẽ giải quyết ngay. Còn không thì sau này chúng ta sẽ connect Hibernate , làm gì đó, config, mày mò, và nếu có lộn xộn ở đâu đó thì ít nhất chúng ta cũng biết rằng vấn đề không nằm ở đây. Chà, để kiểm tra kết nối, tạm thời hãy tạo một phương thức main. Về nguyên tắc, bạn có thể đặt nó ở bất cứ đâu, ngay cả trong lớp trình điều khiển, ngay cả trong mô hình hoặc cấu hình, không thành vấn đề, bạn chỉ cần sử dụng nó để đảm bảo mọi thứ đều ổn với kết nối và bạn có thể xóa nó. Nhưng để cẩn thận hơn, hãy tạo một lớp riêng cho nó Main:
package testgroup.filmography;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/test";
        String username = "root";
        String password = "root";
        System.out.println("Connecting...");

        try (Connection connection = DriverManager.getConnection(url, username, password)) {
            System.out.println("Connection successful!");
        } catch (SQLException e) {
            System.out.println("Connection failed!");
            e.printStackTrace();
        }
    }
}
Mọi thứ ở đây đều đơn giản, chúng tôi đặt tham số kết nối cho cơ sở dữ liệu của mình và cố gắng tạo kết nối. Hãy khởi động cái này mainvà xem xét. Vì vậy, tôi gặp một ngoại lệ, một số vấn đề về múi giờ và một số cảnh báo khác về SSL. Sau khi duyệt Internet, bạn có thể phát hiện ra rằng đây là một sự cố khá phổ biến và khi sử dụng các phiên bản trình điều khiển khác nhau (mysql-connector-java), nó có thể xảy ra lỗi khác nhau. Ví dụ, tôi phát hiện bằng thực nghiệm rằng khi sử dụng phiên bản 5.1.47 không có ngoại lệ do múi giờ, kết nối được tạo bình thường nhưng cảnh báo SSL vẫn bật lên. Với một số phiên bản khác, dường như có một ngoại lệ liên quan đến SSL chứ không chỉ là một cảnh báo. Được rồi, đó không phải là vấn đề. Bạn có thể thử giải quyết vấn đề này một cách riêng biệt, nhưng chúng ta sẽ không đi sâu vào vấn đề này ngay bây giờ. Giải pháp cho vấn đề này khá đơn giản, bạn cần chỉ định các tham số bổ sung trong url , cụ thể là serverTimezone, nếu sự cố xảy ra với múi giờ và useSSLnếu sự cố xảy ra với SSL:
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Minsk&useSSL=false";
Bây giờ chúng tôi đã đặt múi giờ và tắt SSL. Chúng tôi khởi chạy lại mainvà thì đấy - Kết nối thành công! Chà, thật tuyệt, chúng tôi đã tìm ra cách tạo kết nối. Lớp Maincơ bản đã hoàn thành nhiệm vụ của mình, bạn có thể xóa nó đi.

ORM và JPA

Nói một cách hay, để hiểu rõ hơn, tốt hơn hết bạn nên bắt đầu làm quen với cơ sở dữ liệu theo thứ tự ngay từ đầu, không có chế độ ngủ đông và những thứ khác. Do đó, sẽ là một ý tưởng hay nếu bạn tìm một số hướng dẫn và trước tiên hãy thử làm việc với các lớp JDBC, viết các truy vấn SQL theo cách thủ công, v.v. Chà, hãy chuyển sang mô hình ORM ngay. Điều đó có nghĩa là gì? Tất nhiên, một lần nữa bạn nên đọc riêng về vấn đề này, nhưng tôi sẽ cố gắng mô tả ngắn gọn về nó. ORM (Ánh xạ quan hệ đối tượng hoặc ánh xạ quan hệ đối tượng) là một công nghệ để ánh xạ các đối tượng vào các cấu trúc cơ sở dữ liệu quan hệ, tức là. để biểu diễn đối tượng Java của chúng ta dưới dạng một hàng trong bảng. Nhờ ORM, bạn không phải lo lắng về việc viết các tập lệnh SQL và tập trung làm việc với các đối tượng. Làm thế nào để sử dụng nó. Java có một điều tuyệt vời khác là JPA (Java Persistence API), triển khai khái niệm ORM. JPA là một đặc tả như vậy; nó mô tả các yêu cầu đối với các đối tượng, nó xác định các giao diện và chú thích khác nhau để làm việc với cơ sở dữ liệu. JPA về cơ bản là một mô tả, một tiêu chuẩn. Do đó, có nhiều cách triển khai cụ thể, một trong số đó (và một trong những cách phổ biến nhất) là Hibernate, đây là bản chất của framework này. Hibernate là một triển khai đặc tả JPA được thiết kế để giải quyết các vấn đề về ánh xạ quan hệ đối tượng (ORM). Chúng ta cần kết nối toàn bộ điều này với dự án của mình. Ngoài ra, để Spring của chúng ta không đứng ngoài cuộc và cũng tham gia vào tất cả phong trào này với cơ sở dữ liệu, chúng ta cần kết nối thêm một vài mô-đun, bởi vì mọi thứ chúng tôi nhận được từ phần phụ thuộc spring-webmvc không còn đủ cho việc này nữa. Chúng ta cũng sẽ cần spring-jdbc để làm việc với cơ sở dữ liệu, spring-tx để hỗ trợ các giao dịch và spring-orm để làm việc với Hibernate. Hãy thêm các phụ thuộc vào pom.xml:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>5.1.1.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.3.7.Final</version>
</dependency>
Hai sự phụ thuộc này là đủ. javax.persistence-apisẽ đến cùng với hibernate-corespring-jdbcspring-tx cùng với spring-orm .

thực thể

Vì vậy, chúng tôi muốn các đối tượng lớp có Filmthể được lưu trữ trong cơ sở dữ liệu. Để làm được điều này, lớp phải đáp ứng một số điều kiện. Trong JPA có một thứ gọi là Thực thể cho việc này . Lớp thực thể là một lớp POJO thông thường , có các trường riêng và các phương thức getter và setters cho chúng. Nó phải có một hàm tạo không riêng tư không có tham số (hoặc hàm tạo mặc định) và nó phải có khóa chính, tức là. thứ gì đó sẽ xác định duy nhất từng bản ghi của lớp này trong cơ sở dữ liệu. Bạn cũng có thể đọc riêng về tất cả các yêu cầu đối với một lớp như vậy. Hãy biến lớp của chúng ta Filmthành một thực thể bằng cách sử dụng các chú thích JPA:
package testgroup.filmography.model;

import javax.persistence.*;

@Entity
@Table(name = "films")
public class Film {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "title")
    private String title;

    @Column(name = "year")
    private int year;

    @Column(name = "genre")
    private String genre;

    @Column(name = "watched")
    private boolean watched;

    // + getters and setters
}
  • @Entity- chỉ ra rằng lớp này là một thực thể.
  • @Table- trỏ tới một bảng cụ thể để hiển thị thực thể này.
  • @Id— chỉ ra rằng trường này là khóa chính, tức là thuộc tính này sẽ được sử dụng để xác định từng mục duy nhất.
  • @Column— kết nối một trường với một cột trong bảng. Nếu tên cột của trường và bảng giống nhau, bạn có thể bỏ qua chúng.
  • @GeneratedValue— thuộc tính sẽ được tạo tự động; bạn có thể chỉ định cách thực hiện trong ngoặc đơn. Bây giờ chúng ta sẽ không hiểu chính xác các chiến lược khác nhau hoạt động như thế nào. Chỉ cần biết rằng trong trường hợp này, mỗi giá trị mới sẽ tăng thêm 1 so với giá trị trước đó.
Đối với mỗi thuộc tính, bạn có thể chỉ định thêm nhiều thứ khác, ví dụ: giá trị nào khác 0 hoặc duy nhất, chỉ định giá trị mặc định, kích thước tối đa, v.v. Điều này sẽ hữu ích nếu bạn cần tạo bảng dựa trên lớp này; Hibernate có tùy chọn này. Nhưng chúng tôi đã tự tạo bảng và định cấu hình tất cả các thuộc tính, vì vậy chúng tôi có thể thực hiện mà không cần nó. Một lưu ý nhỏ.Tài liệu Hibernate khuyên bạn nên sử dụng chú thích không phải trên các trường mà trên getters. Tuy nhiên, sự khác biệt giữa các phương pháp này khá nhỏ và trong ứng dụng đơn giản của chúng tôi, điều này sẽ không có bất kỳ tác động nào. Ngoài ra, hầu hết mọi người đều đặt chú thích phía trên các trường. Vì vậy, chúng ta hãy để nó như thế này, nó trông gọn gàng hơn.

Thuộc tính ngủ đông

Chà, hãy bắt đầu thiết lập Hibernate của chúng ta. Và trước hết, hãy đặt một số thông tin, chẳng hạn như tên người dùng và mật khẩu, url và những thông tin khác vào một tệp riêng. Tất nhiên, bạn có thể chỉ định chúng như một dòng thông thường ngay trong lớp, như chúng ta đã làm khi kiểm tra kết nối ( String username = "root";và sau đó chuyển nó sang phương thức tạo kết nối). Nhưng vẫn đúng hơn nếu lưu trữ dữ liệu tĩnh như vậy trong một số propertytệp. Và nếu, ví dụ, bạn cần thay đổi cơ sở dữ liệu, thì bạn sẽ không phải xem qua tất cả các lớp và tìm nơi nó được sử dụng, chỉ cần thay đổi giá trị trong tệp này một lần là đủ. Hãy tạo một tệp db.properties trong thư mục tài nguyên :
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Minsk&useSSL=false
jdbc.username=root
jdbc.password=root

hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
hibernate.show_sql=true
Chà, mọi thứ đều rõ ràng ở trên, các tham số để kết nối với cơ sở dữ liệu, tức là. tên lớp trình điều khiển, url, tên người dùng và mật khẩu. hibernate.dialect- thuộc tính này cần thiết để cho Hibernate biết phiên bản cụ thể nào của ngôn ngữ SQL được sử dụng. Thực tế là trong mọi DBMS, để mở rộng khả năng, thêm một số chức năng hoặc tối ưu hóa thứ gì đó, họ thường hiện đại hóa ngôn ngữ một chút. Kết quả là mỗi DBMS có phương ngữ SQL riêng. Giống như tiếng Anh, có vẻ như ngôn ngữ giống nhau, nhưng ở Úc, Mỹ hoặc Anh thì sẽ hơi khác một chút và một số từ có thể có nghĩa khác nhau. Và để tránh mọi vấn đề về hiểu biết, bạn cần trực tiếp nói với Hibernate chính xác những gì nó phải giải quyết. hibernate.show_sql— nhờ thuộc tính này, các truy vấn tới cơ sở dữ liệu sẽ được hiển thị trong bảng điều khiển. Điều này là không cần thiết, nhưng với thứ này ít nhất bạn có thể xem điều gì đang xảy ra, nếu không thì có vẻ như Hibernate đang thực hiện một loại phép thuật nào đó. Tất nhiên, nó sẽ không hoàn toàn rõ ràng để hiển thị; tốt hơn là sử dụng một loại máy ghi nhật ký nào đó cho việc này, nhưng đó là việc cần để lúc khác, bây giờ nó sẽ làm được.

Cấu hình ngủ đông

Hãy chuyển sang thiết lập cấu hình. configHãy tạo một lớp trong gói HibernateConfig:
package testgroup.filmography.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@ComponentScan(basePackages = " testgroup.filmography")
@EnableTransactionManagement
@PropertySource(value = "classpath:db.properties")
public class HibernateConfig {
    private Environment environment;

    @Autowired
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        return properties;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan("testgroup.filmography.model");
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    @Bean
    public HibernateTransactionManager transactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory().getObject());
        return transactionManager;
    }
}
Ở đây có khá nhiều thứ mới nên tốt nhất bạn nên tìm kiếm thêm thông tin về từng món ở nhiều nguồn khác nhau. Chúng ta hãy lướt qua nó một cách ngắn gọn ở đây.
  • Chúng tôi @Configurationđã @ComponentScantìm ra khi chúng tôi tham gia lớp học WebConfig.
  • @EnableTransactionManagement— cho phép bạn sử dụng nó TransactionManagerđể quản lý các giao dịch. Hibernate làm việc với cơ sở dữ liệu bằng cách sử dụng các giao dịch; chúng cần thiết để một tập hợp các hoạt động nhất định được thực hiện dưới dạng một tổng thể duy nhất, tức là. nếu phương thức này gặp vấn đề với bất kỳ thao tác nào thì tất cả các thao tác khác sẽ không được thực thi, do đó nó không xảy ra như trong ví dụ cổ điển với việc chuyển tiền, khi thao tác rút tiền từ một tài khoản đã hoàn tất, nhưng thao tác viết thư cho người khác không thành công, kết quả là tiền biến mất.
  • @PropertySource- kết nối tệp thuộc tính mà chúng tôi đã tạo gần đây.
  • Environment- để lấy các thuộc tính từ propertymột tập tin.
  • hibernateProperties- phương thức này cần thiết để biểu diễn các thuộc tính Hibernate dưới dạng đối tượng Properties
  • DataSource- được sử dụng để tạo kết nối tới cơ sở dữ liệu. Đây là một giải pháp thay thế cho DriverManager mà chúng tôi đã sử dụng trước đó khi tạo tệp main. Các tài liệu nói rằng DataSourcenó là thích hợp hơn để sử dụng. Tất nhiên, đó là những gì chúng tôi sẽ làm, không quên đọc trên Internet xem sự khác biệt và ưu điểm là gì. Một lợi ích đặc biệt là khả năng tạo Nhóm kết nối cơ sở dữ liệu (DBCP).
  • sessionFactory— để tạo các phiên với sự trợ giúp của các hoạt động với các đối tượng thực thể được thực hiện. Ở đây chúng ta đặt nguồn dữ liệu, thuộc tính Hibernate và gói nào chúng ta cần tìm các lớp thực thể.
  • transactionManager- để cấu hình trình quản lý giao dịch.
Một lưu ý nhỏ về DataSource. Tài liệu nói rằng việc sử dụng triển khai tiêu chuẩn, cụ thể là DriverManagerDataSource, không được khuyến khích, bởi vì nó chỉ là sự thay thế cho việc tổng hợp kết nối thông thường và thường chỉ phù hợp cho các thử nghiệm, v.v. Đối với một ứng dụng thông thường, tốt nhất nên sử dụng một số loại thư viện DBCP. Chà, đối với ứng dụng của chúng ta, tất nhiên những gì chúng ta có là đủ, nhưng để hoàn thiện bức tranh, có lẽ chúng ta vẫn sẽ sử dụng một cách triển khai khác như đã khuyên. Hãy thêm pom.xmlphụ thuộc sau:
<dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-dbcp</artifactId>
            <version>9.0.10</version>
</dependency>
Và trong phương thức dataSourcelớp HibernateConfig, chúng tôi thay thế nó DriverManagerDataSourcebằng BasicDataSourcemột từ gói org.apache.tomcat.dbcp.dbcp2:
BasicDataSource dataSource = new BasicDataSource();
Chà, mọi thứ dường như đã xong, cấu hình đã sẵn sàng, tất cả những gì còn lại là thêm nó vào AppInitializer :
protected Class<?>[] getRootConfigClasses() {
        return new Class[]{HibernateConfig.class};
    }

Lớp truy cập dữ liệu

Cuối cùng đã đến lúc bắt đầu với DAO của chúng tôi. Chúng tôi đến lớp FilmDAOImplvà trước hết chúng tôi xóa danh sách dùng thử ở đó, chúng tôi không cần nó nữa. Hãy thêm một nhà máy phiên và xử lý nó.
private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
Để bắt đầu, chúng tôi sẽ tạo một phương thức hiển thị một trang có danh sách các phim, trong đó chúng tôi sẽ nhận được một phiên và đưa ra yêu cầu tới cơ sở dữ liệu (lấy tất cả các bản ghi và tạo thành một danh sách):
public List<Film> allFilms() {
        Session session = sessionFactory.getCurrentSession();
        return session.createQuery("from Film").list();
    }
Có 2 điểm ở đây. Đầu tiên, một cảnh báo đã được hiển thị. Điều này là do thực tế là chúng ta muốn nhận một tham số được tham số hóa List<Film>, nhưng phương thức trả về đơn giản Listvì tại thời điểm biên dịch, không biết yêu cầu sẽ trả về loại nào. Vì vậy, ý tưởng này cảnh báo chúng ta rằng chúng ta đang thực hiện một chuyển đổi không an toàn, điều này có thể dẫn đến rắc rối. Có một số cách chính xác hơn để làm điều này để không nảy sinh câu hỏi như vậy. Bạn có thể tìm kiếm thông tin trên Internet. Nhưng chúng ta đừng bận tâm đến điều này bây giờ. Thực tế là chúng tôi biết chính xác loại nào sẽ được trả về, vì vậy sẽ không có vấn đề gì phát sinh ở đây, bạn chỉ cần bỏ qua cảnh báo. Tuy nhiên, để không bị mỏi mắt, bạn có thể treo chú thích phía trên phương thức @SupressWarning("unchecked"). Bằng cách này, chúng tôi nói với trình biên dịch rằng, cảm ơn bạn thân, vì sự quan tâm của bạn, nhưng tôi biết mình đang làm gì và kiểm soát mọi thứ, vì vậy bạn có thể thư giãn và không phải lo lắng về phương pháp này. Thứ hai, ý tưởng được gạch chân màu đỏ " from Film". Đó chỉ là một truy vấn HQL (Ngôn ngữ truy vấn ngủ đông) và ý tưởng không hiểu liệu mọi thứ đều đúng hay có lỗi. Bạn có thể vào phần cài đặt ý tưởng và điều chỉnh mọi thứ theo cách thủ công (tìm trên Internet nếu quan tâm). Hoặc bạn có thể chỉ cần thêm hỗ trợ cho Hibernate framework, để thực hiện việc này, nhấp chuột phải vào dự án, chọn Add Framework Support , đánh dấu vào ô Hibernate và nhấn OK. Sau này, rất có thể trong lớp thực thể ( Film) rất nhiều thứ cũng sẽ được gạch chân màu đỏ, chẳng hạn như nơi chú thích @Table(name = "films")sẽ đưa ra cảnh báo Không thể giải quyết bảng 'phim' . Một lần nữa, không có gì sai ở đây cả, đây không phải là lỗi thiết kế, mọi thứ sẽ biên dịch và hoạt động. Ý tưởng này được nhấn mạnh vì nó không biết gì về căn cứ của chúng tôi. Để khắc phục điều này, hãy tích hợp ý tưởng với cơ sở dữ liệu. View -> Tool Windows -> Persistense (một tab sẽ mở ra) -> chuột phải, chọnAssign Data Sources -> trong Data Source, chỉ định kết nối tới cơ sở dữ liệunhấn OK . Giới thiệu Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên (phần 3) - 3Khi tất cả những điều này đã được giải quyết, vẫn còn lại một cái gì đó. Hãy đi đến một cấp độ cao hơn, đến dịch vụ. Trong lớp, FilmServiceImplchúng ta đánh dấu allFilmsphương thức spring bằng một chú thích @Transactional, điều này sẽ cho biết rằng phương thức đó nên được thực thi trong một giao dịch (nếu không có điều này, Hibernate sẽ từ chối hoạt động):
@Transactional
public List<Film> allFilms() {
    return filmDAO.allFilms();
}
Vì vậy, mọi thứ đã sẵn sàng ở đây, bạn không cần phải chạm vào bất cứ thứ gì trong bộ điều khiển. Chà, có vẻ như thời điểm của sự thật đã đến, hãy nhấp vào Chạy và xem điều gì sẽ xảy ra. Giới thiệu Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên (phần 3) - 4Và đây là bảng hiệu của chúng tôi, và lần này nó được lấy không phải từ danh sách mà chúng tôi tự lập ngay trên lớp mà từ cơ sở dữ liệu. Tuyệt vời, mọi thứ dường như đang hoạt động. Bây giờ chúng ta thực hiện tất cả các thao tác CRUD khác theo cách tương tự bằng cách sử dụng các phương thức phiên. Lớp kết quả trông như thế này:
package testgroup.filmography.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import testgroup.filmography.model.Film;

import java.util.List;

@Repository
public class FilmDAOImpl implements FilmDAO {
    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Film> allFilms() {
        Session session = sessionFactory.getCurrentSession();
        return session.createQuery("from Film").list();
    }

    @Override
    public void add(Film film) {
        Session session = sessionFactory.getCurrentSession();
        session.persist(film);
    }

    @Override
    public void delete(Film film) {
        Session session = sessionFactory.getCurrentSession();
        session.delete(film);
    }

    @Override
    public void edit(Film film) {
        Session session = sessionFactory.getCurrentSession();
        session.update(film);
    }

    @Override
    public Film getById(int id) {
        Session session = sessionFactory.getCurrentSession();
        return session.get(Film.class, id);
    }
}
Bây giờ tất cả những gì còn lại là đừng quên truy cập dịch vụ và thêm chú thích vào các phương thức @Transactional. Thế là xong, sẵn sàng. Bây giờ bạn có thể chạy và kiểm tra. Nhấp vào liên kết và nút, cố gắng thêm/xóa/chỉnh sửa các mục. Nếu mọi thứ được thực hiện chính xác thì nó sẽ hoạt động. Bây giờ đây là một ứng dụng CRUD chính thức sử dụng Hibernate, Spring, MySQL. Còn tiếp... Giới thiệu Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên (phần 1) Giới thiệu Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên (phần 2) Giới thiệu Maven, Spring, MySQL, Hibernate và Ứng dụng CRUD đầu tiên (phần 3) Giới thiệu về Maven, Spring, MySQL, Hibernate và ứng dụng CRUD đầu tiên (phần 4)
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION