JPA——入门

1.使用背景

1.1 ORM

1.1.1 ORM概述

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

1.1.2 为什么使用ORM

当实现一个应用程序时(不使用O/R Mapping),我们可能会写特别多数据访问层的代码,从数据库保存数据、修改数据、删除数据,而这些代码都是重复的。而使用ORM则会大大减少重复性代码。对象关系映射(Object Relational Mapping,简称ORM),主要实现程序对象到关系数据库数据的映射。

常见的orm框架:Mybatis(ibatis)、Hibernate、Jpa。

1.2 JPA

1.2.1 JPA 概述

JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。JPA通过JDK 5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

1.2.2 JPA优势

1. 标准化

 JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 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是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。

5. 高级特性

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

1.3 JPA与Hibernate的关系

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

 

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

2.入门案例——搭建开发环境

需求:实现的功能是保存一个客户到数据库的客户表中。

创建一个Maven工程。

2.1 导入jar包

有两种方式:

1.传统方式导入jar包

2.maven工程导入坐标

 <dependencies>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- hibernate对jpa的支持包 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.6.Final</version>
        </dependency>
        <!-- log日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- Mysql and MariaDB -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.6.Final</version>
        </dependency>
    </dependencies>

2.2 创建客户的数据库表和客户的实体类

创建客户的数据库表:

