JPA第一章

文章目录

JPA第一章

一、什么是jpa

​ jpa是一个开发规范,是一个orm框架的开发规范。是sun公司定义的。
​ orm:对象关系映射。是一个解决问题的一个思路。

二、jpa的提供商

1、Hibernate(使用)

​ 完全支持jpa。业内最好的一个jpa框架。

2、OpenJpa

​ 是apache旗下的一个开源项目,也是jpa规范的实现。

3、TopLink

​ 也是一个开源项目。是Oracle公司的。

三、SpringDataJpa

​ 并不是jpa规范的实现。基于原生jpa的api进行了再次的封装,
​ 提供更简单的使用方法,和更好的用户体验。
​ 如果要使用SpringDataJpa还是需要使用Hibernate。

四、入门程序

1、需求

​ 向客户表中插入一条数据。
​ 如果使用Jpa框架可以不用先建表。可以使用框架生成表。

​ 导入Jar包

  • <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.hibernate.version>5.0.7.Final</project.hibernate.version>
    </properties>
    <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-entitymanager</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>
        <!-- c3p0 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>${project.hibernate.version}</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>5.1.6</version>
        </dependency>
        <!-- 或者使用oracle数据库
     	<dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc14</artifactId>
            <version>10.2.0.2.0</version>
        </dependency>
    	-->
    </dependencies>
    

2、实现步骤

​ 1)创建一个工程。创建一个java工程即可。可以使用maven管理工程。
​ 2)创建一个配置文件。
​ 配置文件必须在classpath:/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="sgw_jpa" transaction-type="RESOURCE_LOCAL">
            <!--持久化单元的属性配置-->
            <properties>
                <!--数据库连接的属性-->
                <!-- mysql数据库 -->
                <property name="javax.persistence.jdbc.user" value="root"/>
                <property name="javax.persistence.jdbc.password" value="root"/>
    			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
    			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa_sgw?characterEncoding=utf8"/>
    
                <!-- oracle数据库 
                <property name="javax.persistence.jdbc.user" value="scott"/>
                <property name="javax.persistence.jdbc.password" value="tiger"/>
                <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
                <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@192.168.211.128:1521:orcl"/>
    			-->
                <!--Hibernate的属性配置-->
                <!--是否打印sql语句-->
                <property name="hibernate.show_sql" value="true"/>
                <!--是否格式化sql语句-->
                <property name="hibernate.format_sql" value="true"/>
                <!--是否自动创建数据库表
                    可选值:create、update、none
                    create:程序自动创建数据库表,如果表存在则先删除后创建
                    update:程序自动创建数据库表,如果表存在则不创建。
                    none:不会创建表
                -->
                <property name="hibernate.hbm2ddl.auto" value="create"/>
            </properties>
        </persistence-unit>
    </persistence>
    

​ 3)创建一个Entity类。对应数据库中每个表创建一个实体类。
​ 配置映射关系。

  • package cn.sgwks.jpa.entity;
    import javax.persistence.*;
    //代表是一个jpa的实体类
    @Entity
    //配置实体类和数据库中表的映射关系 name对应的表名
    @Table(name = "cst_customer")
    public class Customer {
        //配置主键的生成策略
        /**
         * 1: @GeneratedValue(strategy = GenerationType.IDENTITY)====>自增长
         * 2: @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cust_seq")====>使用序列生成主键
         *      @SequenceGenerator(name = "cust_seq", sequenceName = "cust_sequence")
         * 3: @GeneratedValue(strategy = GenerationType.TABLE, generator = "tab_gen")====>使用表生成主键
         *      @TableGenerator(name = "tab_gen", table = "ids_gen", pkColumnName = "ids", valueColumnName = "vals", pkColumnValue = "customer", allocationSize = 1)
         * 4: @GeneratedValue(strategy = GenerationType.AUTO)
         */
        //在主键字段使用@Id标注
        @Id
        //配置属性和字段的映射关系
        @Column(name = "cust_id")
        //GenerationType.IDENTITY是自增长
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        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;}
    }
    

​ 4)编写测试程序,实现数据添加。
​ 1、创建一个EntityManagerFactory对象。在系统中一般都是单例的。
​ 2、使用工厂对象创建一个EntityManager对象。一个EntityManager就是一个连接。是一个多例对象。

