ORM与JPA基本用法

1. ORM简介

1.1 什么是ORM

ORMObject-Relational Mapping表示对象关系映射。面向对象的软件开发中通过ORM可以把对象映射到关系型数据库中。只要有一套程序能够做到建立对象与数据库的关联,操作对象就可以直接操作数据库数据,就可以说这套程序实现了ORM对象关系映射。

1.2 使用ORM的好处

实现一个应用程序时,我们会写特别多数据访问层的代码,而这些代码大部分都是重复的。ORM则会大大减少重复性代码。ORM主要实现程序对象到关系数据库的映射。

1.3 常见ORM框架

  1. Mybatis
  2. Hibernate
  3. jpa

2. Hibernate和JPA

2.1 什么是Hibernate

Hibernate时一个对象关系映射框架,对jdbc进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架,hibernate可以自动生成sql语句,自动执行。

2.2 什么是JPA

JPA全程java persistence API,就是java持久层api,是一套基于ORM的规范,内部由一系列的接口和抽象类组成。

2.3 JPA和Hibernate的关系

JPA规范本质上是一种ORM规范,却不是一个ORM框架,因为它并没有提供实现,只定制了一些规范,具体实现由服务厂商来实现。

应用程序
JPA
Hibernate
数据库

3. JPA入门

3.1 demo

  1. 导入依赖
  2. 准备数据库表和实体类
  3. 编写映射配置
  4. 配置JPA核心文件
  5. 使用
<!-- hibernate对jpa的支持包 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>${project.hibernate.version}</version>
</dependency>
create table customer (
	cust_id int primary key,
    cust_name varchar(32) not null,
    cust_source varchar(32) not null
);
// 要java.persistence包下的
@Entity // 标注这是一个实体类
@Table(name="customer") // 建立实体类和表的关系
public class Customer implements Serializable {
    
    
    @Id // 表示custId是主键
    @GeneratedValue(strategy=GenerationType.IDENTITY) // 主键生成策略
    @Column(name="cust_id") // 指定该属性和cust_id字段对应
    private int custId;
    @Column(name="cust_name")
    private String custName;
    @Column(name="cust_source")
    private String custSource;
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!-- 持久的persistence  JPA java持久层API -->
    <!--
        必须配置的结点  persistence-unit
        持久化单元
        @param name 持久化单元名称 -> 可以随便写
        @param transaction-type 事务管理类型:
            value:
                JTA:分布式事务管理 -> 不同的表在不同的数据库时才用 (Java Transaction API)
                RESOURCE_LOCAL:本地事务管理
    -->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!-- 1.jpa的实现方式->是规范,必须要有实现 -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <!-- 2.连接数据库的信息:
                   驱动:           javax.persistence.jdbc.driver
                   用户名:         javax.persistence.jdbc.user
                   密码:           javax.persistence.jdbc.password
                   数据库地址:      javax.persistence.jdbc.url
             -->
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa?characterEncoding=utf-8"/>
            <!-- 3.可选:配置JPA实现方的配置信息(例如hibernate)
                显示sql:便于DEBUG
                自动创建数据库表: hibernate.hbm2ddl.auto:
                    create: 程序运行时创建数据库表,如果有表先删除表再创建
                    update: 程序运行时创建数据库表,如果有表不会创建表
                    none
             -->
            <property name="hibernate.show_sql" value="true"/>
            <!-- none相当于没写,执行之前需要有表,否则报错 -->
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

@Test
public void test() {
    
    
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
    EntityManager em = factory.createEntityManager();
	// 开启事务
    EntityTransaction tx = en.getTransaction();
    tx.begin();
    
    Customer cust = new Customer();
    cust.setCustName("jerry");
    em.persist(cust);
    
    tx.commit();
    em.close();
    factory.close();
}

3.2 常用注解

