关于Spring Boot - 3的注意事项
这是一篇关于Spring Boot和Hibernate的笔记。
背景
这是关于 Spring Boot 和 Hibernate 的一个注释。所附的 Maven 项目是一个 Spring Boot 应用程序,打包为可执行 JAR。
- 如果您不是 Spring Boot 专家,我建议您查看我之前的注释 关于 Spring Boot 的一个注释 - 1,了解如何将 Web 应用程序打包成 JAR 文件。
- 因为我使用的是 Linux Mint 电脑,所以我将使用 MySQL 作为示例的数据库服务器。
安装 MySQL 和 MySQL Workbench
在 Linux Mint 电脑上安装 MySQL 服务器是一项简单的任务。点击 菜单 并搜索 软件管理器,您可以找到并启动 软件管理器。
如果您搜索 mysql,您会找到 mysql-server 和 mysql-workbench。然后您可以按照说明安装它们。请务必记住您为 root
用户选择的密码,您将需要它来访问 MySQL 服务器。mysql-server 和 mysql-workbench 的版本可能不是最新的,但它们应该与最新发布版本足够接近。
默认情况下,MySQL 服务器在计算机启动时启动。但在开发计算机上,您可能不希望它一直启动。您可能希望在需要时手动启动它。您可以找到 /etc/int/mysql.conf 文件,并通过 #
注释掉 start on runlevel ...
这一行。要手动启动 MySQL 服务器,您可以执行以下命令。
sudo service mysql start
您可以通过以下命令停止它。
sudo service mysql stop
您可以通过以下命令检查 MySQL 服务器是否正在运行。
sudo service mysql status
MySQL 服务器启动后,您可以启动 MySQL Workbench 连接到它。
您可以通过 MySQL Workbench 执行以下 SQL 脚本来创建数据库表并添加一些数据。
DROP DATABASE IF EXISTS experimentA;
CREATE DATABASE experimentA;
USE experimentA;
CREATE TABLE Student (
Id int(11) NOT NULL AUTO_INCREMENT,
Name varchar(100) COLLATE latin1_general_ci NOT NULL,
Score int(11) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=1
DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
INSERT INTO Student (Name, Score)
VALUES ('Song Li', 25);
INSERT INTO experimentA.Student (Name, Score)
VALUES ('Donald Trump', 100);
SELECT * FROM Student;
成功运行 SQL 脚本后,您应该会有一个名为 [Student]
的表。我们将使用此表在 Spring Boot 中尝试 Hibernate。
示例 - Spring Boot + Hibernate
附件是一个用于 JAR 打包的 Spring Boot 应用程序的 Maven 应用程序。
- 本注释旨在介绍 Spring Boot + Hibernate,所以我不会花太多时间单独介绍 Spring Boot;
- 如果您不是 Spring Boot 专家,我建议您查看我之前的注释 关于 Spring Boot 的一个注释 - 1,了解如何将 Web 应用程序打包成 JAR 文件;
由于它是一个 Maven 项目,让我们首先看一下 POM.xml。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.song.example</groupId>
<artifactId>spring-boot-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<spring-boot.version>1.5.7.RELEASE</spring-boot.version>
<hibernate.version>5.2.12.Final</hibernate.version>
<mysql.connector.version>6.0.6</mysql.connector.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration><source>1.8</source><target>1.8</target></configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals><goal>repackage</goal></goals>
<configuration>
<finalName>${artifactId}-${version}</finalName>
<mainClass>${start-class}</mainClass>
<addResources>true</addResources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
- Spring Boot 应用程序需要依赖
spring-boot-starter-web
。 - 使用 Hibernate 时需要依赖
hibernate-entitymanager
。它是 Hibernate 的顶级 Maven 包。通过包含此包,我们有效地声明了 Hibernate 所需的所有包。 - 依赖
mysql-connector-java
是连接 MySQL 数据库的 JDBC 驱动程序。 - 需要构建插件
spring-boot-maven-plugin
将应用程序打包为可执行 JAR 文件。
为了访问 MySQL 数据库中的 [Student]
表,我们需要添加一个 @Entity
类,该类在 Student.java 文件中实现。
package com.song.hibernate.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "Student")
public class Student implements java.io.Serializable {
private static final long serialVersionUID = -2724306148955297613L;
private Integer id;
private String name;
private Integer score;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id")
public Integer getId() { return this.id; }
public void setId(Integer id) { this.id = id; }
@Column(name = "Name", length = 100)
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
@Column(name = "Score")
public Integer getScore() { return this.score; }
public void setScore(Integer score) { this.score = score; }
}
为了创建一个 Hibernate SessionFactory,我们需要在 src/main/resources 目录中添加 hibernate.cfg.xml。在应用程序中,Hibernate SessionFactory 的典型用法是使其成为单例。此单例对象管理所有执行数据库操作的 Session。
- 一个 SessionFactory 是线程安全的。我们可以允许多个线程访问它。
- 一个 Session 不是线程安全的。我们需要确保只有一个线程可以使用它。完成数据库操作后,我们需要关闭会话。
<?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="connection.driver_class">
com.mysql.cj.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql:///experimentA
</property>
<property name="connection.username">root</property>
<property name="connection.password">password</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping class="com.song.hibernate.entities.Student" />
</session-factory>
</hibernate-configuration>
- hibernate.cfg.xml 文件配置 Hibernate 如何与数据库服务器通信。
<mappping />
部分告诉 Hibernate 在com.song.hibernate.entities.Student
类中查找@Entity
。
ApplicationStart.java 负责启动 Spring Boot 应用程序并初始化 @Bean 来创建单例 SessionFactory。
package com.song.web.boot;
import javax.servlet.Filter;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Scope;
import com.song.web.filter.NocacheFilter;
@SpringBootApplication
@ComponentScan({ "com.song.web.controller" })
public class ApplicationStart extends SpringBootServletInitializer {
public static void main (String[] args) {
SpringApplication.run(ApplicationStart.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ApplicationStart.class);
}
@Bean
public EmbeddedServletContainerCustomizer portCustomizer() {
return (container -> { container.setPort(8090); });
}
@Bean
public FilterRegistrationBean noCacheFilter() {
Filter filter = new NocacheFilter();
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(1);
return registration;
}
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public SessionFactory sessionFactory() {
return new Configuration().configure().buildSessionFactory();
}
}
ApplicationStart
类是一个标准的 Spring Boot 启动类。
- @Bean 方法
portCustomizer()
配置应用程序监听端口号8090
。 - @Bean 方法
noCacheFilter()
配置应用程序发送头以禁用所有浏览器缓存。 - @Bean 方法
sessionFactory()
基于 hibernate.cfg.xml 中的配置创建一个SessionFactory
。它是一个单例,可以@Autowired
到使用它的地方。
在此示例中,在 @Bean 方法中创建 SessionFactory 的方式是实验性的。它很方便,但存在问题。如果数据库服务器没有运行,应用程序将无法启动,因为 SessionFactory 的创建将失败。您可能仍然希望使用标准的单例模式来创建 SessionFactory。您可以参考 此示例,了解如何创建 SessionFactory。
然后我们可以在 ExampleController.java 中使用 SessionFactory 查询数据库。
package com.song.web.controller;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.song.hibernate.entities.Student;
@Controller
public class ExampleController {
@Autowired
private SessionFactory sessionFactory;
@ResponseBody
@RequestMapping(value = "/getStudent", method=RequestMethod.GET)
public Student getStudent() {
Student student = null;
try(Session session = sessionFactory.openSession()) {
student = session.get(Student.class, 2);
}
return student;
}
}
- 单例 SessionFactory 被
@Autowired
注入到ExampleController
中。 - 单例 SessionFactory 用于在
getStudent()
方法中打开会话。 - 一个 Session 是一个 AutoCloseable 对象。
- 一个
Student
对象通过 Session 获取。它通过getStudent()
方法响应 HTTP 请求。
运行应用程序
如果您将项目加载到 Eclipse 中,可以直接在 Eclipse 中运行/调试应用程序,选择 ApplicationStart
类作为启动类。
您还可以通过以下命令通过 Maven 运行应用程序。
mvn spring-boot:run
成功执行 mvn clean install
后,您可以通过以下命令启动应用程序。
java -jar target/spring-boot-example-0.0.1-SNAPSHOT.jar
在 MySQL 服务器启动后,如果您启动应用程序并在 POSTMAN
中发出 GET
请求 https://:8090/getStudent
,您将看到以下响应。
摘要
- 要在应用程序中使用 Hibernate,我们需要添加 Maven 依赖项
hibernate-entitymanager
。 - 要连接到数据库服务器,我们需要添加相应的驱动程序依赖项。在此示例中,它是
mysql-connector-java
。 - 我们需要添加一个 hibernate.cfg.xml 文件来配置 Hibernate SessionFactory 的创建方式。此文件的位置可以在硬盘上的任何位置。但在 Spring Boot 应用程序中,默认位置是 src/main/resources 目录。
- 通常的做法是创建一个单例 SessionFactory,用于打开所有数据库会话。
- 一个 SessionFactory 是线程安全的,但一个 Session 不是线程安全的。
- 一个 Session 对象是一个 AutoCloseable 对象。您需要确保在使用后将其关闭。
关注点
- 这是关于 Spring Boot 和 Hibernate 的一个注释;
- 希望您喜欢我的帖子,并希望这篇说明能对您有所帮助。
历史
- 2017 年 12 月 18 日:首次修订