jpa-study
1:JPA (Java Persist API)
* Hibernate 是一个开放源代码的对象关系映射(ORM)框架,它是对于JDBC进行了轻量级的封装。 它将entity与数据库表建立关系映射。
它可以自动生成SQL语句,自动执行,使java程序员可以随心所欲的使用对象思维来操作数据库。
* JPA 是SUN公司官方提出的java持久化规范,它的出翔主要是简化持久化开发整合结束了现在 Hibernate、TopLink(Eclipse Link)等ORM框架各自为营的局面。
JPA是一种规范,而Hibernate是它的实现。
2:JPA 的优缺点
JDBC的优缺点:
*优点:操作数据库最底层,性能高。
*缺点:
1: 使用复杂。
2: 移植数据库比较麻烦,改动比较多。(主键的生成方式不同)。
3: 性能优化得自己处理。
4: 面向sql语句,不是面向对象
JPA的优缺点:处理Java对象和关系层数据库表之间的转化,只是对JDBC的一个简单的封装。
*优点:
1: 程序员操作简单,代码简单。
2:直接面向持久对象操作。
3:提供世界级数据库缓存 (一级缓存、二级缓存、查询缓存)
4:数据库移植性强 很少修改(通过配置方言)
*缺点:
1: 不能干预sql语句的生成。
2: 一个项目,如果对sql语句的优化比较高,不适合使用JPA
3: 如果一张表中有上亿级别的数据量,也不适合JPA,也不适用JDBC。(数据库读写分离)
3:ORM的概念
面向对象概念 面向关系概念
类 表
对象实体 表的行(记录)
属性 表的列
4:持久化配置 META-INFO文件夹下
<!--持久化名称 -->
<persistence-unit name="cn.com.star">
<properties>
<!-- 必须配置的4个连接信息-->
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost/company" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.username" value="postgres" />
<property name="hibernate.connection.password" value="sql" />
<!--必须配置一个方言属性 -->
<!-- 方言的作用: 主键的选择, 分页的sql的处理 不同的数据库需要不同的方言去解释-->
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL94Dialect" />
<!--可选配置-->
<!--是否显示sql -->
<property name="hibernate.show_sql" value="true" />
<!--是否自动建表 hbm 映射文件 ddl建表语句-->
<!-- 自动生成表策略-->
<!--
1:create-drop 先删除表-再建表-再删除表 删除时必须把EntityManagerFactory关闭 (一般不会用)
2:create 先删除表再建立表 (在测试环境中经常被应用)
3:update 如果没有表根据映射信息创建表
如果表里已经有这个属性,更改属性长度,不会更新到表里面 (测试和web项目中)
4:validate 用在系统上线或者给定了数据库
表不存在,会抛出异常
-->
<property name="hibernate.hbm2ddl.auto" value="create" />
<!--是否格式化sql -->
<property name="hibernate.format_sql" value="false" />
</properties>
</persistence-unit>
JPA-Study-Cache
1:JPA一级缓存和二级缓存简介
见图 resources/cache.png
2:JPA一级缓存的使用
/**
* JPA 的一级缓存的测试
* 一级缓存命中条件:
* 1: 同一个EntityManagerFactory
* 2: 同一个EntityManager
* 3: 对象Employee的全限定类名 + 主键叫做OID , 需要同一个OID
* OID = "cn.com.star.cache.Employee#1"
*/
@Test
public void findEmployeeUseSessionCache(){
EntityManager entityManager = JPAUtil.getEntityManager();
Employee star = entityManager.find(Employee.class,1L);
Employee starSession = entityManager.find(Employee.class, 1L);
//如果为true、只发一条sql、一级缓存命中
Assert.assertTrue("内存地址不一致!没用使用一级缓存",star == starSession);
}
/**
* 一级缓存没有命中, 将会发送两条sql.
*/
@Test
public void findEmployeeNotUseSessionCache(){
//清除一级缓存不关闭
//entityManager.clear();
//一级缓存移除对象
entityManager.detach(star);
}
3: JPA 持久对象的状态
/**
* JPA 持久化的4种状态
* 1: 瞬时状态(transient) 没有和EntityManager发生关系,没有被持久化。
* 2: 持久化状态(persistent) 已经和EntityManager发生关系 加入到EntityManager的一级缓存中。
* 3: 游离状态(detached) 已经被持久化,但不被EntityManager管理。
* 4: 删除状态(removed) 计划被删除,entityManager.delete(Entity)。
*/
JPA-Study-CRUD
1:JPA核心API简介
/**
* 核心API的简介
* Persistence 主要是创建EntityManagerFactory, 根据传入的 <persistence-unit name="cn.com.star">名称来创建相应的factory
* EntityManagerFactory EntityManger 工厂负责创建EntityManager
* EntityManager 实体管理对象 调用具体的 persist merge remove find findAll
* EntityTransaction 事务管理对象
* EntityTransaction 为javax.persistence.EntityTransaction
* 此类只能空值同一数据库不同表,大多数都使用这各类
* JTA Transaction 为javax.transaction.Transaction
* 此类可以处理不同数据库的事务。 事务列表list, 当list为true时提交事务
*/
2:JPA的简单注解使用
@Entity
//希望把Employee变成一张数据库表
@Table(name = "t_employee")
// 配置表名,如果没有写@Table,默认使用类名做为表名
public class Employee {
@Id
//配置主键
//配置主键生成策略 @GeneratedValue(Strategy=GenerationType.AUTO) 默认值
//mysql:AUTO_INCREMENT自增
//oracle:序列
@GeneratedValue
//修改数据库列名
//唯一约束 UNIQUE_KEY unique = true
// 非空约束 nullable = false
@Column(name = "e_id", unique = true, nullable = false)
private long id;
private String name;
//修改字段的长度
@Column(name = "pwd", length = 20)
private String password;
private Integer age;
private BigDecimal salary;
private Boolean sex;
//出生:年月日
@Temporal(TemporalType.DATE)
private Date birthday;
//会议时间: 时分秒
@Temporal(TemporalType.TIME)
private Date time;
//注册时间: 年月日 时分秒 默认生成时间戳
@Temporal(TemporalType.TIMESTAMP)
//注册时间不能被修改
@Column(updatable = false)
private Date createTime;
//大文本 oracle clob mysql longtext postgres text
@Lob
private String text;
}
3: JPA主键生成策略
1: 四种生成策略 auto策略 table策略 sequence策略 identity策略
主键实现的两种类型
1: 自然主键 有业务意义的主键
2: 代理主键 这个主键没有意义,用来区分数据库每行记录
JPA-Study-JPQL
1:基本的JPQL的格式
*只能写java的类名和属性名
*SELECT o[o.property, o.property*] FROM Entity o
[WHERE conditions]
[GROUP BY conditions]
[HAVING conditions]
ORDER BY o.property[ASC|DESC]*
JPQL 本质是JPA通过antlr-2.7.7.jar翻译成sql并且封装执行
JPQL和SQL很像, 查询关键字都是一样的
唯一的区别就是JPQL是面向对象的
2:练习
*1.查询所有员工
*2.查询所有员工的姓名和所属的部门名称
*3.查询出所有在成都和广州工作的员工
*4.查询所有员工信息, 按月薪排序
*5.查询出所有员工信息, 按照部门编号排序
*6.查询出在恩宁路和八宝街上班的员工信息[使用IN]
*7.查询出工资在5000-6000的员工[使用BETWEEN...AND...]
*8.查询出姓名包含er或者en的员工