• JPA 入门实战(3)Spring Boot 中使用 JPA


    本文主要介绍在 Spring Boot 中使用 JPA 的方法(暂不使用 spring-data-jpa),相关的环境及软件信息如下:Spring Boot 2.6.10、JPA 2.2、eclipselink 2.7.10。

    1、原生使用

    该使用方法与 Spring Boot 的关系不是很大,一般 Java 项目都可以这么使用。工程目录结构如下:

    1.1、引入依赖

    这里使用 eclipselink 作为 JPA 的实现框架。

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa</artifactId>
        <version>2.7.10</version>
    </dependency>

    其他的依赖可自行引入,如数据库驱动、lombok 等。

    1.2、创建实体类

    package com.abc.demojpa.entity;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import javax.persistence.*;
    
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @Entity
    @Table(name = "a_student")
    public class Student {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        private String name;
    
        private Integer age;
    
        @Column(name = "home_address")
        private String homeAddress;
    }

    1.3、编写 JPA 配置文件 (persistence.xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.2"
                 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_2.xsd">
        <persistence-unit name="myUnit">
            <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
            <exclude-unlisted-classes>false</exclude-unlisted-classes>
            <properties>
                <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="javax.persistence.jdbc.url" value="jdbc:mysql://10.49.196.10:3306/test?useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="javax.persistence.jdbc.user" value="root"/>
                <property name="javax.persistence.jdbc.password" value="123456"/>
                <property name="eclipselink.logging.level" value="INFO" />
                <property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
            </properties>
        </persistence-unit>
    
    </persistence>

     eclipselink 开头的配置是 eclipselink 自带的扩展配置,用于实现功能的增强;详细的扩展配置说明可参考官网说明:https://www.eclipse.org/eclipselink/documentation/2.7/jpa/extensions/toc.htm。

    1.4、配置 EntityManager

    package com.abc.demojpa.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;
    
    @Configuration
    public class EntityManagerConfig {
        @Bean
        public EntityManagerFactory entityManagerFactory() {
            return Persistence.createEntityManagerFactory("myUnit");
        }
    
        @Bean
        public EntityManager entityManager() {
            return entityManagerFactory().createEntityManager();
        }
    }

    1.5、使用例子

    package com.abc.demojpa.service;
    
    import com.abc.demojpa.entity.Student;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import javax.persistence.EntityManager;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class TestService {
        private static final Logger logger = LoggerFactory.getLogger(TestService.class);
    
        @Autowired
        private EntityManager entityManager;
    
        //插入实体
        @Test
        public void persist() {
            entityManager.getTransaction().begin();
            Student student = new Student();
            student.setName("小明");
            student.setAge(15);
            student.setHomeAddress("江苏");
    
            Student student2 = new Student();
            student2.setName("小红");
            student2.setAge(18);
            student2.setHomeAddress("广东");
    
            entityManager.persist(student);
            entityManager.persist(student2);
    
            entityManager.getTransaction().commit();
        }
    
        //查询实体
        @Test
        public void find() {
            Student student = entityManager.find(Student.class, 1501L);
            logger.info("student={}", student);
        }
    
        //更新实体(先查再更新)
        @Test
        public void modify() {
            entityManager.getTransaction().begin();
            Student student = entityManager.find(Student.class, 1501L);
            student.setName("小明2");
            entityManager.getTransaction().commit();
        }
    
        //更新实体(直接根据id更新)
        @Test
        public void merge() {
            entityManager.getTransaction().begin();
            Student student = new Student();
            student.setId(1501L);
            student.setName("小明3");
            student.setAge(16);
            entityManager.merge(student);
            entityManager.getTransaction().commit();
        }
    
        //删除实体
        @Test
        public void remove() {
            entityManager.getTransaction().begin();
            Student student = entityManager.find(Student.class, 1501L);
            entityManager.remove(student);
            entityManager.getTransaction().commit();
        }
    }

    2、使用 Spring 提供的 JPA 辅助功能

    Sping 提供了对 EntityManagerFactory 的管理,使得 JPA 和 Spring 可以作为一个整体在工作;详细可参考:https://blog.csdn.net/lijia791541916/article/details/49181603。

    工程目录结构如下:

    2.1、引入依赖

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa</artifactId>
        <version>2.7.10</version>
    </dependency>

    2.2、创建实体类

    package com.abc.demojpa.entity;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import javax.persistence.*;
    
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @Entity
    @Table(name = "a_student")
    public class Student {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        private String name;
    
        private Integer age;
    
        @Column(name = "home_address")
        private String homeAddress;
    }

    2.3、编写 Spring Boot 配置文件 (application.yml)

    server:
      port: 8080
    
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://10.255.1.96:3306/cqt?useUnicode=true&characterEncoding=UTF-8
        username: root
        password: Root12#$

    2.4、配置 EntityManagerFactory

    package com.abc.demojpa.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
    import org.springframework.transaction.PlatformTransactionManager;
    
    import javax.persistence.EntityManagerFactory;
    import javax.sql.DataSource;
    import java.util.Properties;
    
    
    @Configuration
    public class EntityManagerFactoryConfig {
        @Bean
        public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean(@Autowired DataSource dataSource) {
            LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
            localContainerEntityManagerFactoryBean.setDataSource(dataSource);
            localContainerEntityManagerFactoryBean.setPersistenceUnitName("myUnit");
            localContainerEntityManagerFactoryBean.setPackagesToScan("com.abc");
            localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new EclipseLinkJpaVendorAdapter());
            Properties properties = new Properties();
            properties.setProperty("eclipselink.logging.level", "INFO");
            properties.setProperty("eclipselink.ddl-generation", "create-or-extend-tables");
            properties.setProperty("eclipselink.weaving", "false");
            localContainerEntityManagerFactoryBean.setJpaProperties(properties);
            return localContainerEntityManagerFactoryBean;
        }
    
        @Bean
        public PlatformTransactionManager platformTransactionManager(@Autowired EntityManagerFactory entityManagerFactory) {
            return new JpaTransactionManager(entityManagerFactory);
        }
    }

    2.5、使用例子

    package com.abc.demojpa.service;
    
    import com.abc.demojpa.entity.Student;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.annotation.Commit;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class TestService {
        private static final Logger logger = LoggerFactory.getLogger(TestService.class);
    
        @PersistenceContext
        private EntityManager entityManager;
    
        /**
         * 增加数据
         * Spring Boot 事务测试时默认会回滚操作避免产生测试数据,如果不需要回滚可使用 @Commit 注解
         */
        @Test
        @Transactional
        @Commit
        public void add() {
            Student student = new Student();
            student.setName("小明");
            student.setAge(15);
            student.setHomeAddress("江苏");
    
            Student student2 = new Student();
            student2.setName("小红");
            student2.setAge(18);
            student2.setHomeAddress("广东");
    
            entityManager.persist(student);
            entityManager.persist(student2);
        }
    
        //查询实体
        @Test
        public void find() {
            Student student = entityManager.find(Student.class, 1L);
            logger.info("student={}", student);
        }
    
        //更新实体(先查再更新)
        @Test
        @Transactional
        @Commit
        public void modify() {
            Student student = entityManager.find(Student.class, 1L);
            student.setName("小明2");
        }
    
        //更新实体(直接根据id更新)
        @Test
        @Transactional
        @Commit
        public void merge() {
            Student student = new Student();
            student.setId(1L);
            student.setName("小明3");
            student.setAge(16);
            entityManager.merge(student);
        }
    
        //删除实体
        @Test
        @Transactional
        @Commit
        public void remove() {
            Student student = entityManager.find(Student.class, 1L);
            entityManager.remove(student);
        }
    }
  • 相关阅读:
    高精度、大整数幂取模
    关于正则表达式
    003.android资源文件剖析(Resources)
    myBatis 基础测试 表关联关系配置 集合 测试
    Android应用开发学习笔记之播放音频
    移植一个开源点餐网到SAE平台上
    6.0RMB MP3所看到的……
    [读书笔记]设计原本[The Design of Design]
    递归 和 非递归 遍历二叉树
    Android应用开发学习笔记之播放视频
  • 原文地址:https://www.cnblogs.com/wuyongyin/p/16527392.html
Copyright © 2020-2023  润新知