1 ORM思想
1.1 主要目的
操作实体类就相当于操作数据库表。
简单的说:ORM就是建立实体类和数据库表之间的关系,从而达到操作实体类就相当于操作数据库表的目的。
![](https://static.kevinchu.top/blog/public/jpa-01.png)
1.2 实现方法
建立两个映射关系:
- 实体类和表的映射关系;
- 实体类中属性和表中字段的映射关系。
1.3 优点
不再重点关注sql语句。
1.4 实现ORM的框架
如mybatis,hibernate,等等。
2 Hibernate框架
Hibernate是一个开源的对象关系映射框架:
- 它对JDBC进行了非常轻量级的对象封装;
- 它将POJO与数据库表建立映射关系,是一个全自动的orm框架。
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
3 JPA规范
3.1 定义
jpa规范,实现jpa规范,内部是由接口和抽象类组成。
JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。
JPA通过JDK 5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
![](https://static.kevinchu.top/blog/public/jpa-02.png)
3.2 优势
- 标准化
JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
- 容器级特性的支持
JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。
- 简单方便
JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java 类一样简单,没有任何的约束和限制,只需要使用 javax.persistence.Entity进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成
- 查询能力
JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
- 高级特性
JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
4 JPA的基本操作
4.1 案例
客户的操作(增删改查)。
![](https://static.kevinchu.top/blog/public/jpa-03.png)
persistence.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.user" value="root"> <property name="javax.persistence.jdbc.password" value="111111"> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"> <property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa">
<property name="hibernate.show_sql" value="true"> <property name="hibernate.hbm2ddl.auto" value="update"> </property></property></property></property></property></property></properties> </persistence-unit> </persistence>
|
pom依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${project.hibernate.version}</version> </dependency>
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>${project.hibernate.version}</version> </dependency>
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> </dependencies>
|
客户数据库表:
1 2 3 4 5 6 7 8 9 10
| 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;
|
Customer.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| package cn.itcast.domain;
import javax.persistence.*;
@Entity @Table(name = "cst_customer") public class Customer {
@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 + '\'' + '}'; } }
|
JpaTest.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
| package cn.itcast.test;
import cn.itcast.domain.Customer; import cn.itcast.utils.JpaUtils; import org.junit.Test;
import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence;
public class JpaTest {
@Test public void testSave() {
EntityManager em = JpaUtils.getEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Customer customer = new Customer(); customer.setCustName("传智播客"); customer.setCustIndustry("教育"); em.persist(customer); tx.commit(); em.close();
}
@Test public void testFind() { EntityManager entityManager = JpaUtils.getEntityManager(); EntityTransaction tx = entityManager.getTransaction(); tx.begin();
Customer customer = entityManager.find(Customer.class, 1l); tx.commit(); entityManager.close(); }
@Test public void testReference() { EntityManager entityManager = JpaUtils.getEntityManager(); EntityTransaction tx = entityManager.getTransaction(); tx.begin();
Customer customer = entityManager.getReference(Customer.class, 1l); System.out.print(customer); tx.commit(); entityManager.close(); }
@Test public void testRemove() { EntityManager entityManager = JpaUtils.getEntityManager(); EntityTransaction tx = entityManager.getTransaction(); tx.begin();
Customer customer = entityManager.find(Customer.class,1l); entityManager.remove(customer);
tx.commit(); entityManager.close(); }
@Test public void testUpdate() { EntityManager entityManager = JpaUtils.getEntityManager(); EntityTransaction tx = entityManager.getTransaction(); tx.begin();
Customer customer = entityManager.find(Customer.class,1l); customer.setCustIndustry("it教育"); entityManager.merge(customer);
tx.commit(); entityManager.close(); }
}
|
JpaUtil.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package cn.itcast.utils;
import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence;
public class JpaUtils {
private static EntityManagerFactory factory;
static { factory = Persistence.createEntityManagerFactory("myJpa"); }
public static EntityManager getEntityManager() { return factory.createEntityManager(); } }
|
JpaTest.java(plus):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
| package cn.itcast.test;
import cn.itcast.domain.Customer; import cn.itcast.utils.JpaUtils; import org.junit.Test;
import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import javax.persistence.Query; import java.util.List;
public class JpqlTest {
@Test public void testFindAll() { EntityManager em = JpaUtils.getEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); String jpql = "from Customer "; Query query = em.createQuery(jpql);
List list = query.getResultList();
for (Object obj : list) { System.out.print(obj); }
tx.commit(); em.close(); }
@Test public void testOrders() { EntityManager em = JpaUtils.getEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); String jpql = "from Customer order by custId desc"; Query query = em.createQuery(jpql);
List list = query.getResultList();
for (Object obj : list) { System.out.println(obj); }
tx.commit(); em.close(); }
@Test public void testCount() { EntityManager em = JpaUtils.getEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); String jpql = "select count(custId) from Customer"; Query query = em.createQuery(jpql);
Object result = query.getSingleResult();
System.out.println(result);
tx.commit(); em.close(); }
@Test public void testPaged() { EntityManager em = JpaUtils.getEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); String jpql = "from Customer"; Query query = em.createQuery(jpql); query.setFirstResult(0); query.setMaxResults(2);
List list = query.getResultList();
for(Object obj : list) { System.out.println(obj); }
tx.commit(); em.close(); }
@Test public void testCondition() { EntityManager em = JpaUtils.getEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); String jpql = "from Customer where custName like ? "; Query query = em.createQuery(jpql); query.setParameter(1,"传智播客%");
List list = query.getResultList();
for(Object obj : list) { System.out.println(obj); }
tx.commit(); em.close(); }
}
|
相关笔记:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| jpa操作的操作步骤 1.加载配置文件创建实体管理器工厂 Persisitence:静态方法(根据持久化单元名称创建实体管理器工厂) createEntityMnagerFactory(持久化单元名称) 作用:创建实体管理器工厂 2.根据实体管理器工厂,创建实体管理器 EntityManagerFactory :获取EntityManager对象 方法:createEntityManager
内部维护了数据库信息, 维护了缓存信息 维护了所有的实体管理器对象 再创建EntityManagerFactory的过程中会根据配置创建数据库表
特点:线程安全的对象 多个线程访问同一个EntityManagerFactory不会有线程安全问题
思路:创建一个公共的EntityManagerFactory的对象
3.创建事务对象,开启事务 EntityManager对象:实体类管理器 getTransaction : 创建事务对象 presist : 保存 merge : 更新 remove : 删除 find/getReference : 根据id查询 Transaction 对象 : 事务 begin:开启事务 commit:提交事务 rollback:回滚 4.增删改查操作 5.提交事务 6.释放资源 i.搭建环境的过程 1.创建maven工程导入坐标 2.需要配置jpa的核心配置文件
3.编写客户的实体类 4.配置实体类和表,类中属性和表中字段的映射关系 5.保存客户到数据库中 ii.完成基本CRUD案例 persist : 保存 merge : 更新 remove : 删除 find/getRefrence : 根据id查询 iii.jpql查询 sql:查询的是表和表中的字段 jpql:查询的是实体类和类中的属性
1.查询全部 2.分页查询 3.统计查询 4.条件查询 5.排序
|