/*创建客户表*/
    CREATE TABLE cst_customer (
      cust_id bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
      cust_name varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
      cust_source varchar(32) DEFAULT NULL COMMENT '客户信息来源',
      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 

创建客户的实体类

public class Customer {

    private long custId;  //客户主键
    private String custName;  //客户名称
    private String custSource;  //来源
    private String custLevel;  //级别
    private String custIndustry;  //所属行业
    private String custPhone;  //联系方式
    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 + '\'' +
                '}';
    }

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

这个部分要完成两个映射关系:

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

在实体类上使用JPA注解的形式配置映射关系

import javax.persistence.*;

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

 */
@Entity
@Table(name = "cst_customer")
public class Customer {
    /**
     *  @Id:声明主键的配置
     *  @GeneratedValue:配置主键的生成策略
     *    strategy属性:
     *       GenerationType.IDENTITY:自增,底层数据库必须支持自动增长,对ID进行自增,mysql数据库
     *       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 + '\'' +
                '}';
    }


}

常用注解说明:

注解名称作用属性说明
@Entity指定当前类是实体类 
@Table指定实体类和表之间的对应关系name:指定数据库表的名称
@Id指定当前字段是主键 
@GeneratedValue指定主键的生成方式stratehy:指定主键生成策略
@Column指定实体类属性和数据库表之间的关系

name:指定数据库表的列名称

unique:是否唯一

nullable:是否可以为空

insertable:是否可以插入

updateable:是否可以更新

columnDefinition:定义建表时创建此列的DDL

secondaryTable:从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境

主键生成策略:

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

具体说明如下:

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;

2.4 配置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:事务管理的方式
                          JTA:分布式事务管理(不同的表分布在不同的数据库中)
                          RESOURCE_LOCAL:本地事务管理-->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!--jap的实现方式-->
       <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <!--数据库信息-->
        <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="password"/>
            <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=UTC"/>
            <!--可选配置:配置JPA实现方(hibernate)的配置
                  显示sql        :hibernate.show_sql
                  自动创建数据库表:hibernate.hbm2ddl.auto
                                  create 程序运行时创建数据库表,如果有表,先删除表再创建
                                  update 程序运行时创建表,如果有表,不会创建表
                                  none  不会创建表
            -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            
        </properties>
    </persistence-unit>
</persistence>

3.JPA的的API介绍

3.1 Persistence对象

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

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

3.2 EntityManagerFactory

EntityManagerFactory 接口主要用来创建 EntityManager 实例

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

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

3.3 EntityManager

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

Bean, 还可以通过JPQL语句查询实体。我们可以通过调用EntityManager的方法完成获取事务,以及持久化数据库的操作

方法说明:

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

3.4 EntityTransaction

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

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

4.JPA操作

4.1 JPA执行的操作步骤

  /**
     * 测试JPA的保存:
     *   保存一个客户到数据库中
     *  JPA的操作步骤:
     *    1.加载配置文件创建工厂(实体管理类工厂)对象
     *    2.通过实体类管理类工厂获得实体管理器
     *    3.获取事务对象开启事务
     *    4.完成增删改查操作
     *    5.提交事务(回滚事务)
     *    6.释放资源
     */
 

4.2 抽取工具类

EntityManagerFactory的创建过程比较浪费资源。如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题?
            思路:创建一个公共的EntityManagerFactory的对象,静态代码块的形式创建EntityManagerFactory

/**
 * 解决实体管理器工程的浪费资源和耗时问题
 *    通过静态代码块的形式,当程序第一次访问此工具类是,创建一个公共的实体管理器工厂对象
 *
 *   第一次访问getEntityManager,首先经过静态代码块,创建一个factory对象,再调用方法创建EntityManager实体类对象
 *   第二次访问getEntityManager,直接通过已经创建好的factory对象,创建EntityManager对象
 */
public final class JpaUtils {
    private static EntityManagerFactory factory;
    static {
        //1.加载配置文件,创建entityManagerFactory
       factory = Persistence.createEntityManagerFactory("myJpa");
    }

    /**
     * 获取EntityManager实体类对象
     */
    public static EntityManager getEntityManager(){
        return factory.createEntityManager();
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

4.3 保存操作:EntityManager.persist

 @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();  //开启事务
        //4.保存一个数据到数据库中
        Customer customer=new Customer();
        customer.setCustName("创智");
        customer.setCustIndustry("互联网");
        //保存
        entityManager.persist(customer);  //保存操作
        //5.提交事务
        transaction.commit();
        //6.释放资源
        entityManager.clear();

    }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

4.4 根据ID查询:EntityManager.find/getReference

有两种方法:

  • find:查询的对象就是当前的客户对象;在调用find方法的时候,就会发送sql语句查询数据库(立即加载)
  • getReference:获取的对象是一个动态代理对象, 调用getReference方法不会立即发送SQL语句查询数据库,当调用查询结果对象的时候,才会发送查询的SQL语句(什么时候用什么时候发送查询SQL语句到数据库,延迟加载)。
/**
     * 根据ID查询客户
     * 使用find方法:
     *     查询的对象就是当前的客户对象
     *     在调用find方法的时候,就会发送sql语句查询数据库
     *  立即加载
     */
    @Test
    public void testFind(){
        //1.使用工具类,获得对象
        EntityManager entityManager= JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.增删改查
        /**
         * find:根据ID查询参数
         *    class: 查询数据的结果需要包装实体类类型的字节码
         *    id:查询主键的取值
         */
        Customer customer = entityManager.find(Customer.class, 1l);
        System.out.println(customer);
        //4.提交事务
        transaction.commit();
        //5.释放资源
        entityManager.close();

    }

    /**
     * 根据ID查询客户
     * 使用getReference方法:
     *        获取的对象是一个动态代理对象
     *        调用getReference方法不会立即发送SQL语句查询数据库,当调用查询结果对象的时候,才会发送查询的SQL语句(什么时候用什么时候发送查询SQL语句到数据库)
     *   延迟加载(懒加载):
     *        得到的是一个动态代理对象
     *        什么时候用什么时候发送查询SQL语句到数据库
     *   一般是使用延迟加载方法
     */
    @Test
    public void testReference(){
        //1.使用工具类,获得对象
        EntityManager entityManager= JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.增删改查
        /**
         * find:根据ID查询参数
         *    class: 查询数据的结果需要包装实体类类型的字节码
         *    id:查询主键的取值
         */
        Customer customer = entityManager.getReference(Customer.class, 1l);
        System.out.println(customer);
        //4.提交事务
        transaction.commit();
        //5.释放资源
        entityManager.close();

    }

4.5 根据ID删除:EntityManager.remove

 /**
     * 根据ID删除
     */
    @Test
    public void testRemove(){
        //1.使用工具类,获得对象
        EntityManager entityManager= JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.增删改查
        //i.根据ID查询客户
        Customer customer=entityManager.find(Customer.class,1l);
        //ii.根据remove方法完成删除操作
        entityManager.remove(customer);
        //4.提交事务
        transaction.commit();
        //5.释放资源
        entityManager.close();
    }

4.6 更新:EntityManager.merge

 /**
     * 更新
     */
    @Test
    public void testUpdate(){
        //1.使用工具类,获得对象
        EntityManager entityManager= JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.增删改查--更新
        //i.根据ID查询客户
        Customer customer=entityManager.find(Customer.class,2l);
        //ii.根据remove方法完成删除操作
        customer.setCustIndustry("IT");
        entityManager.merge(customer);
        //4.提交事务
        transaction.commit();
        //5.释放资源
        entityManager.close();
    }

5.JPA的复杂查询

JPQL(Java持久性查询语言)是一种面向对象的查询语言,用于对持久实体执行数据库操作。 JPQL不使用数据库表,而是使用实体对象模型来操作SQL查询。 这里,JPA的作用是将JPQL转换为SQL。因此,它为开发人员提供了一个处理SQL任务的简单方式。

JPQL是实体JavaBeans查询语言(EJBQL)的扩展,向其添加了以下重要功能 -

  • 它可以执行连接操作。
  • 它可以批量更新和删除数据。
  • 它可以使用排序和分组子句执行聚合函数。
  • 单值和多值结果类型。

JPA的查询语言,类似于sql,书写规则如下:

  • 1.里面不能出现表名,列名,只能出现java的类名,属性名,区分大小写
  • 2.出现的sql关键字是一样的意思,关键字不区分大小写
  • 3.不能写select * 要写select 别名

5.1 查询全部

 /**
     * 查询全部
     *   jpql  from Customer
     *   sql:select * from cst_customer
     */

    @Test
    public void testFindALl(){
        //1.获取EntityManager对象
        EntityManager entityManager=JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.查询全部
        String jpql = "from Customer";
        Query query = entityManager.createQuery(jpql);//创建Query对象,query对象才是执行JPQL的对象
        //发送查询,并封装结果集
        List resultList = query.getResultList();
        for (Object obj:resultList)
        {
            System.out.println(obj);
        }

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

5.2 倒序查询

 /**
     * 排序查询:倒序查询所有客户
     *   sql:select * from cst_customer order by cust_id DESC
     *   jpql: from Customer order by custId
     *
     * 进行jpql查询:
     *    1.创建Query查询对象
     *    2.对参数进行赋值
     *    3.查询,并得到返回值
     */
    @Test
    public void testOrder(){
        //1.获取EntityManager对象
        EntityManager entityManager=JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.查询全部
        String jpql = "from Customer order by custId desc";
        Query query = entityManager.createQuery(jpql);//创建Query对象,query对象才是执行JPQL的对象
        //发送查询,并封装结果集
        List resultList = query.getResultList();
        for (Object obj:resultList)
        {
            System.out.println(obj);
        }

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

5.3 统计查询

 /**
     * 统计客户总数
     *   sql:select count(cust_id) from cst_customer
     *   jpql: select count(custId) from Customer
     */
    @Test
    public void testCount(){
        //1.获取EntityManager对象
        EntityManager entityManager=JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.查询全部
        String jpql = "select count(custId) from Customer";
        Query query = entityManager.createQuery(jpql);//创建Query对象,query对象才是执行JPQL的对象
        //发送查询,并封装结果集
        Object singleResult = query.getSingleResult();
        System.out.println(singleResult);
        //4.提交事务
        transaction.commit();
        //5.释放资源
        entityManager.close();
    }

5.4 分页查询

 /**
     * 分页查询
     *   sql:select * from cst_customer limit ?,?
     *   jpql: from Customer
     */
    @Test
    public void testPaged(){
        //1.获取EntityManager对象
        EntityManager entityManager=JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.查询全部
        String jpql = "from Customer";
        Query query = entityManager.createQuery(jpql);//创建Query对象,query对象才是执行JPQL的对象
        //对参数进行赋值--分页参数
        //起始索引
        query.setFirstResult(0);
        //每页查询的页数
        query.setMaxResults(2);
        //发送查询,并封装结果集
        List resultList = query.getResultList();
        for (Object obj:resultList)
        {
            System.out.println(obj);
        }
        //4.提交事务
        transaction.commit();
        //5.释放资源
        entityManager.close();
    }

5.5 条件查询

  /**
     * 条件查询
     * 查询客户名称,以IT开头
     *   sql:select * from cst_customer where cust_name like ?
     *   jpql: from Customer where custName like ?
     */
    @Test
    public void testCondition(){
        //1.获取EntityManager对象
        EntityManager entityManager=JpaUtils.getEntityManager();
        //2.开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        //3.查询全部
        String jpql = "from Customer where custName like ?";
        Query query = entityManager.createQuery(jpql);//创建Query对象,query对象才是执行JPQL的对象
        //对参数进行赋值--占位符参数
        //第一个参数指的是占位符的位置
        //第二个参数取值
        query.setParameter(1,"传智%");
        //发送查询,并封装结果集
        List resultList = query.getResultList();
        for (Object obj:resultList)
        {
            System.out.println(obj);
        }
        //4.提交事务
        transaction.commit();
        //5.释放资源
        entityManager.close();
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值