文章目录
1. ORM简介
1.1 什么是ORM
ORM
是Object-Relational Mapping
表示对象关系映射。面向对象的软件开发中通过ORM
可以把对象映射到关系型数据库中。只要有一套程序能够做到建立对象与数据库的关联,操作对象就可以直接操作数据库数据,就可以说这套程序实现了ORM
对象关系映射。
1.2 使用ORM的好处
实现一个应用程序时,我们会写特别多数据访问层的代码,而这些代码大部分都是重复的。ORM
则会大大减少重复性代码。ORM
主要实现程序对象到关系数据库的映射。
1.3 常见ORM框架
Mybatis
Hibernate
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
框架,因为它并没有提供实现,只定制了一些规范,具体实现由服务厂商来实现。
3. JPA入门
3.1 demo
- 导入依赖
- 准备数据库表和实体类
- 编写映射配置
- 配置JPA核心文件
- 使用
<!-- 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 常用注解
@Entity
:标注该类是一个实体类@Table
:指定实体类和表之间的对应关系@Id
:指定某个属性是主键@GeneratedValue
:指定主键的生成策略@Column
:指定数据库表的列名
3.3 主键自增策略
JPA
提供四种标准用法:
TABLE
:使用一个特殊的表来保存主键SEQUENCE
:根据底层数据库的序列来生成主键IDENTITY
:主键自动生成,一般是自增长AUTO
:程序自动控制
3.4 基本操作CRUD
-
保存:
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(); } }
-
修改:em等对象直接用了没有写出来
public void testUpdate() { tx.begin(); // 根据ID查询 Customer cus = entityManager.getReference(Customer.class, 1); // 更新 cus.setCustSource("jj"); entityManager.merge(cus); tx.commit(); }
-
删除:
public void testDelete() { tx.begin(); Customer c = em.find(Customer.class, 6); em.remove(c); tx.commit(); }
-
查询:
// 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);
}