使用完毕之后就关闭。
3、开启事务。
4、创建一个Customer对象。
5、使用Entitymanager对象的persist方法向数据库插入数据。
6、事务提交
7、关闭连接

  • package cn.sgwks.jpa;
    import cn.sgwks.jpa.entity.Customer;
    import org.junit.Test;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.EntityTransaction;
    import javax.persistence.Persistence;
    public class JpaManager {
        @Test
        public void firstTest(){
            //1、创建一个EntityManagerFactory对象。在系统中一般都是单例的。
            EntityManagerFactory factory = Persistence.createEntityManagerFactory("sgw_jpa");
            //2、使用工厂对象创建一个EntityManager对象。一个EntityManager就是一个连接。是一个多例对象。使用完毕之后就关闭。
            EntityManager entityManager = factory.createEntityManager();
            //3、开启事务。
            EntityTransaction transaction = entityManager.getTransaction();
            try {
                transaction.begin();
                //4、创建一个Customer对象。
                Customer customer = new Customer();
                customer.setCustName("sgw");
                customer.setCustSource("电话传销");
                customer.setCustIndustry("程序员");
                customer.setCustLevel("码农");
                customer.setCustAddress("AB市");
                customer.setCustPhone("12345678901");
                //5、使用Entitymanager对象的persist方法向数据库插入数据。
                entityManager.persist(customer);
                //6、事务提交
                transaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
                transaction.rollback();
            } finally {
                //7.关闭EntityManager连接
                entityManager.close();
                //8. 系统关闭之前关闭工厂对象。
                factory.close();
            }
        }
    }
    
  • 执行测试方法打印 hibernate打印create的sql语句

    Hibernate: 
        drop table if exists cst_customer
    Hibernate: 
        create table cst_customer (
            cust_id bigint not null auto_increment,
            cust_address varchar(255),
            cust_industry varchar(255),
            cust_level varchar(255),
            cust_name varchar(255),
            cust_phone varchar(255),
            cust_source varchar(255),
            primary key (cust_id)
        )
    Hibernate: 
        insert 
        into
            cst_customer
            (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source) 
        values
            (?, ?, ?, ?, ?, ?)
    
  • 执行测试方法打印 hibernate打印update的sql语句

    Hibernate: 
        insert 
        into
            cst_customer
            (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source) 
        values
            (?, ?, ?, ?, ?, ?)
    
  • 执行测试方法打印 hibernate打印none的sql语句

    • 如果表已创建

      Hibernate: 
          insert 
          into
              cst_customer
              (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source) 
          values
              (?, ?, ?, ?, ?, ?)
      
    • 如果表未创建,none不会自动创建表

      //会报异常:
      Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'jpa_sgw.cst_customer' doesn't exist
      
  • 执行测试方法查找指定id对象打印findById的java语句

    @Test
    public void findById() {
        //1、创建一个EntityManager对象
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        //2、使用find方法根据id查询
        Customer customer = entityManager.find(Customer.class, 2l);
        System.out.println("============================");
        //3、打印结果
        System.out.println(customer);
        //4、关闭连接
        entityManager.close();
    }
    
    • 打印 hibernate的查询sql语句

      Hibernate: 
          select
              customer0_.cust_id as cust_id1_0_0_,
              customer0_.cust_address as cust_add2_0_0_,
              customer0_.cust_industry as cust_ind3_0_0_,
              customer0_.cust_level as cust_lev4_0_0_,
              customer0_.cust_name as cust_nam5_0_0_,
              customer0_.cust_phone as cust_pho6_0_0_,
              customer0_.cust_source as cust_sou7_0_0_ 
          from
              cst_customer customer0_ 
          where
              customer0_.cust_id=?
      ============================
      Customer{custId=3, custName='sgw', custSource='电话营销', custIndustry='程序员', custLevel='码农', custAddress='AB市', custPhone='12345678901'}
      
  • 执行测试方法删除指定对象打印deleteCustomer的java语句

    @Test
    public void deleteCustomer() {
        //1)获得EntityManager对象
        EntityManager entityManager = factory.createEntityManager();
        //	2)开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        try {
            //	3)先从数据库中查询一个Customer对象
            //find方法根据主键查询
            //参数1:返回结果的数据类型,参数2:主键的值
            Customer customer = entityManager.find(Customer.class, 6l);
            //	4)使用entityManger对象remove方法删除。参数就是Customer对象。
            entityManager.remove(customer);
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        } finally {
            entityManager.close();
            factory.close();
        }
    }
    
    • 打印 hibernate的删除sql语句

      Hibernate: 
          select
              customer0_.cust_id as cust_id1_0_0_,
              customer0_.cust_address as cust_add2_0_0_,
              customer0_.cust_industry as cust_ind3_0_0_,
              customer0_.cust_level as cust_lev4_0_0_,
              customer0_.cust_name as cust_nam5_0_0_,
              customer0_.cust_phone as cust_pho6_0_0_,
              customer0_.cust_source as cust_sou7_0_0_ 
          from
              cst_customer customer0_ 
          where
              customer0_.cust_id=?
      Hibernate: 
          delete 
          from
              cst_customer 
          where
              cust_id=?
      
  • 执行测试方法修改指定对象打印updateCustomer的java语句

    @Test
    public void updateCustomer() {
        //1)获得EntityManager对象
        EntityManager entityManager = factory.createEntityManager();
        //	2)开启事务
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        try {
            //3)根据id查询一个Customer对象
            Customer customer = entityManager.find(Customer.class, 7l);
            //4)修改对象的属性。
            customer.setCustIndustry("软件工程师");
            //5) 把修改结果保存到数据库
            entityManager.merge(customer);
            //6)提交事务
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //7).异常事务回滚
            transaction.rollback();
        } finally {
            //8)关闭连接
            entityManager.close();
            factory.close();
        }
    }
    
    • 打印 hibernate的修改sql语句

      Hibernate: 
          select
              customer0_.cust_id as cust_id1_0_0_,
              customer0_.cust_address as cust_add2_0_0_,
              customer0_.cust_industry as cust_ind3_0_0_,
              customer0_.cust_level as cust_lev4_0_0_,
              customer0_.cust_name as cust_nam5_0_0_,
              customer0_.cust_phone as cust_pho6_0_0_,
              customer0_.cust_source as cust_sou7_0_0_ 
          from
              cst_customer customer0_ 
          where
              customer0_.cust_id=?
      Hibernate: 
          update
              cst_customer 
          set
              cust_address=?,
              cust_industry=?,
              cust_level=?,
              cust_name=?,
              cust_phone=?,
              cust_source=? 
          where
              cust_id=?
      

