写点什么

JPA 基本使用,Java 虚拟机学习集锦是我攒来的

  • 2021 年 11 月 10 日
  • 本文字数:5425 字

    阅读完需:约 18 分钟

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 '客户联系电话',


PRIMARY KEY (cust_id)


) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


创建客户的实体类,编写映射配置:


在实体类上使用 JPA 注解的形式配置映射关系,所有的注解都是使用 JPA 的规范提供的注解,在导入注解包的时候,一定要导入 javax.persistence 下的包。常用注解的说明:


  • @Entity 作用: 指定当前类是实体类。

  • @Table 作用: 指定实体类和表之间的对应关系。属性:name:指定数据库表的名称

  • @Id 作用: 指定当前字段是主键。

  • @GeneratedValue 作用: 指定主键的生成方式。 属性:strategy :指定主键生成策略。


GenerationType.IDENTITY:主键由数据库自动生成,需要数据库支持自增长,适用于 mysql 数据库


GenerationType.SEQUENCE:根据底层数据库的序列来生成主键,需要数据库支持序列,适用于 Oracle


GenerationType.AUTO:主键由程序控制,会在数据库中生成数据库表格保存主键


GenerationType.TABLE:使用一个特定的数据库表格来保存主键,可以自动生成


  • @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") //指定和表中 cust_id 字段的映射关系


private Long custId;


@Column(name="cust_name") //指定和表中 cust_name 字段的映射关系


private String custName;


@Column(name="cust_source")//指定和表中 cust_source 字段的映射关系


private String custSource;


@Column(name="cust_industry")//指定和表中 cust_industry 字段的映射关系


private String custIndustry;


@Column(name="cust_level")//指定和表中 cust_level 字段的映射关系


private String custLevel;


@Column(name="cust_address")//指定和表中 cust_address 字段的映射关系


private String custAddress;


@Column(name="cust_phone")//指定和表中 cust_phone 字段的映射关系


private String custPhone;


/**


  • Get、Set、toString


*/


}


配置 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">


<!--配置持久化单元


name:持久化单元名称


transaction-type:事务类型


RESOURCE_LOCAL:本地事务管理


JTA:分布式事务管理 -->


<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">


<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>


<properties>


<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />


<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8" />


<property name="javax.persistence.jdbc.user" value="root" />


<property name="javax.persistence.jdbc.password" value="520992" />


<!--配置 jap 实现(hibernate)的配置信息


显示 sql :false|true


自动创建数据库表:hibernate.hbm2dd1.auto


create :程序运行时创建数据库表(如果表存在,先删除表再创建表)


update :程序运行时创建表(如果表存在,不创建)


none :不会创建表


-->


<property name="hibernate.show_sql" value="true" />


<property name="hibernate.format_sql" value="true" />


<property name="hibernate.hbm2ddl.auto" value="update" />


</properties>


</persistence-unit>


</persistence>


JPA 的 API 介绍




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


String unitName = "myJpa";


EntityManagerFactory factory= Persistence.createEntityManagerFactory(unitName);


EntityManagerFactory:主要用来创建 EntityManager 实例,由于 EntityManagerFactory 是一个线程安全的对象(即多个线程访问同一个 EntityManagerFactory 对象不会有线程安全问题),并且 EntityManagerFactory 的创建极其浪费资源,所以在使用 JPA 编程时,我们可以对其进行优化,满足一个项目中只有一个 EntityManagerFactory。


//创建实体管理类


EntityManager em = factory.createEntityManager();


EntityManager: 是完成持久化操作的核心对象,通过调用 EntityManager 可以将实体类转化为持久化对象。EntityManager 对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过 JPQL 语句查询实体。


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


  • getTransaction : 获取事务对象

  • persist : 保存操作

  • merge : 更新操作

  • remove : 删除操作

  • find/getReference : 根据 id 查询


EntityTransaction: 在 JPA 规范中,EntityTransaction 是完成事务操作的核心对象,对于 EntityTransaction 在我们的 java 代码中承接的功能比较简单 begin:开启事务commit:提交事务rollback:回滚事务


测试代码:


@Test


public void test() {


/**


  • 创建实体管理类工厂,借助 Persistence 的静态方法获取


*/


EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");


//创建实体管理类,工厂对象


EntityManager em = factory.createEntityManager();


//获取事务对象,通过实体管理类工厂获取实体管理器


EntityTransaction tx = em.getTransaction();


//开启事务,获取事务对象


tx.begin();


//完成增删改查操作


Customer c = new Customer();


c.setCustName("客户 1");


c.setCustIndustry("程序员");


//保存操作


em.persist(c);


//提交事务(回滚事务)


tx.commit();


//释放资源


em.close();


factory.close();


}


JPA 中的主键生成策略:


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


@Id


@GeneratedValue(strategy = GenerationType.IDENTITY)


private Long custId;


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


@Id


@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="payablemoney_seq")


@SequenceGenerator(name="payablemoney_seq", sequenceName="seq_payment")


private Long custId;


  • 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;


使用 JPA 完成增删改查操作




1. 抽取 JPAUtil 工具类:


通过静态代码块的形式, 解决实体管理类(EntityManagerFactory)工厂资源浪费和耗时问题。 使用静态代码块,当程序第一次访问此工具类的 getEntityManager 方法,经过静态代码块创建一个 factory 对象,再次调用方法创建一个 EntityManager 对象,当程序第二次访问 getEntityManager 方法时,直接通过一个已经创建好的 factory 对象,创建 EntityManager 对象。


