springdata_day01

目标

  • 理解ORM思想和该数
  • 理解JPA和hibernate的关系
  • 掌握maven单构件jpa项目并进行增删改查操作
  • 掌握JPQL语句进行条件查询

1. ORM思想

1. 概述

ORM(Object-Relational Mapping) 表示对象关系映射。通过ORM,就可以把对象映射到关系型数据库中。

简单的说:ORM就是建立实体类和数据库表之间的关系,从而达到操作实体类就相当于操作数据库表的目的。

2. 目的

主要目的:操作实体类相当于操作数据库表

需要建立两个映射关系:

实体类和表的映射关系

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

3. 实现ORM思想的框架

mybatis和hibernate

2. hibernate与JPA的概述

1. hibernate介绍

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架。

2. JPA

1. 介绍

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

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

2. 优势
  • 标准化
  • 容器级特性的支持
  • 简单方便
  • 查询能力
  • 高级特性

3. JPA和hibernate的关系

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

在这里插入图片描述

3. JPA的入门案例

1. 需求介绍

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

2. 开发包介绍

只需要导入JPA提供商的jar包

3. 搭建开发环境

1. maven工程导入坐标
<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <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>
</dependencies>
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 AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

创建客户的实体类

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

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

@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;
  // getter/setter以及toString

常用注解的说明:

@Entity
作用:指定当前类是实体类。
@Table
作用:指定实体类和表之间的对应关系。
属性:
name:指定数据库表的名称
@Id
作用:指定当前字段是主键。
@GeneratedValue
作用:指定主键的生成方式。。
属性:
strategy :指定主键生成策略。
	GenerationType.IDENTITY 自增,mysql
		底层数据库必须支持自动增长
	GenerationType.SEQUENCE 序列,Oracle
		底层数据库必须支持序列
	GenerationType.TABLE jpa提供的一种机制,通过一张数据库表的形式帮我们完成主键自增
	GenerationType.AUTO 由程序自动帮助我们选择主键生成策略
@Column
作用:指定实体类属性和数据库表之间的对应关系
属性:
name:指定数据库表的列名称。
unique:是否唯一  
nullable:是否可以为空  
inserttable:是否可以插入  
updateable:是否可以更新  
columnDefinition: 定义建表时创建此列的DDL  
secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境[重点]
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:事务管理的方式
                RESOURCE_LOCAL:本地事务管理
                JTA:分布式事务管理
    -->
  <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
    <!--jpa的实现方式-->
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <properties>
      <!--数据库信息-->
      <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:///jpa"/>

      <!--可选配置:配置jpa实现方(hibernate)的配置信息
                显示SQL :false,true
                自动创建数据库表:
                    create:程序运行时创建数据库表(如果有表,先删除表再创建)
                    update:程序运行时创建表(如果有表,不会创建表)
                    none:不会创建表
            -->
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.hbm2ddl.auto" value="create"/>
    </properties>

  </persistence-unit>
</persistence>

4. 实现保存操作

test下创建JpaTest.java文件

jpa的操作步骤

  1. 加载配置文件创建工厂(实体管理类工厂)对象
  2. 通过实体管理类工厂获取实体管理器
  3. 获取事务对象,开启事务
  4. 完成增删改查操作
  5. 提交事务(回滚事务)
  6. 释放资源
public class JpaTest {

  @Test
  public void testSave(){
    // 1.加载配置文件创建工厂(实体管理器工厂)对象
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
    // 2.通过实体管理器工厂获取实体管理器
    EntityManager em = factory.createEntityManager();
    // 3.获取事务对象,开启事务
    EntityTransaction tx = em.getTransaction();
    tx.begin();//开启事务
    // 4.完成正删改查操作,保存一个客户到数据库
    Customer customer = new Customer();
    customer.setCustName("tom");
    customer.setCustIndustry("电商");
    // 保存
    em.persist(customer);
    // 5. 提交事务
    tx.commit();
    // 6.释放资源
    em.clear();
    factory.close();
  }

5. API介绍

1. Persistence对象

作用:创建实体管理器工厂EntityManagerFactory

调用createEntityMnagerFactory静态方法,根据持久化单元名称创建实体管理器工厂

2. EntityManagerFactory

接口,主要用来创建EntityManager对象,方法:createEntityManager

内部维护的很多的内容:数据库信息,缓存信息,所有的实体管理器对象

在创建EntityManagerFactory的过程中会根据配置创建数据库表

特点:是个线程安全的对象,创建过程比较耗费资源。

  • 如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题?

思路:创建一个公共的EntityManagerFactory的对象, 用静态代码块的形式创建EntityManagerFactory

3. EntityManager对象

实体类管理器

  • beginTransaction : 创建事务对象
  • presist : 保存
  • merge : 更新
  • remove : 删除
  • find/getRefrence : 根据id查询
4. Transaction 对象
  • begin:开启事务
  • commit:提交事务
  • rollback:回滚
5. 查询

使用find方法查询:(立即加载)

