Spring Data JPA(一)—— JPA入门

2020-04-02

一、ORM思想

  • 主要目的:操作实体类就相当于操作数据库
  • 建立两个映射关系
    1. 实体类和表的映射关系
    2. 实体类中属性和表中字段的映射关系
  • 不再重点关注:sql语句

实现了ORM思想的框架:MyBatis,Hibernate

二、Hibernate与JPA规范

2.1 Hibernate概述

  • Hibernate是一个开放源代码的对象关系映射框架
    1. 它对JDBC进行了非常轻量级的对象封装
    2. 它将POJO与数据表建立映射关系,是一个全自动的ORM框架

2.2 JPA规范概述

  • Java Persistence API:用于对象持久化的API
  • Java EE 5.0 平台标准的ORM规范,使得应用程序以统一的方式访问持久层
    image.png

2.3 JPA优势

  1. 标准化
    • JPA是JCP组织发布的Java EE标准之一,因此任何声称符合JPA标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
  2. 容器级特性的支持
    • JPA框架中支持大数据集、事务、并发等容器级事务,这使得JPA超越了简单持久化框架的局限,在企业应用发挥更大的作用。
  3. 简单方便
    • JPA的主要目标之一就是提供更加简单的编程模型,在JPA框架下创建实体和创建Java类一样简单,没有任何的约束和限制,只需要使用javax.persistence.Entity进行注释,JPA的框架和接口也都是非侵入式原则设计,因此可以很容易地和其它框架或者容器集成。
  4. 查询能力
    • JPA的查询语言是面对对象而非面向数据库的,它以面对对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING等通常只有SQL才能够提供的高级查询特性,甚至还能够支持子查询。
  5. 高级特性
    • JPA中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。

2.4 JPA与Hibernate的关系

image.png

  • JPA和Hibernate的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现。JPA怎么取代Hibernate呢?JDBC规范可以驱动底层数据库吗?答案是否定的,也就是说,如果使用JPA规范进行数据库操作,底层需要Hibernate作为其实现类完成数据持久化工作。

三、JPA基本操作

案例:客户的相关操作(增删改查)

3.1 需求介绍

  • 本节实现一个保存客户到数据库的功能

3.2 开发包介绍

image.png

3.3 搭建开发环境

