JPA操作

ORM思想

  • ORM(Object-Relational Mapping) 表示对象关系映射。在面向对象的软件开发中,通过ORM,就可以把对象映射到关系型数据库中。只要有一套程序能够做到建立对象与数据库的关联,操作对象就可以直接操作数据库数据,就可以说这套程序实现了ORM对象关系映射
    简单的说:ORM就是建立实体类和数据库表之间的关系,从而达到操作实体类就相当于操作数据库表的目的。

  • 主要目的:操作实体类就像操作数据库表

  • 建立两个映射关系;

    • 实体类和表的映射关系
    • 实体类中属性和表中字段的映射关系
  • 不在重点关注sql语句

  • 实现了ORM思想的框架:Mybatis,hibernate,Jpa等

JPA概述

  • JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。类似于JDBC规范
  • JPA规范本质上就是一种ORM规范,注意不是ORM框架——因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现。

JPA的入门案例

本案例使用Hibernate演示JPA

  • JPA与hibernate的关系

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

    • 1.官方下载地址 http://sourceforge.net/projects/hibernate/files/hibernate-orm/5.0.7.Final/
      在这里插入图片描述
    • 2.Maven坐标
    <!-- hibernate对jpa的支持包 -->
    	<dependency>
    		<groupId>org.hibernate</groupId>
    		<artifactId>hibernate-entitymanager</artifactId>
    		<version>${project.hibernate.version}</version>
    	</dependency>
    
    
  • 二. 创建客户的数据库表和客户的实体类并配置映射关系以及get/set方法

import javax.persistence.*;

/**
 * 客户实体类
 *  配置映射关系
 *          1.实体类和表的映射关系
 *                  @Entity  //声明此类是一个实体类
 *                  @Table(name="cst_customer")    //配置实体类和表的映射关系
 *                                                  name属性配置数据库表的名称
 *          2.实体类属性和表中字段的映射关系
 */