  1. 查询的对象就是当前客户对象本身;
  2. 在调用find方法时,会发送SQL语句查询数据库

使用getReference方法查询:(延迟加载,懒加载)

  1. 获取的对象是一个动态代理对象

  2. 调用getReference方法不会立即发送SQL语句查询数据库

    当调用查询结果对象的时候,才会发送查询的SQL语句,什么时候用,什么时候发送

6. 示范代码

public class JpaTest {

  private EntityManager em;
  private EntityTransaction tx;
  private EntityManagerFactory factory;

  @Before
  public void init(){
    // 1.加载配置文件创建工厂(实体管理器工厂)对象
    factory = Persistence.createEntityManagerFactory("myJpa");
    // 2.通过实体管理器工厂获取实体管理器
    em = factory.createEntityManager();
    // 3.获取事务对象,开启事务
    tx = em.getTransaction();
    tx.begin();//开启事务
  }

  @After
  public void close(){
    // 5. 提交事务
    tx.commit();
    // 6.释放资源
    em.clear();
    factory.close();
  }

  @Test
  public void testSave(){

    // 4.完成正删改查操作,保存一个客户到数据库
    Customer customer = new Customer();
    customer.setCustName("pony");
    customer.setCustIndustry("电商");
    // 保存
    em.persist(customer);
  }

  // 根据id查询客户
  //
  @Test
  public void testFind(){
    Customer customer = em.find(Customer.class, 1L);
    System.out.println(customer);
  }

  // 根据id查询客户
  @Test
  public void testReference(){
    Customer customer = em.getReference(Customer.class, 1L);
    System.out.println(customer);
  }

  // 删除客户
  @Test
  public void testRemove(){
    // 查询客户
    Customer customer = em.getReference(Customer.class, 1L);
    // 删除客户
    em.remove(customer);
  }

  // 更新客户的操作
  @Test
  public void testUpdate(){
    // 查询客户
    Customer customer = em.getReference(Customer.class, 2L);
    customer.setCustIndustry("p2p");
    // 更新客户
    em.merge(customer);
  }
}

7. JPA的复杂查询

1. JPQL

全称Java Persistence Query Language

基于首次在EJB2.0中引入的EJB查询语言(EJB QL),Java持久化查询语言(JPQL)是一种可移植的查询语言,旨在以面向对象表达式语言的表达式,将SQL语法和简单查询语义绑定在一起·使用这种语言编写的查询是可移植的,可以被编译成所有主流数据库服务器上的SQL。

特征与原生SQL语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性

2. 查询步骤
  1. 创建query查询对象
  2. 对参数进行赋值
  3. 查询,并得到返回结果
3. 查询类型
  • 查询全部
  • 排序查询
  • 统计客户的总数
  • 分页查询
  • 条件查询
4. 代码
public class JpqlTest {
  private EntityManager em;
  private EntityTransaction tx;
  private EntityManagerFactory factory;

  @Before
  public void init(){
    // 1.加载配置文件创建工厂(实体管理器工厂)对象
    factory = Persistence.createEntityManagerFactory("myJpa");
    // 2.通过实体管理器工厂获取实体管理器
    em = factory.createEntityManager();
    // 3.获取事务对象,开启事务
    tx = em.getTransaction();
    tx.begin();//开启事务
  }

  @After
  public void close(){
    // 5. 提交事务
    tx.commit();
    // 6.释放资源
    em.clear();
    factory.close();
  }

  // 查询全部
  @Test
  public void testFindAll(){
    String jpql = "from cn.itcast.domain.Customer";
    Query query = em.createQuery(jpql);
    // 发送查询,封装结果集
    List list = query.getResultList();
    for (Object o : list) {
      System.out.println(o);
    }
  }

  // 排序查询
  @Test
  public void testOrders(){
    String jpql = "from Customer order by custId desc";
    Query query = em.createQuery(jpql);
    // 发送查询,封装结果集
    List list = query.getResultList();
    for (Object o : list) {
      System.out.println(o);
    }
  }

  // 统计客户的总数
  @Test
  public void testCount(){
    String jpql = "select count(custId) from Customer";
    Query query = em.createQuery(jpql);
    // 发送查询,封装结果集
    Object result = query.getSingleResult();
    System.out.println(result);
  }

  // 分页查询
  @Test
  public void testPage(){
    String jpql = "from Customer";
    Query query = em.createQuery(jpql);
    query.setFirstResult(0);
    query.setMaxResults(5);
    // 发送查询,封装结果集
    List list = query.getResultList();
    for (Object o : list) {
      System.out.println(o);
    }
  }

  // 条件查询 查询以电商开头的
  @Test
  public void testCondition(){
    String jpql = "from Customer where custIndustry like ?";
    Query query = em.createQuery(jpql);
    // 对参数赋值--占位符参数
    // 第一个参数:占位符位置,第二个参数:取值
    query.setParameter(1,"电商%");
    // 发送查询,封装结果集
    List list = query.getResultList();
    for (Object o : list) {
      System.out.println(o);
    }
  }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值