1,引言
Hibernate是一个全自动的ORM框架。ORM框架通过其独特的优势,可以简化开发、提高可维护性、跨数据库支持和提高性能等。为开发者节约大量的时间(当您用过其它的持久层框架后,你会对这句话深有体会)。
Spring Data JPA是由Spring公司开发的JPA应用框架,用于整合市面上已有的ORM框架,它默认使用Hibernate,可见Hibernate仍然是一个强大且稳定的持久层解决方案。
- 请事先准备一个可以访问的MySQL数据库,记录下访问连接,用户名,密码。
2,创建项目
创建一个名为hibernate-demo的项目,使用Maven+JDK17。不会的请看 IntelliJ IDEA快速创建Spring Boot项目
3,编写代码
3.1 整体结构
最终项目结构,如下图。
3.3 修改pom.xml
这里用的springboot3.x的版本,对应的MySQL驱动需要mysql-connector-j。修改完成后,更新maven,等待资源下载完成。
<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
<artifactId>hibernate-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 为Spring Boot项目提供一系列默认的配置和依赖管理-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring Boot核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Spring Boot单元测试和集成测试的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot构建Web应用程序的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot使用Spring Data JPA的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql驱动-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
</dependencies>
</project>
3.4 在resources下创建application.properties文件
需要配置好自己的数据库连接,用户名,密码。
#数据库连接
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
#数据库用户名
spring.datasource.primary.username=您的数据库用户名
#数据库密码
spring.datasource.primary.password=您的数据库密码
#自动更新数据库
spring.jpa.properties.hibernate.hbm2ddl.auto=update
#显示sql
spring.jpa.show-sql=true
#在视图渲染过程中不执行数据库查询
spring.jpa.open-in-view=false
3.5 将Main类,修改为Spring Boot启动类
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
3.6 创建entity包和User类
User类就是实体类,和数据库中的表对应。
package org.example.entity;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.Date;
@Entity
@Table(name = "t_user")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long createrId;
private Date createTime;
private Long modifierId;
private Date modificationTime;
private String name;
private String phone;
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getCreaterId() {
return createrId;
}
public void setCreaterId(Long createrId) {
this.createrId = createrId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Long getModifierId() {
return modifierId;
}
public void setModifierId(Long modifierId) {
this.modifierId = modifierId;
}
public Date getModificationTime() {
return modificationTime;
}
public void setModificationTime(Date modificationTime) {
this.modificationTime = modificationTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
3.7 创建dao包和PrimaryDaoService类、PrimaryDaoServiceImpl类
dao包中的类就是数据库操作类,封装了数据库操作的方法。
package org.example.dao;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
public interface PrimaryDaoService {
public <T> void save(T o);
public <T> void delete(T o);
public <T> void update(T o);
public <T> T get(Class<T> c, Serializable id);
public List<Map<String, Object>> getListBySql(String sql);
}
package org.example.dao;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import org.example.entity.User;
import org.hibernate.query.sql.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Repository
public class PrimaryDaoServiceImpl implements PrimaryDaoService {
@PersistenceContext(unitName = "primaryEntityManager")
private EntityManager entityManager;
@Override
public <T> void save(T o) {
if (null != o) {
if (o instanceof User) {
User data = (User) o;
data.setCreateTime(new Date());
data.setModificationTime(new Date());
data.setCreaterId(-1l);
data.setModifierId(-1l);
}
entityManager.persist(o);
}
}
@Override
public <T> void delete(T o) {
if (null != o) {
entityManager.remove(o);
}
}
@Override
public <T> void update(T o) {
if (null != o) {
entityManager.merge(o);
}
}
@Override
public <T> T get(Class<T> c, Serializable id) {
if (null != id) {
return (T) entityManager.find(c, id);
}
return null;
}
@Transactional(readOnly = true)
@Override
public List<Map<String, Object>> getListBySql(String sql) {
Query q = entityManager.createNativeQuery(sql);
q.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return q.getResultList();
}
}
3.8 创建controller包和UserController类
UserController类用于测试,正常情况下还需要创建service层,在service层操作数据库,但是这里为了方便测试,就直接在controller层操作数据库。
注意@Transactional(value = “primaryTransactionManager”)是事务注解,增、删、改数据时,必须加这个注解才能成功。
package org.example.controller;
import org.example.dao.PrimaryDaoService;
import org.example.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/UserController")
public class UserController {
@Autowired
protected PrimaryDaoService primaryDao;
@RequestMapping(value = "/test")
@ResponseBody
@Transactional(value = "primaryTransactionManager")
public Object test() throws Exception {
User user = new User();
user.setName("张三");
user.setPhone("12345678901");
primaryDao.save(user);
return user;
}
}
3.9 创建conf包和PrimaryDbConfig类
PrimaryDbConfig类用于配置JPA相关信息。
package org.example.conf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
/*
*
* 数据库配置
*
* basePackages:JPA扫描配置
* entityManagerFactoryRef:实体扫描配置
* transactionManagerRef:事务配置
*
* */
@Configuration
@EnableJpaRepositories(basePackages = "org.example.dao", entityManagerFactoryRef = "primaryEntityManager", transactionManagerRef = "primaryTransactionManager")
public class PrimaryDbConfig {
private final Logger log = LoggerFactory.getLogger(getClass());
private DataSource dataSource;
private LocalContainerEntityManagerFactoryBean entityManager;
/*
* 创建数据库连接
* @Primary 配置多个数据源时,用于标记主库
* @ConfigurationProperties 指定配置文件中的属性前缀
*
* */
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
@Bean(name = "primaryDataSource")
public DataSource primaryDataSource() {
dataSource = DataSourceBuilder.create().build();
log.info("正在连接数据库1...");
return dataSource;
}
/*
* 实体扫描配置
*
* 方法名与类注解中的entityManagerFactoryRef的值保持一致,配置多个数据源时方法名不能相同
*
* */
@Bean
@Primary
LocalContainerEntityManagerFactoryBean primaryEntityManager(EntityManagerFactoryBuilder builder) {
log.info("正在扫描接数据库1的实体类...");
entityManager = builder.dataSource(dataSource).packages("org.example.entity")
.persistenceUnit("primaryPersistenceUnit").build();
return entityManager;
}
/*
* 事务配置
*
* 方法名与类注解中的transactionManagerRef的值保持一致,配置多个数据源时方法名不能相同
*
* */
@Bean
@Primary
PlatformTransactionManager primaryTransactionManager(EntityManagerFactoryBuilder builder) {
log.info("正在配置接数据库1的事务管理器...");
return new JpaTransactionManager(entityManager.getObject());
}
}
4,运行代码
4.1 创建数据库
首先在使用您的数据库工具,在MySQL中创建一个数据库test1,与application.properties中的配置的数据库相对应。
4.2 启动项目
在Main上右键Run,启动项目。
4.3 Hibernate自动创建表
项目启动后,控制台可以看出,Hibernate自动创建了t_user表,这与User类的@Table注释内容一致。
然后从数据库工具中,也可以看到test1库下已创建了t_user表。
4.4 测试新增数据
打开浏览器访问http://localhost:8080/UserController/test,可以看到页面上有一行数据,刚好和UserController类中的代码功能一致,同时控制台也打印出了insert语句,说明调用成功。
4.5 测试成功
打开数据库工具中,看到t_user表里面多了一条数据,表示数据新增成功。自此Spring Boot和Hibernate 简单整合完成。