JPA的入门CRUD

Posted yscec

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JPA的入门CRUD相关的知识,希望对你有一定的参考价值。

主要目的:

操作实体类就相当于操作数据库表

建立两个映射关系:

      实体类和表的映射关系

      实体类中的属性和表中字段的映射关系

不在关注sql语句

常见的orm框架:Mybatisibatis)、HibernateJpa

 

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

 

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

 

 技术图片

 

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

 

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:事务管理方式
RESOURCE_LOCAL:本地事务管理
jpa:分布式事务管理-->
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<!--jpa的实现方式-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

<properties>
<!--加载配置文件-->
<property name="persistenceXmlLocation" value="classpath:/META-INF/persistence.xml"/>
<!--数据库信息-->
<property name="hibernate.dialect" value="org.hibernate.dialect.mysqlDialect"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.2.100:3306/ytkj?serverTimeZone=UTC"/>
<property name="javax.persistence.jdbc.username" value="root"/>
<property name="javax.persistence.jdbc.password" value="123456"/>

<!--可选的配置:配置jpa实现方的配置信息,也就是hibernate的配置信息
显示sql hibernate.show.sql true

自动创建数据库表 hibernate.hbm2ddl.auto
create:程序运行时创建表。若有表先删除表在创建表
update:程序运行时创建表。若有表不会创建表
none: 不会创建表
-->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>

 

  

编写实体类和数据库表的映射配置

 

package com.ytk.entity;

import javax.persistence.*;
import java.io.Serializable;

/**
 *          @Entity
 *         	作用:指定当前类是实体类。
 *         @Table
 *         	作用:指定实体类和表之间的对应关系。
 *         	属性:
 *         		name:指定数据库表的名称
 *         @Id
 *         	作用:指定当前字段是主键。
 *         @GeneratedValue
 *         	作用:指定主键的生成方式。。
 *         	属性:
 *         		strategy :指定主键生成策略。
 *         @Column
 *         	作用:指定实体类属性和数据库表之间的对应关系
 *         	属性:
 *         		name:指定数据库表的列名称。
 *         		unique:是否唯一
 *         		nullable:是否可以为空
 *         		inserttable:是否可以插入
 *         		updateable:是否可以更新
 *         		columnDefinition: 定义建表时创建此列的DDL
 *         		secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境[重点]
 *
 * 客户实体类
 *      配置映射关系
 *          实体类和表映射
 *          实体类属性和表字段映射
 */
@Entity
@Table(name = "cst_customer")
public class Customer implements Serializable {
    /**
     * 声明主键配置
     */
    @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_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;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "custId=" + custId +
                ", custName=‘" + custName + ‘‘‘ +
                ", custSource=‘" + custSource + ‘‘‘ +
                ", custIndustry=‘" + custIndustry + ‘‘‘ +
                ", custLevel=‘" + custLevel + ‘‘‘ +
                ", custAddress=‘" + custAddress + ‘‘‘ +
                ", custPhone=‘" + custPhone + ‘‘‘ +
                ‘}‘;
    }
}

 

package com.ytk.utils;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 * 解决实体管理器工厂的浪费资源和耗时问题
 *      通过静态代码块的形式,当程序第一次访问此工具类时,创建一个公共的实体管理器工厂对象
 *
 * 第一次访问getEntityManager方法:经过静态代码块创建一个factory对象,再调用方法创建一个EntityManager对象
 * 第二次方法getEntityManager方法:直接通过一个已经创建好的factory对象,创建EntityManager对象
 */
public class JpaUtils {

    private static EntityManagerFactory factory;

    static  {
        //1.加载配置文件,创建entityManagerFactory
        factory = Persistence.createEntityManagerFactory("myJpa");
    }

    /**
     * 获取EntityManager对象
     */
    public static EntityManager getEntityManager() {
       return factory.createEntityManager();
    }
}

  

package com.ytkj.test;

import com.ytk.entity.Customer;
import com.ytk.utils.JpaUtils;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

/**
* jpa操作步骤
* 1.加载配置文件创建工厂对象
* 2.通过实体类工厂获取实体类管理器
* 3.获取事务对象,开启事务
* 4.完成crud
* 5.提交事务
* 6.释放资源
*
*/
public class JpaTest {

/**
* 保存
*/
@Test
public void testSave(){
//1.加载配置文件创建工厂对象
//EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");;
//2.通过实体类工厂获取实体类管理器
//EntityManager entityManager = factory.createEntityManager();
EntityManager entityManager = JpaUtils.getEntityManager();
//3.获取事务对象,开启事务
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//完成crud
Customer customer=new Customer();
customer.setCustName("zhechaochao");
customer.setCustIndustry("it");
//保存
entityManager.persist(customer);
//5.提交事务
transaction.commit();
//6.释放资源
entityManager.close();
//factory.close();

}

/**
* 查询
* find
* getreference 懒加载
*/
@Test
public void findById(){
EntityManager entityManager = JpaUtils.getEntityManager();
//3.获取事务对象,开启事务
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = entityManager.find(Customer.class, 1L);
//Customer customer = entityManager.getreference(Customer.class, 1L);
//5.提交事务
transaction.commit();
System.out.println(customer);
}

/**
* 删除
* find
* getreference 懒加载
*/
@Test
public void delete(){
EntityManager entityManager = JpaUtils.getEntityManager();
//3.获取事务对象,开启事务
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = entityManager.find(Customer.class, 1L);
if (customer!=null){
entityManager.remove(customer);
}
//5.提交事务
transaction.commit();

}

/**
* 更新
* find
* getreference 懒加载
*/
@Test
public void updateById(){
EntityManager entityManager = JpaUtils.getEntityManager();
//3.获取事务对象,开启事务
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = entityManager.find(Customer.class, 1L);
customer.setCustPhone("110");
customer.setCustAddress("昆明");
if (customer!=null){
entityManager.merge(customer);
}
//5.提交事务
transaction.commit();

}


}

  

 

 

 

 

 

 

以上是关于JPA的入门CRUD的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data JPA入门及深入

Spring Data JPA入门及深入

MyBatis-plus的入门学习

第120天学习打卡(MyBatisPlus 概述 特性 入门 配置日志 CRUD扩展 乐观锁)

SpringDataJPA 入门

是否可以在不使用 Spring Boot JPA 的情况下测试基于 java 的 CRUD?