3、配置文件

  1. persistence-unit:持久化单元。每个配置文件中至少有一个持久化单元的配置。

    • name:持久化单元的名称。不能重复。

    • transaction-type:事务类型

      RESOURCE_LOCAL:单数据库的事务。
      JTA:分布式事务,跨数据库的事务,多个数据库的事务。
      
    • property

      hibernate.show_sql:是否在控制台输出sql语句。
      true 打印/false 不打印
      
    • hibernate.hbm2ddl.auto:是否自动创建表

      create:自动创建表,先删除后创建。仅供测试使用。不能应用在正式环境。
      update:自动创建表,如果表存在就直接使用,如果不存在就创建。可以应用在正式环境。
      none:不自动创建表。如果表存在就直接使用,如果不存在就报错。
      

4、实体类

  1. @Entity:代表是一个jpa的实体类。

  2. @Table:配置实体类和表的映射关系
    name:配置表名。

  3. @Column:配置实体类的属性和字段的映射关系。
    如果实体类的属性和字段名称相同可以不用配置此注解。

  4. @Id:标记哪个属性是主键属性。

  5. @GeneratedValue:主键的生成方式。如果手动生成主键,可以没有此注解。

    • JAVA代码

      @Test
      public void addCustomer() {
          //创建EntityManager对象
          EntityManager entityManager = factory.createEntityManager();
          //开启事务
          EntityTransaction transaction = entityManager.getTransaction();
          transaction.begin();
          try {
              //4、创建一个Customer对象。
              Customer customer = new Customer();
              customer.setCustName("张三");
              customer.setCustSource("宣传");
              customer.setCustIndustry("经理");
              customer.setCustLevel("有钱人");
              customer.setCustAddress("cc市");
              customer.setCustPhone("16677889900");
              entityManager.persist(customer);
              transaction.commit();
          } catch (Exception e) {
              e.printStackTrace();
              transaction.rollback();
          } finally {
              entityManager.close();
              factory.close();
          }
      }
      

    ​ 如果主键需要框架生成需要配置此注解。

    • 1)GenerationType.IDENTITY:自增长主键。推荐在mysql下使用,不能在Oracle使用

    • 2)GenerationType.SEQUENCE:使用序列生成主键,一般是在Oracle下使用,不推荐在mysql下使用,在mysql中使用表生成主键。

      • @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = “cust_seq”)

        generator:生成器的名称
        
      • @SequenceGenerator(name = “cust_seq”, sequenceName = “cust_sequence”,allocationSize = 1)

      • @SequenceGenerator:定义一个生成器

        name:生成器的名称
        sequenceName:Oracle数据库中序列对象的名称
        allocationSize = 1 如果每次增长值不设置默认是50 
            int allocationSize() default 50;
        
      • sql语句如果表未创建:

        Hibernate: 
            drop table if exists cst_customer
        Hibernate: 
            drop table if exists cust_sequence
        Hibernate: 
            create table cst_customer (
                cust_id bigint not null,
                cust_address varchar(255),
                cust_industry varchar(255),
                cust_level varchar(255),
                cust_name varchar(255),
                cust_phone varchar(255),
                cust_source varchar(255),
                primary key (cust_id)
            )
        Hibernate: 
            create table cust_sequence (
                next_val bigint
            )
        Hibernate: 
            insert into cust_sequence values ( 1 )
        Hibernate: 
            select
                next_val as id_val 
            from
                cust_sequence for update
                    
        Hibernate: 
            update
                cust_sequence 
            set
                next_val= ? 
            where
                next_val=?
        Hibernate: 
            select
                next_val as id_val 
            from
                cust_sequence for update
                    
        Hibernate: 
            update
                cust_sequence 
            set
                next_val= ? 
            where
                next_val=?
        Hibernate: 
            insert 
            into
                cst_customer
                (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source, cust_id) 
            values
                (?, ?, ?, ?, ?, ?, ?)
        
      • sql语句如果表已经创建:

        Hibernate: 
            select
                next_val as id_val 
            from
                cust_sequence for update  
        Hibernate: 
            update
                cust_sequence 
            set
                next_val= ? 
            where
                next_val=?
        Hibernate: 
            insert 
            into
                cst_customer
                (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source, cust_id) 
            values
                (?, ?, ?, ?, ?, ?, ?)
        
    • 3)GenerationType.TABLE:使用数据库的表生成主键。

      @GeneratedValue(strategy = GenerationType.TABLE, generator = "tab_gen")
         @TableGenerator(name = "tab_gen", table = "ids_gen", pkColumnName = "ids", valueColumnName = "vals", pkColumnValue = "customer", allocationSize = 1)
      
      name:生成器的名称
      table:生成主键的表的名称
      pkColumnName:主键字段的名称
      valueColumnName:值字段的名称
      pkColumnValue:主键字段的值
      allocationSize:生成主键的步长,默认是5
      
      • sql语句如果表未创建:

        Hibernate: 
            drop table if exists cst_customer
        Hibernate: 
            drop table if exists ids_gen
        Hibernate: 
            create table cst_customer (
                cust_id bigint not null,
                cust_address varchar(255),
                cust_industry varchar(255),
                cust_level varchar(255),
                cust_name varchar(255),
                cust_phone varchar(255),
                cust_source varchar(255),
                primary key (cust_id)
            )
        Hibernate: 
            create table ids_gen (
                ids varchar(255) not null,
                vals bigint,
                primary key (ids)
            )
        Hibernate: 
            select
                tbl.vals 
            from
                ids_gen tbl 
            where
                tbl.ids=? for update
                    
        Hibernate: 
            insert 
            into
                ids_gen
                (ids, vals)  
            values
                (?,?)
        Hibernate: 
            update
                ids_gen 
            set
                vals=?  
            where
                vals=? 
                and ids=?
        Hibernate: 
            insert 
            into
                cst_customer
                (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source, cust_id) 
            values
                (?, ?, ?, ?, ?, ?, ?)
        
        Process finished with exit code 0
        
      • sql语句如果表已经创建:

        Hibernate: 
            select
                tbl.vals 
            from
                ids_gen tbl 
            where
                tbl.ids=? for update
                    
        Hibernate: 
            insert 
            into
                ids_gen
                (ids, vals)  
            values
                (?,?)
        Hibernate: 
            update
                ids_gen 
            set
                vals=?  
            where
                vals=? 
                and ids=?
        Hibernate: 
            insert 
            into
                cst_customer
                (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source, cust_id) 
            values
                (?, ?, ?, ?, ?, ?, ?)
        
    • 4)GenerationType.AUTO:由框架自动选择
      默认是使用数据库表生成主键。不推荐使用。