本实例环境:JDK 1.8、MySQL 8.0.19

  1. 导入依赖

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.hibernate.version>5.4.13.Final</project.hibernate.version>
    </properties>
    
    <dependencies>
        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    
        <!-- Hibernate对JPA的支持包 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>
    
        <!-- c3p0 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>
    
        <!-- log日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    
        <!-- Mysql and MariaDB -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
    </dependencies>
    
  2. 创建数据表

    CREATE TABLE tab_customer (
    cust_id BIGINT(32) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '客户编号(主键)',
    cust_name VARCHAR(32) NOT NULL COMMENT '客户名称(公司名称)',
    cust_source VARCHAR(32) DEFAULT NULL COMMENT '客户信息来源',
    cust_industry VARCHAR(32) DEFAULT NULL COMMENT '客户所属行业',
    cust_level VARCHAR(32) DEFAULT NULL COMMENT '客户级别',
    cust_address VARCHAR(128) DEFAULT NULL COMMENT '客户联系地址',
    cust_phone VARCHAR(64) DEFAULT NULL COMMENT '客户联系电话'
    )
    
  3. 编写客户实体类

    package com.cherishvii.domain;
    
    /**
     * 客户实体类
     *
     * @author CHERISHVII
     * @author www.cherishvii.com
     * @version V1.0
     * @date 2020/3/31 17:47
     */
    public class Customer {
        /**
         * 客户主键
         */
        private Long custId;
        /**
         * 客户名称
         */
        private String custName;
        /**
         * 客户来源
         */
        private String custSource;
        /**
         * 客户级别
         */
        private String custLevel;
        /**
         * 客户所属行业
         */
        private String custIndustry;
        /**
         * 客户联系方式
         */
        private String custPhone;
        /**
         * 客户地址
         */
        private String custAddress;
    
        public Long getCustId() {
            return custId;
        }
    
        public void setCustId(Long custId) {
            this.custId = custId;
        }
    
        public String getCustName() {
            return custName;
        }
    
        public void setCustName(String custName) {
            this.custName = custName;
        }
    
        public String getCustSource() {
            return custSource;
        }
    
        public void setCustSource(String custSource) {
            this.custSource = custSource;
        }
    
        public String getCustLevel() {
            return custLevel;
        }
    
        public void setCustLevel(String custLevel) {
            this.custLevel = custLevel;
        }
    
        public String getCustIndustry() {
            return custIndustry;
        }
    
        public void setCustIndustry(String custIndustry) {
            this.custIndustry = custIndustry;
        }
    
        public String getCustPhone() {
            return custPhone;
        }
    
        public void setCustPhone(String custPhone) {
            this.custPhone = custPhone;
        }
    
        public String getCustAddress() {
            return custAddress;
        }
    
        public void setCustAddress(String custAddress) {
            this.custAddress = custAddress;
        }
    
        @Override
        public String toString() {
            return "Customer{" +
                    "custId=" + custId +
                    ", custName='" + custName + '\'' +
                    ", custSource='" + custSource + '\'' +
                    ", custLevel='" + custLevel + '\'' +
                    ", custIndustry='" + custIndustry + '\'' +
                    ", custPhone='" + custPhone + '\'' +
                    ", custAddress='" + custAddress + '\'' +
                    '}';
        }
    }
    
  4. 配置JPA的核心配置文件

    位置:配置到类路径下的***META-INF***的文件夹下

    命名persistence.xml

    <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
        <!-- 需要配置persistence-unit节点
            持久化单元:
                name:持久化单元名称
                transaction-type:事务管理的方式
                    JTA:分布式事务管理
                    RESOURCE_LOCAL:本地事务管理
         -->
        <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
            <!-- JPA的实现方式 -->
            <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    
            <properties>
                <!-- 数据库信息
                    用户名:javax.persistence.jdbc.user
                    密码:javax.persistence.jdbc.password
                    驱动:javax.persistence.jdbc.driver
                    地址:javax.persistence.jdbc.url
                -->
                <property name="javax.persistence.jdbc.user" value="CherishVII"/>
                <property name="javax.persistence.jdbc.password" value="19990211"/>
                <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="javax.persistence.jdbc.url" value="jdbc:mysql://47.108.20.172:3306/jpa"/>
    
                <!-- (可选)配置JPA实现方(Hibernate)的配置信息
                    显示sql语句
                    自动创建数据库表:hibernate.hbm2ddl.auto
                        create:程序运行时创建数据库表(如果有表,删除表再创建)
                        update:程序运行时创建数据库表(如果有表,不会创建表)
                        none:不会创建表
                -->
                <property name="hibernate.show_sql" value="true"/>
                <property name="hibernate.hbm2ddl.auto" value="update"/>
                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
            </properties>
        </persistence-unit>
    </persistence>
    
  5. 配置映射关系

    1. 实体类和表的映射关系
    2. 实体类中属性和表中字段的映射关系
    /**
     * 客户实体类
     *      配置映射关系
     *          1.实体类和表的映射关系
     *              @Entity:声明实体类
     *              @Table:配置实体类和表的映射关系
     *                  name:配置数据库表的名称
     *          2.实体类中属性和表中字段的映射关系
     *
     * @author CHERISHVII
     * @author www.cherishvii.com
     * @version V1.0
     * @date 2020/3/31 17:47
     */
    @Entity
    @Table(name = "tab_customer")
    public class Customer {
        /**
         * 客户主键
         * @Id:声明主键的配置
         * @GeneratedValue:配置主键的生成策略
         *      GenerationType.IDENTITY:自增
         * @Column:配置属性和字段的映射关系
         *      name:数据库表中字段的名称
         */
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "cust_id")
        private Long custId;
        /**
         * 客户名称
         */
        @Column(name = "cust_name")
        private String custName;
        /**
         * 客户来源
         */
        @Column(name = "cust_source")
        private String custSource;
        /**
         * 客户级别
         */
        @Column(name = "cust_level")
        private String custLevel;
        /**
         * 客户所属行业
         */
        @Column(name = "cust_industry")
        private String custIndustry;
        /**
         * 客户联系方式
         */
        @Column(name = "cust_phone")
        private String custPhone;
        /**
         * 客户地址
         */
        @Column(name = "cust_address")
        private String custAddress;
    
        //省略Get、Set、toString方法
    }
    

    若代码有报错情况,参考以下处理

    *5.1 Persistence指定数据库

    1. 打开Persistence视图
      image.png

    2. Idea界面左边找到Persistence标签卡,右键当前项目,选择Assign Data Source
      image.png

    3. 选择你已连接的数据库

      若没有选项及Idea没有配置连接数据库,请参照Idea操作数据库

      image.png

  6. 编写测试类

    package com.cherishvii.test;
    
    import com.cherishvii.domain.Customer;
    import org.junit.Test;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.EntityTransaction;
    import javax.persistence.Persistence;
    
    /**
     * @author CHERISHVII
     * @author www.cherishvii.com
     * @version V1.0
     * @date 2020/3/31 18:53
     */
    public class JpaTest {
    
        /**
         * 测试Jpa的保存
         *      案例:保存一个客户到数据库
         * Jpa的操作步骤
         *      1.加载配置文件创建工程(实体管理类工厂)对象
         *      2.通过实体管理类工厂获取实体管理类
         *      3.获取事务对象,开启事务
         *      4.完成增删改查操作
         *      5.提交事务(回滚事务)
         *      6.释放资源
         */
        @Test
        public void testSave() {
            //1.加载配置文件创建工程(实体管理类工厂)对象
            EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
            //2.通过实体管理类工厂获取实体管理类
            EntityManager entityManager = factory.createEntityManager();
            //3.获取事务对象,开启事务
            EntityTransaction tx = entityManager.getTransaction();
            //开启事务
            tx.begin();
            //4.完成增删改查操作
            //创建需要保存的对象
            Customer customer = new Customer();
            customer.setCustName("CherishVII");
            customer.setCustIndustry("IT");
            //保存
            entityManager.persist(customer);
            //5.提交事务(回滚事务)
            tx.commit();
            //6.释放资源
            entityManager.close();
            factory.close();
        }
    }
    
  7. 运行测试类,查看结果
    image.png
    image.png


标题:Spring Data JPA(一)—— JPA入门
作者:CherishVII
地址:https://cherishvii.com/articles/2020/03/31/1585655429630.html

评论
发表评论