- JPA是Java Persistence API的简称。
2.JPA作为 Java EE 5.0 平台标准的 对象关系映射(ORM) 规范
Hibernate和JPA的关系
Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级(相对于EJB这一套)的对象封装,它将POJO(就是咱们的domain)与数据库表建立映射关系,是一个全自动的orm框架,Hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
JPA是持久化规范,而Hibernate是其实现
JDBC的优缺点
如果说JDBC与JPA优能更高:你必需会使用缓存,必需是一个SQL高手
本质:处理Java对象和关系型数据库表之间的转换
优点:操作数据库最底层,性能最高(前提是你要有相应的经验,并且是一个数据库高手)
缺点:
- 使用复杂(重复代码太多)
- 移植数据库很麻烦,改动比较多
主键的生成方式不同(mysql使用自增,oracle使用序列sequence)
分页的sql语句也是不同(mysql使用limit,oracle使用ROWNUM) - 性能优化得自己处理,没有提供数据的缓存,需要自己实现
- 面向sql语句操作,不是面向对象的
JPA的优缺点
本质:处理Java对象和关系型数据库表之间的转换,只是对JDBC再次做了一层封装
优点:
- 程序员操作很简单,代码简单 entityManager.persist(employee);
- 直接面向持久对象操作
- 提供世界级数据缓存(现在几乎所有的ORM框架的缓存都是学的Hibernate)
一级缓存,二级缓存,查询缓存(空间换速度) - 数据库移植性很强,很少的修改(通过配置方言搞定)
把各种数据库抽取了一个方言接口
不同数据库实现一个方言接口,如果换了数据库,必须修改方言实现,驱动jar文件,连接数据库信息。
缺点:
1.不能干预sql语句的生成
entityManager.find(User.class, 1L);
find方法默认查询t_user表的所有字段
自动生成select user0_.id,user0_.name,user0_.age from t_user user0_ where user0_.id=?
2.一个项目中,如果对sql语句的优化要求比较高,不适合用JPA(不过可以使用JPA对原生sql的支持来解决)
3.如果一张表中有上亿级别的数据量,也不适合用JPA,其实也不适合用jdbc(可以使用数据库读写分离,分库分表方案解决)。
JPA CRUD
抽取JPAUtils
和以前学习JDBC一样,咱们需要抽取一个工具类
public class JPAUtils {
// 保证EntityManagerFactory是单例
private static EntityManagerFactory entityManagerFactory;
static {
try {
// 对应配置文件里面的persistence-unit name=“cn.itsource.jpa”
entityManagerFactory = Persistence.createEntityManagerFactory(“cn.itsource.jpa”);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(“解析配置文件或者映射配置出现异常:” + e.getMessage());
}
}
public static EntityManager getEntityManager() {
return entityManagerFactory.createEntityManager();
}
}
每次都先添加数据
@Before
public void save() throws Exception {
Employee employee = new Employee();
employee.setName(“xxxxx”);
employee.setPassword(“yyyyy”);
EntityManager entityManager = JPAUtils.getEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(employee);
entityManager.getTransaction().commit();
entityManager.close();
}
修改
@Test
public void update() throws Exception {
Employee employee = new Employee();
employee.setId(1L);
employee.setName(“itsource”);
employee.setPassword(“25度”);
EntityManager entityManager = JPAUtils.getEntityManager();
entityManager.getTransaction().begin();
entityManager.merge(employee);
entityManager.getTransaction().commit();
entityManager.close();
}
删除
@Test
public void delete() throws Exception {
EntityManager entityManager = JPAUtils.getEntityManager();
entityManager.getTransaction().begin();
Employee employee = entityManager.find(Employee.class, 1L);
if (employee != null) {
entityManager.remove(employee);
}
entityManager.getTransaction().commit();
entityManager.close();
}
查询所有数据
@Test
public void getAll() throws Exception {
EntityManager entityManager = JPAUtils.getEntityManager();
// jpql:JPA的查询语言,类似于sql
// 1.里面不能出现表名,列名,只能出现java的类名,属性名
// 2.出现的sql关键字是一样的意思,
// 3.不能写select * 要写select 别名
// 建议用法
String jpql = "select o from Employee o";
// 最标准的用法
jpql = "select o from cn.itsource.jpa.crud.Employee o";
// 简写
jpql = "from Employee";
Query query = entityManager.createQuery(jpql);
List<Employee> list = query.getResultList();
System.out.println(list.size());
for (Employee employee : list) {
System.out.println(employee);
}
entityManager.close();
}
通过主键获取一条数据
@Test
public void get() throws Exception {
EntityManager entityManager = JPAUtils.getEntityManager();
Employee employee = entityManager.find(Employee.class, 1L);
System.out.println(employee);
entityManager.close();
}