5、入门小结

​ 1)入门程序
​ 1、创建配置文件。classpath:META-INF/persistence.xml
​ 2、创建实体,配置映射关系。
​ 3、编写测试代码
​ 使用EntityManager对象实现数据库的增删改查。
​ 2)配置文件中
​ hibernate.hbm2ddl.auto:属性
​ 可以配置自动生成表的策略。
​ 3)主键生成策略
​ 1、自增长
​ 2、使用序列
​ 3、使用表
​ 4、自动选择

五、使用jpa实现crud

1、添加数据

​ 使用EntityManager对象的persist方法实现插入。
​ EntityManagerFactory对象应该是单例存在。

2、删除数据

​ 步骤:
​ 1)获得EntityManager对象
​ 2)开启事务
​ 3)先从数据库中查询一个Customer对象
​ 4)使用entityManger对象remove方法删除。参数就是Customer对象。
​ 5)提交事务
​ 6)关闭连接

对象的状态:
	瞬时态:直接new的对象就是瞬时态。
	持久态:把数据插入到数据库之后就是持久态。
	游离态:把数据库和对象直接的关系断开之后。

3、修改数据

​ 步骤:
​ 1)获得EntityManager对象
​ 2)开启事务
​ 3)根据id查询一个Customer对象
​ 4)修改对象的属性。
​ 5) 把修改结果保存到数据库
​ 6)提交事务
​ 7)关闭连接

