ORM是软件开发的一种思想,主要针对持久层
ORM描述的对象关系映射
O --> Object --> 对象
R --> Relational --> 关系表
M --> Mapping --> 映射
1、让开发人员不用关注SQL语句
2、操作类就是操作表
3、隐藏不同数据库的差异
Hibernate一种开源、流行的ORM框架。底层封装JDBC,是ORM思想的一种实现
JPA是由SUN公司提出的这对ORM框架的规范。 内部是接口。
众多ORM实现厂商针对JPA里的接口进行实现。
开发人员面向JPA接口进行开发,只需要了解一套API。统一了ORM框架的语法。
1)、Hibernate和JPA是实现和接口的关系。JPA是接口,Hibernate是实现
2)、Hibernate的作用:简化JDBC操作、让开发人员不关注SQL语句
3)、JPA的作用:统一ORM语法,实现ORM框架无缝切换。多态思想
开发人员面向JPA编程,ORM实现厂商实现JPA接口。
面向JPA的开发就是面向接口开发。
/*创建客户表*/
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;
注意:JPA是规范,无法操作数据库,需要引入Hibernate对JPA的实现包
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-entitymanagerartifactId>
<version>5.0.7version>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-c3p0artifactId>
<version>5.0.7version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.6version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.9version>
<scope>testscope>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
一个类如果与数据中的某个表有映射关系,这个类就是持久化类
/**
* * 所有的注解都是使用 JPA 的规范提供的注解,
* * 所以在导入注解包的时候,一定要导入 javax.persistence 下的
*/
@Entity //声明实体类
@Table(name="cst_customer") //建立实体类和表的映射关系
public class Customer {
//声明当前私有属性为主键
@Id
//配置主键的生成策略,IDENTITY是数据库的自增
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="cust_id") //指定和表中 cust_id 字段的映射关系
private Long custId;
@Column(name="cust_name") //指定和表中 cust_name 字段的映射关系
private String custName;
@Column(name="cust_source")//指定和表中 cust_source 字段的映射关系
private String custSource;
@Column(name="cust_industry")//指定和表中 cust_industry 字段的映射关系
private String custIndustry;
@Column(name="cust_level")//指定和表中 cust_level 字段的映射关系
private String custLevel;
@Column(name="cust_address")//指定和表中 cust_address 字段的映射关系
private String custAddress;
@Column(name="cust_phone")//指定和表中 cust_phone 字段的映射关系
private String custPhone;
//get() set()方法略。。。
}
常见注解说明:
@Entity :指定当前类是实体类。
@Table :指定实体类和表之间的对应关系。
属性:
name:指定数据库表的名称
@Id :指定当前字段是主键。
@GeneratedValue :指定主键的生成方式。。
属性:
strategy :指定主键生成策略。
generator:指定引用 hibernate 中声明的主键策略
@Column :指定实体类属性和数据库表之间的对应关系
属性:
name:指定数据库表的列名称。
unique:是否唯一
nullable:是否可以为空
inserttable:是否可以插入
updateable:是否可以更新
columnDefinition: 定义建表时创建此列的 DDL
secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名
注意:在 maven 工程的 resources 路径下创建一个名为 META-INF 的文件夹,在此文件夹下创建一个名为
persistence.xml 的配置文件。META-INF 文件夹名称不能修改。 persistence.xml 文件名称不能改
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProviderprovider>
<class>com.itheima.po.Customerclass>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/day01" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="123456" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
properties>
persistence-unit>
persistence>
@Test
public void testSave() {
/**
* 创建实体管理类工厂,使用 Persistence 的静态方法获取
* 其中传递的参数为持久化单元名称,需要 jpa 配置文件中指定
*/
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
//创建实体管理类
EntityManager em = factory.createEntityManager();
//获取事务对象
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
//创建要操作的对象
Customer customer = new Customer();
c.setCustName("传智播客");
//保存操作
em.persist(customer);
//提交事务
tx.commit();
//释放资源
em.close();
}
Persistence //工具类,用来创建EntityManagerFactory
EntityManagerFactory //工厂类,用来创建EntityManager
EntityManager //核心类,封装操作数据库的方法
EntityTransaction //事务对象
public final class JPAUtil {
// JPA 的实体管理器工厂:相当于 Hibernate 的 SessionFactory
private static EntityManagerFactory em;
// 使用静态代码块赋值
static {
// 注意:该方法参数必须和 persistence.xml 中 persistence-unit 标签 name 属性取值一致
em = Persistence.createEntityManagerFactory("myPersistUnit");
}
/**
* 使用管理器工厂生产一个管理器对象
* @return
*/
public static EntityManager getEntityManager() {
return em.createEntityManager();
}
}
@Test
public void testFindOne() {
// 定义对象
EntityManager em = JPAUtil.getEntityManager();
EntityTransaction tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
Customer customer = em.find(Customer.class, 1L);
// 提交事务
tx.commit();
System.out.println(customer.getCustName()); // 输出查询对象
// 释放资源
em.close();
}
@Test
public void testMerge(){
//定义对象
EntityManager em=JPAUtil.getEntityManager();
EntityTransaction tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer customer = em.find(Customer.class, 1L);
customer.setCustName("传智播客-黑马程序员");
em.merge(customer);
//提交事务
tx.commit();
//释放资源
em.close();
}
//注意:修改操作要先查询,然后用查询出来的对象进行修改操作
@Test
public void testRemove(){
//定义对象
EntityManager em=JPAUtil.getEntityManager();
EntityTransaction tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer customer = em.find(Customer.class, 1L);
em.remove(customer);
//提交事务
tx.commit();
//释放资源
em.close();
}
public void testGetOne() {
EntityManager em = JPAUtil.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
//find 立即加载,立即发送SQL进行查询,返回的是真实对象
Customer customer1 = em.find(Customer.class, 2L);
System.out.println(customer1);
//getReference 延迟加载,不会立即发送SQL查询,返回的是代理对象
//在Debug模式下可以看到 对象是带着$符号,就是代理对象
Customer customer2 = em.getReference(Customer.class, 2L);
System.out.println(customer2);
tx.commit();
em.close();
}
JPQL 全称 Java Persistence Query Language,与原生 SQL 语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的列名
public void testFindAll() {
EntityManager em = JPAUtil.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
// 创建 query 对象
String jpql = "from Customer";
Query query = em.createQuery(jpql);
// 查询并得到返回结果
List<Customer> list = query.getResultList(); // 得到集合返回类型
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
em.close();
}
public void testFindAll() {
EntityManager em = JPAUtil.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
// 创建 query 对象
String jpql = "from Customer where custName like ? and custId=?";
Query query = em.createQuery(jpql);
//对占位符赋值, 从 1 开始
query.setParameter(1, "传智播客%");
query.setParameter(2,2L);
// 查询并得到返回结果
List<Customer> list = query.getResultList(); // 得到集合返回类型
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
em.close();
}
public void testFindAll() {
EntityManager em = JPAUtil.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
// 创建 query 对象
String jpql = "from Customer order by custId desc";
Query query = em.createQuery(jpql);
// 查询并得到返回结果
List<Customer> list = query.getResultList(); // 得到集合返回类型
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
em.close();
}
public void testFindAll() {
EntityManager em = JPAUtil.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
// 创建 query 对象
String jpql = "from Customer";
Query query = em.createQuery(jpql);
//起始索引
query.setFirstResult(0);
//每页显示条数
query.setMaxResults(2)
// 查询并得到返回结果
List<Customer> list = query.getResultList(); // 得到集合返回类型
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
em.close();
}