/**


  • @Author: Ly

  • @Date: 2020-11-27 21:09


*/


public class JpaUtils {


// JPA 的实体管理器工厂:相当于 Hibernate 的 SessionFactory


private static EntityManagerFactory factory;


// 使用静态代码块赋值


static {


// 注意:该方法参数必须和 persistence.xml 中 persistence-unit 标签 name 属性取值一致


factory = Persistence.createEntityManagerFactory("myJpa");


}


/**


  • 使用管理器工厂生产一个管理器对象

  • @return


*/


public static EntityManager getEntityManager() {


return factory.createEntityManager();


}


}


2. 测试增删改查:


  • persist :保存

  • merge : 更新

  • remove : 删除

  • find/getRefrence:根据 id 查询


class::查询数据的结果需要包装的实体类类型的字节码


id: 查询主键的取值


2.1 保存


@Test


public void testSave() {


EntityManager em = JpaUtils.getEntityManager();


//获取事务对象,通过实体管理类工厂获取实体管理器


EntityTransaction tx = em.getTransaction();


//开启事务,获取事务对象


t


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


x.begin();


//完成保存操作


Customer customer = new Customer();


customer.setCustName("客户 2");


customer.setCustIndustry("教育");


//保存操作


em.persist(customer);


//提交事务(回滚事务)


tx.commit();


//释放资源


em.close();


}


2.2 修改


@Test


public void testUpdate() {


EntityManager em = JpaUtils.getEntityManager();


//获取事务对象,通过实体管理类工厂获取实体管理器


EntityTransaction tx = em.getTransaction();


//开启事务,获取事务对象


tx.begin();


//更新客户


Customer customer=em.find(Customer.class,1l);


customer.setCustIndustry("IT 教育");


em.merge(customer);


//提交事务(回滚事务)


tx.commit();


//释放资源


em.close();


}


2.3 删除


@Test


public void testRemove() {


EntityManager em = JpaUtils.getEntityManager();


//获取事务对象,通过实体管理类工厂获取实体管理器


EntityTransaction tx = em.getTransaction();


//开启事务,获取事务对象


tx.begin();


//删除客户


//根据 id 查询


Customer customer = em.find(Customer.class, 1l);


//删除用户


em.remove(customer);


//提交事务(回滚事务)


tx.commit();


//释放资源


em.close();


}


2.4 根据 id 查询


find 与 getReference:


  • find: 查询的对象是当前客户对象本身,在调用 find 方法的时候,就会发送 sql 语句数据库 (立即加载)

  • getReference: 查询对象是一个动态代理对象,调用 getReference 方法立即发送 sql 语句查询数据,当调用查询结果对象的时候,才会发送查询的 sql 语句,即什么时候用,什么时候发送 sql 语句查询数据库 (延迟加载)


@Test


public void testFind() {


//通过工具类获取 entityManager


EntityManager em = JpaUtils.getEntityManager();


//获取事务对象,通过实体管理类工厂获取实体管理器


EntityTransaction tx = em.getTransaction();


//开启事务,获取事务对象


tx.begin();


//完成查询操作


//Customer customer = em.find(Customer.class,1l);


Customer customer = em.getReference(Customer.class,1l);


System.out.println(customer);


//提交事务(回滚事务)


tx.commit();


//释放资源


em.close();


}


JPA 中的复杂查询




JPA 定义了独特的 JPQL(Java Persistence Query Language),JPQL 是 EJB 查询语言的一种扩展,以面向对象表达式语言的表达式,将 SQL 语法和简单查询语义绑定在一起。它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,因此其具有可移植性,可以被编译成所有主流数据库服务器上的 SQL。其特征与原生 SQL 语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性。


JPQL 支持批量更新和修改、JOIN、GROUP BY、HAVING 等高级查询特性,同时还能够支持子查询


1. 查询全部


//查询所有客户


@Test


public void findAll() {


EntityManager em = null;


EntityTransaction tx = null;


try {


//获取实体管理对象


em = JpaUtils.getEntityManager();


//获取事务对象


tx = em.getTransaction();


tx.begin();


// 创建 query 对象


//jqpl: from com.ly.domain.Customer


//sql: select * from cst_cus_customer


String jpql = "from Customer";


Query query = em.createQuery(jpql);


// 查询并得到返回结果


List list = query.getResultList(); // 得到集合返回类型


for (Object object : list) {


System.out.println(object);


}


tx.commit();


} catch (Exception e) {


// 回滚事务


tx.rollback();


e.printStackTrace();


} finally {


// 释放资源


em.close();


}


}


2. 分页查询


//分页查询客户


@Test


public void findPaged () {


EntityManager em = null;


EntityTransaction tx = null;


try {


//获取实体管理对象


em = JpaUtils.getEntityManager();


//获取事务对象


tx = em.getTransaction();


tx.begin();


//创建 query 对象


String jpql = "from Customer";


Query query = em.createQuery(jpql);


//起始索引


query.setFirstResult(0);


//每页显示条数


query.setMaxResults(2);


//查询并得到返回结果


List list = query.getResultList(); //得到集合返回类型


for (Object object : list) {


System.out.println(object);


}


tx.commit();


} catch (Exception e) {


// 回滚事务


tx.rollback();


e.printStackTrace();


} finally {


// 释放资源


em.close();


}


}


3. 条件查询


//条件查询


@Test


public void findCondition () {


EntityManager em = null;

评论

发布
暂无评论
JPA基本使用,Java虚拟机学习集锦是我攒来的