4、查询

1)根据id查询

  1. find:根据id查询

    ​ 步骤:

    • 1、创建一个EntityManager对象

    • 2、使用find方法根据id查询

    • 3、打印结果

    • 4、关闭连接

      sql:SELECT * FROM `cst_customer`
      jpql:from Customer
      

    • //及时加载:find方法执行之后sql语句以及执行。getReference:根据id查询
      @Test
      public void findById() {
          //1、创建一个EntityManager对象
          EntityManager entityManager = factory.createEntityManager();
          //2、使用find方法根据id查询
          Customer customer = entityManager.find(Customer.class, 3L);
          System.out.println("============================");
          //3、打印结果
          System.out.println(customer);
          //4、关闭连接
          entityManager.close();
          factory.close();
      }
      --sql结果:
      Hibernate: 
          select
              customer0_.cust_id as cust_id1_0_0_,
              customer0_.cust_address as cust_add2_0_0_,
              customer0_.cust_industry as cust_ind3_0_0_,
              customer0_.cust_level as cust_lev4_0_0_,
              customer0_.cust_name as cust_nam5_0_0_,
              customer0_.cust_phone as cust_pho6_0_0_,
              customer0_.cust_source as cust_sou7_0_0_ 
          from
              cst_customer customer0_ 
          where
              customer0_.cust_id=?
      ============================
      Customer{custId=3, custName='sgw', custSource='电话营销', custIndustry='程序员', custLevel='码农', custAddress='AB市', custPhone='12345678901'}
      //延迟加载,懒加载:执行getReference方法之后sql并没有执行。当访问对象的属性时才执行查询。
      @Test
      public void findByID2() {
          EntityManager entityManager = factory.createEntityManager();
          Customer customer = entityManager.getReference(Customer.class, 3L);
          System.out.println("============================");
          System.out.println(customer);
          entityManager.close();
          factory.close();
      }
      --sql结果:
      ============================
      Hibernate: 
          select
              customer0_.cust_id as cust_id1_0_0_,
              customer0_.cust_address as cust_add2_0_0_,
              customer0_.cust_industry as cust_ind3_0_0_,
              customer0_.cust_level as cust_lev4_0_0_,
              customer0_.cust_name as cust_nam5_0_0_,
              customer0_.cust_phone as cust_pho6_0_0_,
              customer0_.cust_source as cust_sou7_0_0_ 
          from
              cst_customer customer0_ 
          where
              customer0_.cust_id=?
      Customer{custId=3, custName='sgw', custSource='电话营销', custIndustry='程序员', custLevel='码农', custAddress='AB市', custPhone='12345678901'}
      

