zoukankan      html  css  js  c++  java
  • SpringData-JPA

    在讲解JPA之前先将hibernate和JPA简单的了解一下.

    Hibernate概述:

      Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象变成思维来操作数据库.

    JPA概述:

      JPA全称为Java Persistence API,即Java持久化Api,是sun公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成.

      JPA通过JDK5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.

    JPA的优势:

    1.标注化

      JPA是JCP组织发布的JavaEE 标准之一,因此任何声称符合JPA标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行.

    2.容器级特性的支持.

      JPA框架中支持大数据集.事务.并发等容器级事务,这使得JPA超越了见到持久化框架的局限,在企业应用发挥更大的作用.

    3.简单方便

      JPA的主要目标之一就是提供更加简单的变成模型:在JPA框架下创建实体和创建Java类一样简单.没有任何的约束和限制,只需要使用javax,persistence.Entity进行注释,JPA的框架和接口也都非常简单.没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握.JPA 基于非侵入式原则设计.因此可以分容易和其他框架或者容器集成.

    4.查询能力

      JPA的查询语言是面向对象而非面向数据库的.它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物,JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJBQL的一种拓展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改,JOIN GROUP BY ,HAVING等通常只有SQL才能够提供的高级查询特性,甚至还能够支持子查询.

    5.高级特性

      JPA中能够支持面向对象的高级特性,如类之间的继承.多态和类之间的复杂关系,这样能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化.

    JPA与hibernate的关系?

    JPA规范本质上就是一种ORM规范,注意不是ORM框架---因为JPA并未提供ORM实现,它只是制定了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现.

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

    简单的入门案例:

      因为JPA是sun公司制定的API规范,所以我并没有使用额外的JPA相关的Jar包,只需要导入JPA的提供商的jar包,我们选择Hibernate作为JPA的提供商,所以需要导入Hibernate的相关jar包.

    可以在

        http://sourceforge.net/projects/hibernate/files/hibernate-orm/5.0.7.Final/

    这里进行下载.

    JPA中的主键生成策略

      通过annotation(注解)来映射hibernate实体的,基于annotation的hibernate主键标识为@Id,其生成规则由@GeneratedValue设定的,这里的@Id和@GeneratedValue都是JPA的标准用法.

      JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO

      具体说名如下:

      IDENTITY:主键由数据库自动生成(主要是自动增长型)

      用法:

      

    @Id
    @GeneratedValue(startegy=GenerationType.IDENTITY)
    private Long custId;

    SQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列.

    用法:一般情况为Oracle数据库

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="payablemoney_seq")
    @SequenceGenerator(name="payablemoney_seq",sequenceName="seq_payment")
    private Long custId;
    //@SequenceGenerator源码中的定义
    @Target({TYPE,METHOD,FIELD})
    @Retention(RUNTIME)
    public @interface SequenceGenerator{
    //表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的"generator"值中
    String name();
    //属性表示生成策略用到的数据库序列名称
    String sequenceName() default "";
    //表示主键初始值,默认为0
    int initialValue() default 0;
    //表示每次主键值增加的大小,例如设置1,则表示每次插入新纪录后自动加1,默认为50
    int allocationSize() default 50;
    }

    AUTO:主键由程序控制

    用法:

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long custId;

    TABLE:使用一个特定的数据库表格来保存主键

    用法:

        @Id  
        @GeneratedValue(strategy = GenerationType.TABLE, generator="payablemoney_gen")  
        @TableGenerator(name = "pk_gen",  
            table="tb_generator",  
            pkColumnName="gen_name",  
            valueColumnName="gen_value",  
            pkColumnValue="PAYABLEMOENY_PK",  
            allocationSize=1  
        ) 
    private Long custId;
    
    
    //@TableGenerator的定义:
        @Target({TYPE, METHOD, FIELD})   
        @Retention(RUNTIME)  
        public @interface TableGenerator {  
          //表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中
          String name();  
          //表示表生成策略所持久化的表名,例如,这里表使用的是数据库中的“tb_generator”。
          String table() default "";  
          //catalog和schema具体指定表所在的目录名或是数据库名
          String catalog() default "";  
          String schema() default "";  
          //属性的值表示在持久化表中,该主键生成策略所对应键值的名称。例如在“tb_generator”中将“gen_name”作为主键的键值
          String pkColumnName() default "";  
          //属性的值表示在持久化表中,该主键当前所生成的值,它的值将会随着每次创建累加。例如,在“tb_generator”中将“gen_value”作为主键的值 
          String valueColumnName() default "";  
          //属性的值表示在持久化表中,该生成策略所对应的主键。例如在“tb_generator”表中,将“gen_name”的值为“CUSTOMER_PK”。 
          String pkColumnValue() default "";  
          //表示主键初识值,默认为0。 
          int initialValue() default 0;  
          //表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50。
          int allocationSize() default 50;  
          UniqueConstraint[] uniqueConstraints() default {};  
        } 
    
        //这里应用表tb_generator,定义为 :
        CREATE TABLE  tb_generator (  
          id NUMBER NOT NULL,  
          gen_name VARCHAR2(255) NOT NULL,  
          gen_value NUMBER NOT NULL,  
          PRIMARY KEY(id)  
        )

    JPA的API介绍

    Persistence对象

    Persistence对象主要作用是用于获取EntityManagerFactory对象的.通过调用该类的createEntityManagerFactory静态方法,根据配置文件中持久化单元名称创建EntityManagerFactory.

    //1. 创建 EntitymanagerFactory
    @Test
    String unitName = "myJpa";
    EntityManagerFactory factory= Persistence.createEntityManagerFactory(unitName);

    EntityManagerFactory

    EntityManagerFacotry接口主要用来创建EntityManager实例:

    //创建实体管理类
    EntityManager em = factory.createEntityManager();

    由于EntityManagerFactory是一个线程安全的对象(即多个线程访问同一个EntityManagerFactory对象不会有线程问题),并且EntityManagerFactory的创建极其浪费资源,所以在使用JPA编程时,我们可以对EntityManagerFactory的创建进行优化,只需要做到一个工程只存在一个EntityMmanagerFactory即可/

    EntityManger

    在JPA规范中,EntityMmanager是完成持久化操作的核心对象,实体类作为普通java对象,只有在调用EntityManager将其持久化后才会变成持久化对象.EntityMmanager对象在一组实体类与底层数据源之间进行O/R映射的管理.它可以用来管理和更新EntityBean,根据主键查找EntityBean,还可以通过JPQL语句查询实体.

    我们可以通过调用EntityManager的方法完成获取事务,以及持久化数据库的操作.

      方法说明:

        getTransaction : 获取事务对象
        persist : 保存操作
        merge : 更新操作
        remove : 删除操作
        find/getReference : 根据id查询

    EntityTransaction

    在JPA规范中,EntityTraction是完成事务操作的核心对象,对于EntityTraction在我们的java代码中承接的功能比较简单

    begin:开启事务
    commit:提交事务
    rollback:回滚事务

    抽取JPAUtils工具类

    package cn.itcast.dao;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;
    
    public final class JPAUtil {
        // JPA的实体管理器工厂:相当于Hibernate的SessionFactory
        private static EntityManagerFactory em;
        // 使用静态代码块赋值
        static {
            // 注意:该方法参数必须和persistence.xml中persistence-unit标签name属性取值一致
            em = Persistence.createEntityManagerFactory("myPersistUnit");
        }
    
        /**
         * 使用管理器工厂生产一个管理器对象
         * 
         * @return
         */
        public static EntityManager getEntityManager() {
            return em.createEntityManager();
        }
    }

    简单的增删改查和复杂查询:

    package com.qingmu;
    
    import org.hibernate.dialect.CUBRIDDialect;
    import org.junit.Test;
    import org.junit.experimental.theories.suppliers.TestedOn;
    
    import javax.persistence.*;
    import java.util.List;
    
    /**
     * @Auther:qingmu
     * @Description:脚踏实地,只为出人头地
     * @Date:Created in 16:12 2019/5/14
     */
    public class SpringDataJPATest02 {
        private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa");
    
        /**
         * 增加
         */
        @Test
        public void saveCustomer() {
            Customer customer = new Customer();
            /**
             * 如果设置了主键自增长,然后再设置id,就会出现异常:
             * PersistentObjectException: detached entity passed to persist: com.qingmu.Customer
             */
    //        customer.setCustId(3L);
            customer.setCustName("青木堂");
            customer.setCustAddress("北京市昌平区");
            customer.setCustIndustry("教育");
            customer.setCustLevel("VIP");
            customer.setCustPhone("12345678912");
            customer.setCustSource("网络");
            EntityManager entityManager = null;
            //创建事务
            EntityTransaction transaction = null;
            try {
                //获取实体类管理对象
                entityManager = entityManagerFactory.createEntityManager();
                transaction = entityManager.getTransaction();
                //开始事务
                transaction.begin();
                //创建一个pojo对象
    
                //保存
                entityManager.persist(customer);
                //提交
                transaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
                transaction.rollback();
    
            } finally {
                //关闭资源
                entityManager.close();
                entityManagerFactory.close();
            }
        }
    
        /**
         * 更新
         */
        @Test
        public void update() {
    
            EntityManager entityManager = null;
            EntityTransaction transaction = null;
            try {
                entityManager = entityManagerFactory.createEntityManager();
                transaction = entityManager.getTransaction();
                transaction.begin();
                Customer customer = entityManager.find(Customer.class, 2L);
                customer.setCustName("qingmutang");
                transaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
                transaction.rollback();
            } finally {
                entityManager.close();
                entityManagerFactory.close();
            }
        }
    
        /**
         * 删除
         */
        @Test
        public void testRemove() {
            EntityManager entityManager = null;
            EntityTransaction transaction = null;
            try {
                entityManager = entityManagerFactory.createEntityManager();
                transaction = entityManager.getTransaction();
                transaction.begin();
                Customer customer = entityManager.find(Customer.class, 3L);
                entityManager.remove(customer);
                transaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
                transaction.rollback();
            } finally {
                entityManager.close();
            }
        }
    
        /**
         * 根据id查询,立即加载
         */
        @Test
        public void findById() {
            EntityManager entityManager = null;
            EntityTransaction transaction = null;
            try {
                entityManager = entityManagerFactory.createEntityManager();
                transaction = entityManager.getTransaction();
                transaction.begin();
                Customer customer = entityManager.find(Customer.class, 2L);
                System.out.println(customer);
                transaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
                transaction.rollback();
            } finally {
                entityManager.close();
            }
        }
    
        /**
         * 根据id查询,延迟加载
         */
        @Test
        public void findById2() {
            EntityManager entityManager = null;
            EntityTransaction transaction = null;
            try {
                entityManager = entityManagerFactory.createEntityManager();
                transaction = entityManager.getTransaction();
                transaction.begin();
                Customer reference = entityManager.getReference(Customer.class, 2L);
                System.out.println(reference);
                transaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
                transaction.rollback();
            } finally {
                entityManager.close();
            }
        }
    
        /**
         * 查询全部
         */
        @Test
        public void findAll() {
            EntityManager entityManager = null;
            EntityTransaction transaction = null;
            try {
                entityManager = entityManagerFactory.createEntityManager();
                transaction = entityManager.getTransaction();
                transaction.begin();
                String jpql = "from Customer";
                Query query = entityManager.createQuery(jpql);
                List resultList = query.getResultList();
                for (Object o : resultList) {
                    System.out.println(o);
                }
                transaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
                transaction.rollback();
            } finally {
                entityManager.close();
            }
        }
    
        /**
         * 分页查询
         */
        @Test
        public void limit() {
            EntityManager entityManager = null;
            EntityTransaction transaction = null;
            try {
                entityManager = entityManagerFactory.createEntityManager();
                transaction = entityManager.getTransaction();
                transaction.begin();
                String jpql = "from Customer";
                Query query = entityManager.createQuery(jpql);
                query.setFirstResult(0);
                query.setMaxResults(2);
                List resultList = query.getResultList();
                for (Object o : resultList) {
                    System.out.println(o);
                }
                transaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
                transaction.rollback();
            } finally {
                entityManager.close();
            }
        }
    /**
    *通过条件查询
    */ @Test
    public void ByQuery() { EntityManager entityManager = null; EntityTransaction transaction = null; try { entityManager = entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); String jpql = "from Customer where custName like ?"; Query query = entityManager.createQuery(jpql); query.setParameter(1, "%青木%"); List resultList = query.getResultList(); for (Object o : resultList) { System.out.println(o); } transaction.commit(); } catch (Exception e) { e.printStackTrace(); transaction.rollback(); } finally { entityManager.close(); } } /**
    *分类查询
    */ @Test
    public void sortBy(){ EntityManager entityManager = null; EntityTransaction transaction = null; try { entityManager = entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); String jpql = "from Customer order by custId desc"; Query query = entityManager.createQuery(jpql); List resultList = query.getResultList(); for (Object o : resultList) { System.out.println(o); } transaction.commit(); } catch (Exception e) { e.printStackTrace(); transaction.rollback(); }finally { entityManager.close(); } } /** * 统计查询 */ @Test public void count(){ EntityManager entityManager = null; EntityTransaction transaction = null; try { entityManager = entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); String jpql = "select count(custId) from Customer"; Query query = entityManager.createQuery(jpql); List resultList = query.getResultList(); for (Object o : resultList) { System.out.println(o); } transaction.commit(); } catch (Exception e) { e.printStackTrace(); transaction.rollback(); }finally { entityManager.close(); } } }
  • 相关阅读:
    计算机科学中最重要的32个算法
    趣事
    深度学习迷你地图
    物理学
    代数几何
    Node.js 文件系统
    Node.js 常用工具util包
    Node.js 全局对象
    favi.icon是什么?
    Node.js 路由
  • 原文地址:https://www.cnblogs.com/qingmuchuanqi48/p/10864694.html
Copyright © 2011-2022 走看看