JPA入门案例

wen java案例 3

本文目录导读:

JPA入门案例

  1. 项目结构
  2. Maven依赖 (pom.xml)
  3. 配置文件 (persistence.xml)
  4. 实体类 (User.java)
  5. DAO层 (UserDao.java)
  6. 测试主类 (Main.java)
  7. 数据库SQL脚本
  8. 运行说明
  9. 核心概念说明
  10. 常见问题解决

我为您提供一个完整的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&amp;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;

运行说明

环境准备

  1. JDK 1.8+ 已安装
  2. MySQL 8.0+ 已安装并启动
  3. 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 面向对象的查询语言

常见问题解决

  1. 数据库连接失败:检查MySQL服务和账号密码
  2. 字符集乱码:设置characterEncoding=utf8
  3. 表不存在:确保hibernate.hbm2ddl.auto设置为updatecreate

这就是一个完整的JPA入门案例,涵盖了JPA最核心的用法,您可以根据实际需求扩展更复杂的关联映射、缓存配置等功能。

抱歉,评论功能暂时关闭!