2)使用JPQL查询

​ 相当于是sql语句的一个变种。

  1. 查询全部

    • @Test
      public void findAll() {
          //1)创建一个EntityManager对象
          EntityManager entityManager = factory.createEntityManager();
          //2)使用EntityManager创建一个Query对象,基于jpql创建。
          //参数就是jpql语句
          Query query = entityManager.createQuery("from Customer");
          //3)使用query对象执行查询。
          List<Customer> resultList = query.getResultList();
          //4)打印结果
          for (Customer customer : resultList) {
              System.out.println(customer);
          }
          entityManager.close();
          factory.close();
      }
      --sql结果:
      Hibernate: 
          select
              customer0_.cust_id as cust_id1_0_,
              customer0_.cust_address as cust_add2_0_,
              customer0_.cust_industry as cust_ind3_0_,
              customer0_.cust_level as cust_lev4_0_,
              customer0_.cust_name as cust_nam5_0_,
              customer0_.cust_phone as cust_pho6_0_,
              customer0_.cust_source as cust_sou7_0_ 
          from
              cst_customer customer0_
      
    • 使用方法:
      1)创建一个EntityManager对象
      2)使用EntityManager创建一个Query对象,基于jpql创建。
      3)使用query对象执行查询。
      4)打印结果
      5)关闭连接

    ​ from语句中使用表名应该换成实体类的类名。

  2. 查询全部带分页
    需要使用query对象的方法设置分页信息。
    起始的行号:setFistResult
    每页的行数:setMaxResult

    • @Test
      public void findAllWithPage() {
          //创建一个EntityManager对象
          EntityManager entityManager = factory.createEntityManager();
          //创建一个query对象,查询全部数据
          Query query = entityManager.createQuery("from Customer");
          //设置分页信息
          query.setFirstResult(5);//从第几条开始查询
          query.setMaxResults(5);//查询几条数据
          //执行查询
          List<Customer> customerList = query.getResultList();
          //打印结果
          for (Customer customer : customerList) {
              System.out.println(customer);
          }
          //关闭连接
          entityManager.close();
          factory.close();
      }
      --sql结果:
      Hibernate: 
          select
              customer0_.cust_id as cust_id1_0_,
              customer0_.cust_address as cust_add2_0_,
              customer0_.cust_industry as cust_ind3_0_,
              customer0_.cust_level as cust_lev4_0_,
              customer0_.cust_name as cust_nam5_0_,
              customer0_.cust_phone as cust_pho6_0_,
              customer0_.cust_source as cust_sou7_0_ 
          from
              cst_customer customer0_ limit ?,
              ?
      
  3. 带条件的查询

    • 根据id查询:

      • sql:select * from cst_customer where cust_id = ?
        jpql: from Customer where custId = ?
        
      • @Test
        public void findByWhere() {
            EntityManager entityManager = factory.createEntityManager();
            Query query = entityManager.createQuery("from Customer where custId=?");
            //设置查询条件
            //设置参数,索引应该是从1开始,就是第几个参数的位置
            query.setParameter(1, 3L);
            Customer customer = (Customer) query.getSingleResult();
            System.out.println(customer);
            entityManager.close();
            factory.close();
        }
        --sql结果:
        Hibernate: 
            select
                customer0_.cust_id as cust_id1_0_,
                customer0_.cust_address as cust_add2_0_,
                customer0_.cust_industry as cust_ind3_0_,
                customer0_.cust_level as cust_lev4_0_,
                customer0_.cust_name as cust_nam5_0_,
                customer0_.cust_phone as cust_pho6_0_,
                customer0_.cust_source as cust_sou7_0_ 
            from
                cst_customer customer0_ 
            where
                customer0_.cust_id=?
        
    • 根据客户名称模糊查询:

      • sql:select * from cst_customer where cust_name like '%java%'
        jpql: from Customer where custName like ?
        
      • @Test
        public void findByName() {
            EntityManager entityManager = factory.createEntityManager();
            Query query = entityManager.createQuery("from Customer where custName like ? and custAddress like ?");
            query.setParameter(1,"%会%");
            query.setParameter(2,"%界%");
            //执行查询
            List<Customer> customerList = query.getResultList();
            for (Customer customer : customerList) {
                System.out.println(customer);
            }
            entityManager.close();
            factory.close();
        }
        --sql结果:
        Hibernate: 
            select
                customer0_.cust_id as cust_id1_0_,
                customer0_.cust_address as cust_add2_0_,
                customer0_.cust_industry as cust_ind3_0_,
                customer0_.cust_level as cust_lev4_0_,
                customer0_.cust_name as cust_nam5_0_,
                customer0_.cust_phone as cust_pho6_0_,
                customer0_.cust_source as cust_sou7_0_ 
            from
                cst_customer customer0_ 
            where
                (
                    customer0_.cust_name like ?
                ) 
                and (
                    customer0_.cust_address like ?
                )
        

    jpql相当于sql语句,只是把表名替换成实体类的类名,字段名换成实体类的属性名。

  4. 查询带排序

    • sql:SELECT * from cst_customer ORDER BY cust_id desc
      jpql:from Customer order by custId desc
      
    • @Test
      public void findAllWithOrder() {
          EntityManager entityManager = factory.createEntityManager();
          Query query = entityManager.createQuery("from Customer order by custId desc");
          List<Customer> resultList = query.getResultList();
          for (Customer customer : resultList) {
              System.out.println(customer);
          }
          entityManager.close();
          factory.close();
      }
      --sql结果:
      Hibernate: 
          select
              customer0_.cust_id as cust_id1_0_,
              customer0_.cust_address as cust_add2_0_,
              customer0_.cust_industry as cust_ind3_0_,
              customer0_.cust_level as cust_lev4_0_,
              customer0_.cust_name as cust_nam5_0_,
              customer0_.cust_phone as cust_pho6_0_,
              customer0_.cust_source as cust_sou7_0_ 
          from
              cst_customer customer0_ 
          order by
              customer0_.cust_id desc
      
  5. 聚合查询

    • sql:SELECT COUNT(*) from cst_customer
      jpql:select count(*) from Customer
      
    • @Test
      public void testCount() {
          EntityManager entityManager = factory.createEntityManager();
          Query queryCount = entityManager.createQuery("select count(*) from Customer");
          Long count = (Long) queryCount.getSingleResult();
          System.out.println("总记录数:"+count);
          Query query = entityManager.createQuery("select sum(custId) from Customer");
          Long sum = (Long) query.getSingleResult();
          System.out.println("id数字的总和"+sum);
      }
      --sql结果:
      Hibernate: 
          select
              count(*) as col_0_0_ 
          from
              cst_customer customer0_
      总记录数:6
      Hibernate: 
          select
              sum(customer0_.cust_id) as col_0_0_ 
          from
              cst_customer customer0_
      id数字的总和26
      

六、总结

1、入门程序

​ 步骤:
​ 1、创建配置文件
​ 2、实体类
​ 3、测试代码

2、配置文件

​ classpath:/META-INF/persistence.xml
​ 配置数据的连接信息
​ 配置框架参数:
​ hibernate.hbm2ddl.auto
​ create:先删除后创建
​ update:没有创建,有直接使用
​ none:不创建。

3、实体类

​ @Entity:必须有
​ @Table:必须有
​ @Column:不必须,如果属性和字段名不一致需要配置。
​ @Id:必须有,标记主键字段。
​ @GeneratedValue:需要框架自动生成主键时需要配置。
​ 自增长
​ 序列
​ 表
​ 自动选择

4、测试方法

​ EntityManangerFactory:工厂类对象。创建EntityManager对象。
​ EntityManager:
​ 添加:persist
​ 删除:remove
​ 修改:merge
​ 查询:find:即时加载
​ getReference:懒加载

5、jpql

​ 把sql语句中的表名替换成实体类名
​ 字段名替换成实体类属性名。

JPA第一章JPA第一章 sgwks 发布了64 篇原创文章 · 获赞 2 · 访问量 3364 私信 关注
上一篇:mysql的模型依赖说明


下一篇:MSQL存储引擎(一)