Jpa使用教程(1)

1、ORM概述

  • ORM(Object-Relational Mapping) 表示对象关系映射。在面向对象的软件开发中,通过ORM,就可以把对象映射到关系型数据库中。只要有一套程序能够做到建立对象与数据库的关联,操作对象就可以直接操作数据库数据,就可以说这套程序实现了ORM对象关系映射

  • 简单的说:ORM就是建立实体类和数据库表之间的关系,从而达到操作实体类就相当于操作数据库表的目的。
    常见的orm框架:Mybatis(ibatis)、Hibernate

2、为什么使用ORM

ORM则会大大减少重复性代码。下图是使用JDBC操作数据库连接查询的语句,可见语句十分繁琐。
在这里插入图片描述

3、什么是JPA

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

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

4、JPA与Hibernate的关系

  • JPA和Hibernate的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现。JPA怎么取代Hibernate呢?JDBC规范可以驱动底层数据库吗?答案是否定的,也就是说,如果使用JPA规范进行数据库操作,底层需要hibernate作为其实现类完成数据持久化工作。
  • 这里不详细展开hibernate这种框架,hibernate实现数据库操作是对JDBC进行了非常轻量级的对象封装
  • 下图展现了各个上述的关系。
  • 在这里插入图片描述
    在这里插入图片描述

5、JPA的基本操作

  • jpa操作的操作步骤

    1. 加载配置文件创建实体管理器工厂
    Persisitence:静态方法(根据持久化单元名称创建实体管理器工厂)
    createEntityMnagerFactory(持久化单元名称)
    作用:创建实体管理器工厂

    2. 根据实体管理器工厂,创建实体管理器
    EntityManagerFactory :获取EntityManager对象
    方法:createEntityManager
    * 内部维护的很多的内容
    内部维护了数据库信息,
    维护了缓存信息
    维护了所有的实体管理器对象
    再创建EntityManagerFactory的过程中会根据配置创建数据库表
    * EntityManagerFactory的创建过程比较浪费资源
    特点:线程安全的对象
    多个线程访问同一个EntityManagerFactory不会有线程安全问题
    * 如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题?
    思路:创建一个公共的EntityManagerFactory的对象
    * 静态代码块的形式创建EntityManagerFactory

    3. 创建事务对象,开启事务
    EntityManager对象:实体类管理器
    beginTransaction : 创建事务对象
    presist : 保存
    merge : 更新
    remove : 删除
    find/getRefrence : 根据id查询
    Transaction 对象 : 事务
    begin:开启事务
    commit:提交事务
    rollback:回滚
    4. 增删改查操作
    5. 提交事务
    6. 释放资源

6、抽取JPAUtil工具类

  • 由于jpa的前三操作都是固定的,所以可以抽取出JPAUtil工具类,事务操作通过getEntityManager()方法就可以获得EntityManager对象,从而进行操作。
  • JPAUtil工具类
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();
	}
}

7、根据JPAUtil工具类对数据库进行操作

  • 配置数据库连接(src\main\resources\META-INF),可以是xml、yml、properties,本例使用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:事务管理的方式
                    JTA:分布式事务管理
                    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 name="javax.persistence.jdbc.password" value="111111"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>

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

            -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>
  • 创建客户实体类,Jpa中在实体类中使用的注解:

        1. @Entity:声明实体类
        2. @Table : 配置实体类和表的映射关系
        3. @Id:声明主键的配置
      	4. @GeneratedValue:配置主键的生成策略
      	5. @Column:配置属性和字段的映射关系:@Colum属性要么全写,要么都不写。
    
package cn.itcast.domain;

import javax.persistence.*;

/**
 * 客户的实体类
 *      配置映射关系
 *
 *
 *   1.实体类和表的映射关系
 *      @Entity:声明实体类
 *      @Table : 配置实体类和表的映射关系
 *          name : 配置数据库表的名称
 *   2.实体类中属性和表中字段的映射关系
 *
 *
 */
@Entity
@Table(name = "cst_customer")
public class Customer {

    /**
     * @Id:声明主键的配置
     * @GeneratedValue:配置主键的生成策略
     *      strategy
     *          GenerationType.IDENTITY :自增,mysql
     *                 * 底层数据库必须支持自动增长(底层数据库支持的自动增长方式,对id自增)
     *          GenerationType.SEQUENCE : 序列,oracle
     *                  * 底层数据库必须支持序列
     *          GenerationType.TABLE : jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
     *          GenerationType.AUTO : 由程序自动的帮助我们选择主键生成策略
     * @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;//客户地址

    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 + '\'' +
                '}';
    }
}

  • 调用JPAUtil工具类进行保存操作。
/**
	 * 保存一个实体
	 */
	@Test
	public void testAdd() {
		// 定义对象
		Customer c = new Customer();
		c.setCustName("卢本伟");
		c.setCustLevel("赌怪");
		c.setCustSource("网络");
		c.setCustIndustry("伞兵");
		c.setCustAddress("卢本伟广场");
		c.setCustPhone("11111111");
		EntityManager em = null;
		EntityTransaction tx = null;
		try {
			// 获取实体管理对象
			em = JPAUtil.getEntityManager();
			// 获取事务对象
			tx = em.getTransaction();
			// 开启事务
			tx.begin();
			// 执行操作
			em.persist(c);
			// 提交事务
			tx.commit();
		} catch (Exception e) {
			// 回滚事务
			tx.rollback();
			e.printStackTrace();
		} finally {
			// 释放资源
			em.close();
		}
	}
  • 查询操作,有两种。
Customer c1 = em.find(Customer.class, 1L);//立即加载查询策略
Customer c1 = em.getReference(Customer.class, 1L)//延迟加载查询策略
  • 删除操作
Customer c1 = em.find(Customer.class, 6L);
			em.remove(c1);
  • 修改操作
Customer c1 = em.find(Customer.class, 6L);
       c1.setCustName("卢本伟广场");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值