本文目录导读:

- 项目结构
- Maven依赖 (pom.xml)
- 配置文件 (persistence.xml)
- 实体类 (User.java)
- DAO层 (UserDao.java)
- 测试主类 (Main.java)
- 数据库SQL脚本
- 运行说明
- 核心概念说明
- 常见问题解决
我为您提供一个完整的JPA入门案例,使用Hibernate作为实现,涵盖实体映射、CRUD操作等核心内容。
项目结构
jpa-demo/
├── pom.xml
└── src/
└── main/
├── java/
│ └── com/example/
│ ├── entity/
│ │ └── User.java
│ ├── dao/
│ │ └── UserDao.java
│ └── Main.java
└── resources/
└── META-INF/
└── persistence.xml
Maven依赖 (pom.xml)
<?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>com.example</groupId>
<artifactId>jpa-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- JPA -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<!-- Hibernate 实现 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.32.Final</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
</dependencies>
</project>
配置文件 (persistence.xml)
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="jpa-demo" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!-- 实体类 -->
<class>com.example.entity.User</class>
<properties>
<!-- 数据库连接 -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa_demo?useSSL=false&serverTimezone=UTC"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<!-- Hibernate 配置 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
实体类 (User.java)
package com.example.entity;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 50)
private String username;
@Column(nullable = false, length = 100)
private String password;
@Column(length = 50)
private String email;
private Integer age;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "create_time")
private Date createTime;
// 构造函数
public User() {}
public User(String username, String password, String email, Integer age) {
this.username = username;
this.password = password;
this.email = email;
this.age = age;
this.createTime = new Date();
}
// Getter/Setter 方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
", age=" + age +
", createTime=" + createTime +
'}';
}
}
DAO层 (UserDao.java)
package com.example.dao;
import com.example.entity.User;
import javax.persistence.*;
import java.util.List;
public class UserDao {
private EntityManagerFactory emf;
private EntityManager em;
public UserDao() {
emf = Persistence.createEntityManagerFactory("jpa-demo");
em = emf.createEntityManager();
}
// 增 - 插入用户
public User save(User user) {
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
em.persist(user);
tx.commit();
return user;
} catch (Exception e) {
if (tx.isActive()) {
tx.rollback();
}
throw e;
}
}
// 删 - 删除用户
public void delete(Long id) {
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
User user = em.find(User.class, id);
if (user != null) {
em.remove(user);
}
tx.commit();
} catch (Exception e) {
if (tx.isActive()) {
tx.rollback();
}
throw e;
}
}
// 改 - 更新用户
public User update(User user) {
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
User updated = em.merge(user);
tx.commit();
return updated;
} catch (Exception e) {
if (tx.isActive()) {
tx.rollback();
}
throw e;
}
}
// 查 - 按ID查询
public User findById(Long id) {
return em.find(User.class, id);
}
// 查 - 查询所有用户
public List<User> findAll() {
String jpql = "SELECT u FROM User u";
return em.createQuery(jpql, User.class).getResultList();
}
// 查 - 按用户名查询
public User findByUsername(String username) {
String jpql = "SELECT u FROM User u WHERE u.username = :username";
try {
return em.createQuery(jpql, User.class)
.setParameter("username", username)
.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
// 查 - 按年龄范围查询
public List<User> findByAgeBetween(int minAge, int maxAge) {
String jpql = "SELECT u FROM User u WHERE u.age BETWEEN :minAge AND :maxAge";
return em.createQuery(jpql, User.class)
.setParameter("minAge", minAge)
.setParameter("maxAge", maxAge)
.getResultList();
}
// JPQL 更新操作
public int updateEmail(String username, String newEmail) {
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
String jpql = "UPDATE User u SET u.email = :newEmail WHERE u.username = :username";
int updatedCount = em.createQuery(jpql)
.setParameter("newEmail", newEmail)
.setParameter("username", username)
.executeUpdate();
tx.commit();
return updatedCount;
} catch (Exception e) {
if (tx.isActive()) {
tx.rollback();
}
throw e;
}
}
// JPQL 删除操作
public int deleteByUsername(String username) {
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
String jpql = "DELETE FROM User u WHERE u.username = :username";
int deletedCount = em.createQuery(jpql)
.setParameter("username", username)
.executeUpdate();
tx.commit();
return deletedCount;
} catch (Exception e) {
if (tx.isActive()) {
tx.rollback();
}
throw e;
}
}
// 分页查询
public List<User> findByPage(int page, int pageSize) {
String jpql = "SELECT u FROM User u ORDER BY u.id";
return em.createQuery(jpql, User.class)
.setFirstResult((page - 1) * pageSize)
.setMaxResults(pageSize)
.getResultList();
}
// 关闭 EntityManager
public void close() {
if (em != null) {
em.close();
}
if (emf != null) {
emf.close();
}
}
}
测试主类 (Main.java)
package com.example;
import com.example.dao.UserDao;
import com.example.entity.User;
import java.util.List;
public class Main {
public static void main(String[] args) {
UserDao userDao = new UserDao();
try {
// 1. 插入三条数据
System.out.println("=== 插入用户 ===");
User user1 = new User("admin", "123456", "admin@example.com", 25);
User user2 = new User("zhangsan", "abc123", "zhangsan@example.com", 30);
User user3 = new User("lisi", "xyz789", "lisi@example.com", 22);
userDao.save(user1);
userDao.save(user2);
userDao.save(user3);
System.out.println("成功插入3个用户");
// 2. 查询所有用户
System.out.println("\n=== 查询所有用户 ===");
List<User> users = userDao.findAll();
users.forEach(System.out::println);
// 3. 按ID查询
System.out.println("\n=== 按ID查询 (id=1) ===");
User foundUser = userDao.findById(1L);
System.out.println(foundUser);
// 4. 按用户名查询
System.out.println("\n=== 按用户名查询 (zhangsan) ===");
User userByName = userDao.findByUsername("zhangsan");
System.out.println(userByName);
// 5. 更新用户
System.out.println("\n=== 更新用户信息 ===");
if (foundUser != null) {
foundUser.setEmail("newadmin@example.com");
foundUser.setAge(26);
User updatedUser = userDao.update(foundUser);
System.out.println("更新后的用户: " + updatedUser);
}
// 6. 按年龄范围查询
System.out.println("\n=== 年龄在20到30岁之间的用户 ===");
List<User> ageUsers = userDao.findByAgeBetween(20, 30);
ageUsers.forEach(System.out::println);
// 7. JPQL更新操作
System.out.println("\n=== JPQL更新邮箱 ===");
int updated = userDao.updateEmail("zhangsan", "zhangsan_new@example.com");
System.out.println("更新了 " + updated + " 条记录");
// 8. 分页查询
System.out.println("\n=== 分页查询 (第1页,每页2条) ===");
List<User> pageUsers = userDao.findByPage(1, 2);
pageUsers.forEach(System.out::println);
// 9. 删除用户
System.out.println("\n=== 删除用户 (id=2) ===");
userDao.delete(2L);
System.out.println("成功删除用户 id=2");
// 10. JPQL删除操作
System.out.println("\n=== JPQL删除用户 (lisi) ===");
int deleted = userDao.deleteByUsername("lisi");
System.out.println("删除了 " + deleted + " 条记录");
// 11. 最终查询验证
System.out.println("\n=== 最终用户列表 ===");
userDao.findAll().forEach(System.out::println);
} finally {
userDao.close();
}
}
}
数据库SQL脚本
-- 创建数据库
CREATE DATABASE IF NOT EXISTS jpa_demo
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE jpa_demo;
-- 如果表已存在则删除
DROP TABLE IF EXISTS users;
-- 创建用户表(也可以由Hibernate自动创建)
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL,
email VARCHAR(50),
age INT,
create_time DATETIME
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
运行说明
环境准备
- JDK 1.8+ 已安装
- MySQL 8.0+ 已安装并启动
- Maven 已配置
运行步骤
# 1. 创建数据库 mysql -u root -p < src/main/resources/db.sql # 2. 编译项目 mvn clean compile # 3. 运行主类 mvn exec:java -Dexec.mainClass="com.example.Main"
核心概念说明
| 注解/概念 | 说明 |
|---|---|
@Entity |
标识这是一个JPA实体类 |
@Table |
指定映射的表名 |
@Id |
标识主键字段 |
@GeneratedValue |
主键生成策略 |
@Column |
列映射配置 |
EntityManager |
JPA核心接口,管理实体生命周期 |
EntityTransaction |
管理事务 |
JPQL |
面向对象的查询语言 |
常见问题解决
- 数据库连接失败:检查MySQL服务和账号密码
- 字符集乱码:设置
characterEncoding=utf8 - 表不存在:确保
hibernate.hbm2ddl.auto设置为update或create
这就是一个完整的JPA入门案例,涵盖了JPA最核心的用法,您可以根据实际需求扩展更复杂的关联映射、缓存配置等功能。