@Entity  //声明此类是一个实体类
@Table(name="cst_customer")    //配置实体类和表的映射关系 name属性配置数据库表的名称
public class Customer {
    /**
     * @Id :声明主键的配置
     * @GeneratedValue :配置主键的生成策略
     *          GenerationType.IDENTITY:自增
     *                          底层数据库必须支持自增
     *          GenerationType.SEQUENCE:序列 oracle
     *                          底层数据库必须支持序列
     *          GenerationType.TABLE:  jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键递增
     *          GenerationType.AUTO :由程序自动帮助我们选择生成策略
     * @Column :配置数据库表字段和属性的映射关系
     *          name:数据库表中字段的名称
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cust_id")
    private Long custId;        //客户ID

    @Column(name="cust_name")
    private String custName;    //客户姓名

    @Column(name="cust_source")
    private String custSource;  //客户来源

    @Column(name="cust_industry")
    private String custIndustry;//客户所属行业

    @Column(name = "cust_level")
    private String custLevel;   //客户级别

    @Column(name = "cust_address")
    private String custAddress; // 客户地址

    @Column(name="cust_phone")
    private String custPhone;   //客户联系方式

    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 getCustIndustry() {
        return custIndustry;
    }

    public void setCustIndustry(String custIndustry) {
        this.custIndustry = custIndustry;
    }

    public String getCustLevel() {
        return custLevel;
    }

    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }

    public String getCustAddress() {
        return custAddress;
    }

    public void setCustAddress(String custAddress) {
        this.custAddress = custAddress;
    }

    public String getCustPhone() {
        return custPhone;
    }

    public void setCustPhone(String custPhone) {
        this.custPhone = custPhone;
    }
}

常用注解说明

    @Entity
        	作用:指定当前类是实体类。
        @Table
        	作用:指定实体类和表之间的对应关系。
        	属性:
        		name:指定数据库表的名称
        @Id
        	作用:指定当前字段是主键。
        @GeneratedValue
        	作用:指定主键的生成方式。。
        	属性:
        		strategy :指定主键生成策略。
        @Column
        	作用:指定实体类属性和数据库表之间的对应关系
        	属性:
        		name:指定数据库表的列名称。
        		unique:是否唯一  
        		nullable:是否可以为空  
        		inserttable:是否可以插入  
        		updateable:是否可以更新  
        		columnDefinition: 定义建表时创建此列的DDL  
        		secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境[重点]

  • 三.配置JPA的核心配置文件
  • 在java工程的src路径下创建一个名为META-INF的文件夹,在此文件夹下创建一个名为persistence.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!--需要配置persistence-unit节点 :
        持久化单元: name:持久化单元名称
        transaction-type: 事务管理(jpa:分布式事务 RESOURCE_LOCAL:本地事务管理 )
        -->
    <persistence-unit name="myjpa" transaction-type="RESOURCE_LOCAL">
        <!-- jpa的实现方式-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <!-- 数据库信息-->
        <!-- 可选配置:配置JPA实现方的配置信息-->
        <properties>
                <!--数据库信息
                用户名:javax.persistence.jdbc.user
                密码,javax.persistence.jdbc.password
                驱动:javax.persistence.jdbc.driver
                数据库地址:javax.persistence.jdbc.url
                -->
            <property name="javax.persistence.jdbc.user" value="root"></property>
            <property name="javax.persistence.jdbc.password" value="123456"></property>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"></property>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql:///study"></property>

            <!-- 配置jpa实现方式(hibernate)的配置信息
                显示sql           :hibernate.show_sql false|true
                自动创建数据库表   : hibernate.hbm2ddl.auto
                        create: 程序运行时创建数据库表(如果有表先删除表在创建)

                        update: 程序运行时创建表(如果有表不会创建表)
                        none:   不会创建表
            -->
            <property name="hibernate.show_sql" value="true"></property>
            <property name="hibernate.hbm2ddl.auto" value="update"></property>
        </properties>

    </persistence-unit>
</persistence>
  • 四.JPA的操作步骤
  • JPA的操作步骤
    • 1.加载配置文件创建实体管理器工厂
      • Persistence静态方法createEntityManagerFactory(“持久化单元名称”)(根据持久化单元名称创建实体管理器工厂)
      • 作用:创建实体管理器工厂
    • 2.根据实体管理器工厂,创建实体管理器
      • EntityManagerFactory:获取 EntityManager
      • 方法:createEntityManager()
      • 内部维护了很多内容
        • 内部维护了数据库信息
        • 维护了缓存信息
        • 维护了所有的实体管理器对象
        • 在创建EntityManagerFactory的过程中会根据配置创建数据库表
        • EntityManagerFactory的创建过程比较浪费资源
        • 特点 线程安全的对象
          • 多个线程访问同一个EntityManagerFactory不会有线程安全问题
        • 解决创建过程浪费资源:静态代码块的形式创建EntityManagerFactory
    • 3.创建事务对象,开启事务
      • EntityManager对象:实体类管理器
        • beginTransaction:创建事务对象
        • presist:保存
        • merge:更新
        • remove:删除
        • find/getRefrence:根据Id查询
      • Transaction 对象:事务
        • begin:开启事务
        • commit 提交事务
        • rollback:回滚事务
    • 4.增删改查操作
    • 5.提交事务
    • 6.释放资源
  • 五.测试方法
  • 测试保存方法
    @Test
    public void testSave(){
   /*     //1.加载配置文件创建工厂(实体管理类)对象
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("myjpa");
        //2.通过实体管理类工厂获取实体管理器
        EntityManager entityManager = factory.createEntityManager();*/
        EntityManager entityManager = JpaUtils.getEntityManager();
        //3.获取事务对象,开启事务
        EntityTransaction tx = entityManager.getTransaction();
        tx.begin();//开启事务
        //4.完成增删改查操作
        Customer customer = new Customer();
        customer.setCustName("小明");
        customer.setCustIndustry("架构师");
        //保存
        entityManager.persist(customer);//保存操作
        //5.提交事务
        tx.commit();
        //6.释放资源
        entityManager.close();
        //factory.close();
    }
  • Find查询方法
    @Test
    public void testFind(){
        //1.通过工具类获取EntityManager
        EntityManager entityManager = JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction tx = entityManager.getTransaction();
        tx.begin();
        //3增删改查(根据Id查询客户)
        /**
         * find 根据Id查询客户
         *      class:查询数据的结果需要包装的实体类类型字节码
         *      id:查询的主键的取值
         */
       Customer customer = entityManager.find(Customer.class, 1l);
        //Customer customer = entityManager.getReference(Customer.class,1L);
        System.out.println(customer);

        //4.提交事务
        tx.commit();
        //5.释放资源
        entityManager.close();
    }
  • getReference方法查询
 @Test
    public void testReference(){
        //1.通过工具类获取EntityManager
        EntityManager entityManager = JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction tx = entityManager.getTransaction();
        tx.begin();
        //3增删改查(根据Id查询客户)
        /**
         * find 根据Id查询客户
         *      class:查询数据的结果需要包装的实体类类型字节码
         *      id:查询的主键的取值
         */
        // Customer customer = entityManager.find(Customer.class, 1l);
        Customer customer = entityManager.getReference(Customer.class, 1l);
        System.out.println(customer);

        //4.提交事务
        tx.commit();
        //5.释放资源
        entityManager.close();
    }

  • 更新和删除方法
    @Test
    public void testRemove(){
        //1.通过工具类获取EntityManager
        EntityManager entityManager = JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction tx = entityManager.getTransaction();
        tx.begin();
        //3增删改查(根据Id查询客户)
            //i 根据id查询客户
            //调用remove方法完成删除操作
        Customer customer = entityManager.find(Customer.class, 1l);
        entityManager.remove(customer);
        //4.提交事务
        tx.commit();
        //5.释放资源
        entityManager.close();
    }

    @Test
    public void testUpdata(){
        //1.通过工具类获取EntityManager
        EntityManager entityManager = JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction tx = entityManager.getTransaction();
        tx.begin();
        //3增删改查(根据Id查询客户)
        //客户的更新操作
        //i查询客户
        Customer customer = entityManager.find(Customer.class, 2l);
        //ii 更新客户
        customer.setCustIndustry("高级开发工程师");
        entityManager.merge(customer);
        //4.提交事务
        tx.commit();
        //5.释放资源
        entityManager.close();
    }

getReference和find方法的区别

  • 使用find方法查询(立即加载)
    • 1.查询的对象就是当前客户对象本身
    • 2.在调用find方法的时候,就会发送sql语句,查询数据库
  • 使用getRefrence方法
    • 1.获取的对象是一个动态代理对象
    • 2.调用不会立即发送sql语句查询数据库(延迟加载/懒加载)
    • 3.当调用查询结果对象的时候,才会发送sql语句查询数据库(什么时候用,什么时候发送sql语句查询)
    • 4.得到的是一个动态代理对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值