  1. @Entity:标注该类是一个实体类
  2. @Table:指定实体类和表之间的对应关系
  3. @Id:指定某个属性是主键
  4. @GeneratedValue:指定主键的生成策略
  5. @Column:指定数据库表的列名

3.3 主键自增策略

JPA提供四种标准用法:

  1. TABLE:使用一个特殊的表来保存主键
  2. SEQUENCE:根据底层数据库的序列来生成主键
  3. IDENTITY:主键自动生成,一般是自增长
  4. AUTO:程序自动控制

3.4 基本操作CRUD

  1. 保存:

    public void testAdd() {
          
          
    	Customer cust = new Customer();
        cust.setCustName("jerry");
        cust.setCustSource("china");
      	
        try {
          
          
            EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
            EntityManager em = factory.createEntityManager();
            // 开启事务
            EntityTransaction tx = en.getTransaction();
            tx.begin();
            em.persist(cust);
        	tx.commit();
        } catch(Exception e) {
          
          
            tx.rollback();
        } finally {
          
          
            em.close();
            factory.close();
        }
       
       
      
        
    }
    
  2. 修改:em等对象直接用了没有写出来

    public void testUpdate() {
          
          
        tx.begin();
        // 根据ID查询
        Customer cus = entityManager.getReference(Customer.class, 1);
        // 更新
        cus.setCustSource("jj");
        entityManager.merge(cus);
        tx.commit();
    }
    
  3. 删除:

    public void testDelete() {
          
          
        tx.begin();
        Customer c = em.find(Customer.class, 6);
        em.remove(c);
        tx.commit();
    }
    
  4. 查询:

    // 1. 根据Id查询
    public void testFind() {
          
          
        tx.begin();
        // 默认存在缓存
        Customer cust1 = em.find(Customer.class, 1); // 立即加载
        Customer cust2 = em.getReference(Customer.class, 1); // 延迟加载
        tx.commit();
    }
    

4. JPQL

4.1 什么是jpql

全称java persistence query language

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

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

4.2 查询全部

public void findAll() {
    
    
    // 查询全部
    // String jpql = "from com.jerry66.pojo.Customer";
    String jpql = "from Customer"; // 支持简写
    Query query = manager.createQuery(jpql); // query时执行jpql的对象
    // 查询
    List resultList = query.getResultList();
    for (Object o : resultList) {
    
    
        System.out.println(o);
    }
}

4.3 分页查询

public void pageL() {
    
    
    // 1. 查询全部
    String jpql = "from Customer";
    Query query = manager.createQuery(jpql);
    // 2. 赋值分页参数
    // 起始索引 每页查询条数
    query.setFirstResult(0); // 从0查,会优化为limit ?
    query.setMaxResults(2);
    // 3. 封装结果
    List resultList = query.getResultList();
    for (Object o : resultList) {
    
    
        System.out.println(o);
    }
}

4.4 条件查询

public void condition() {
    
    
    // 1. 查询全部
    String jpql = "from Customer where custName like ? ";
    Query query = manager.createQuery(jpql);
    // 2. 赋值分页参数
    query.setParameter(1, "%jerry%");
    // 3. 封装结果
    List resultList = query.getResultList();
    for (Object o : resultList) {
    
    
        System.out.println(o);
    }
}

4.5 排序查询

public void findSort() {
    
    
    // custId | cust_id都可以,写custId比较好
    String jpql = "from Customer order by custId desc";
    Query query = manager.createQuery(jpql);
    List resultList = query.getResultList();
    for (Object o : resultList) {
    
    
        System.out.println(o);
    }
}

4.6 统计查询

public void testCount() {
    
    
    // 1. 根据jpql语句创建query查询对象
    String jpql = "select count(custId) from Customer";
    Query query = manager.createQuery(jpql);
    // 2. 赋值:无
    // 3. 封装结果
    Long singleResult = (Long) query.getSingleResult();
    System.out.println(singleResult);
}

猜你喜欢

转载自blog.csdn.net/weixin_43795939/article/details/112546126
今日推荐