JPA概述

Java Persistence API

什么是JPA

就是一款ORM规范

什么是JDBC

jdbc是操作数据库的唯一技术 ,sun公司只提供了jdbc规范
sun公司在jdbc很难用的情况下 推出了第一款EJB

EJB

企业级的javabean
特点:功能强大提供了非常多的api的文档
简单理解就是他对domain,dao,service进行了强大的封装,你要完成对应的crud,直接调用方法即可
缺陷:太过笨重了

Hibernate

hibernate是一款轻量级的orm框架
主要是解决DAO层领域的问题
但是在hibernate推出的这一时期出现了很多出名的orm框架 比如toplink mybatis
于是 sun公司就找到hibernate的坐着gavin king 说你的hibernate太优秀了 来我们公司制定一些orm框架吧 没过多久 一个强大的orm规范就出来了 这就是jpa

ORM

什么是orm

Object Relational Mapping(对象关系映射)
o:object
R:关系型数据库
M:对象映射关系型数据库

使用jpa或者hibernate的好处:在使用框架的时候,不需要写sql 语句 只需要传入对应的对象 就能完成相应的crud

》》》》面试

jdbc与jpa的区别:

  1. jpa底层是基于jdbc实现的,他对jdbc进行了层层封装 jpa操作数据库更加简单了 因为只需要传入相应的对象 底层会自动生成对应的sql语句
  2. 不需要是sql高手 也可以操作数据库
  3. 由于jpa对jdbc进行了层层封装 所以sql语句不需要自己编写 所以执行性能方面要比原生的jdbc低得多
  4. jpa移植数据库很简单 不需要改sql语句 只需要改一下方言即可
  5. jpa提供了缓存 一级缓存和二级缓存 而jdbc没有 如果需要缓存还需要自己编写
  6. jpa是面向对象编程 而jdbc是面向sql编程

第一个JPA

导包及其作用:

在这里插入图片描述

在这里插入图片描述

核心配置文件persistence.xml

在这里插入图片描述
在这里插入图片描述

persistence.xml的配置

持久化单元 简单理解持久化单元就是我们以前的连接池
name:持久化单元的名字
transaction-type:事务类型

  • RESOURCE_LOCAL:使用mysql自带的事务
  • JTA:主要用于分布式中 目前暂时用不到
配置连接数据库的四大金刚:
<!--username-->
<property name="hibernate.connection.username" value="root"/>
<!--password-->
<property name="hibernate.connection.password" value="root"/>
<!--url-->
<property name="hibernate.connection.url" value="jdbc:mysql:///jpa"/>
<!--driverClassName-->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
配置方言:

使用方法的好处:它底层会根据你使用的方言来自动生成sql语句
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
显示sql
<property name="hibernate.show_sql" value="true"/>

格式化sql
<property name="hibernate.format_sql" value="false"/>

建表策略
  1. create:先删除表,再创建表 使用场景: 学习和测试
  2. create-drop: 先删表,再创建表,再删表(前提:关闭EntityManagerFactory) 不多 使用场景: 学习和测试
  3. update: 只增不减 注意:真实开发我们都用它
    • 如果没有表,它会根据domain自动生成表
    • 如果数据库有表, 并且 domain要比表多属性, 它会自动把多余的属性同步到数据库表中
    • 如果数据库有表, 并且domain要比表少属性,正常运行
  4. validate: 校验 校验domain和数据库中的表示是否对应,如果对应正常运行如果不对应,则报错
    • 如果domain的数量少于数据库表的列,但是类型都是一致的,正常运行
    • 如果domain的数据少于数据表的列,但是数据类型不是一致,则报错
    • 如果domain的个数大于数据库表中的列,直接报错

<property name="hibernate.hbm2ddl.auto" value="create"/>

jpa增删改查代码

原始增加
//持久化单元名
String unitname = "cn.itsource.unit";
//根据持久化单元名加载jpa的核心配置文件(1.检查jpa核心配置文件,配置语法是否有问题
// 2.它会把xml解析的信息放到EntityManagerFactory内部,3.它会扫描所有交给jpa管理的domain,会进行一一映射数据库中)
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(unitname);
//创建EntityManager对象(简单把它看成就是一个连接对象)
EntityManager entityManager = entityManagerFactory.createEntityManager();

//在使用持久化框架的时候,操作数据,必须要提交事务
//开启事务
entityManager.getTransaction().begin();
User user = new User();
user.setUsername("王天霸");
user.setAge(22);
user.setEmail("123@qq.com");
//保存数据
entityManager.persist(user);
//提交事务
entityManager.getTransaction().commit();
//关闭entityManager对象
entityManager.close();
提取工具类
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtils {
    private static EntityManagerFactory entityManagerFactory;
    static{
        entityManagerFactory = Persistence.createEntityManagerFactory("cn.itsource.unit");
    }
    public static EntityManager openEntityManager(){
        return entityManagerFactory.createEntityManager();
    }
}
CRUD
//保存数据
entityManager.persist(user);
//查询对象
entityManager.find(User.class,1L);
//修改数据
entityManager.merge(user);
//删除数据
entityManager.remove(user);
//查找多行数据
 String jpql = "from User";
//获取到query对象
Query query = entityManager.createQuery(jpql);
//查询所有的数据
List<User> resultList = query.getResultList();

注解

  • @Entity
    表示这个类交给jpa管理
  • @Table(name = “t_user”)
    申明指定的表名
  • @Id
    申明id为主键
  • @GeneratedValue
    主键自增
  • @Column(name = “username”,length = 20,nullable = false,unique = true)
    varchar(20),数据库名称为username,不能为空,唯一
  • @Column(columnDefinition = “int default 25”,insertable = false)
    默认值是25,在插入数据时不允许覆盖(添加数据时不操作该字段) 插入数据的时候该属性不会在sql语句中出现
  • @Column(columnDefinition = “decimal(3,2) default null”)
    表示一共有三位 小数位数两位
  • @Temporal(TemporalType.TIMESTAMP)
    包含年月日时分秒,不允许修改
  • @Temporal(TemporalType.DATE)
    包含年月日
  • @Temporal(TemporalType.TIME)
    包含时分秒
  • @Lob
    这是一个大文本
  • @Transient
    瞬时 这一个字段不要同步到数据库

JPA核心对象

Persistence:它主要是用来创建EntityManagerFactory对象

EntityManagerFactory对象

他是一个重量级的对象也就是说我们创建一个EntityManagerFactory是非常不容易的 所以一般我们不会去轻易的销毁

主要重在哪里

  1. 会去检查xml的语法格式
  2. 解析xml之后,把基本信息放到EntityManagerFactory内部
  3. 它管理着交给jpa管理的所有对象
  4. 内部装了一个连接池对象
  5. 内部还装着二级缓存
  6. 内部还装了预定义的sql语句

使用EntityManagerFactory我们有一句口号叫1:1:1
一个项目对象一个EntityManagerFactory对应一个数据库

EntityManager

它是由EntityManagerFactory创建的一个轻量级对象

  1. 内部装着一个一级缓存
  2. 内部也装了一个连接对象

OID(对象id):cn.itsource._02cache.CacheDomain#1

一级缓存底层实现原理
CacheDomain domain =  cache.get(cn.itsource._02cache.CacheDomain#1);
if(domain==null){
	domain = 发送sql语句到数据库中查询对应的对象;
	if(domain!=null){//把查询出来的数据放到一级缓存中
		cache.put(cn.itsource._02cache.CacheDomain#1,domain);
	}
 }
 return domain;

实例:

	EntityManager entityManager = JPAUtils.openEntityManager();
	//它底层代码实现原理:  首先通过oid在一级缓存中查找对应的对象,如果找到了,直接引用,如果没找到则发送sql语句到数据库中进行查找,把查找对象放到一级缓存中
	CacheDomain cacheDomain = entityManager.find(CacheDomain.class, 1L);
	System.out.println(cacheDomain);
	System.out.println("===============================");
	//由于上一个把查询的对象放到一级缓存中了,这时候我通过oid直接在一级缓存中找到对应的对象,所以就没有发送sql语句
	CacheDomain cacheDomain1 = entityManager.find(CacheDomain.class, 1L);
	System.out.println(cacheDomain1);
一级缓存命中满足的条件:
  1. 同一个EntityManager
  2. 同一个OID
  3. 同一个EntityManagerFactory
    缺一不可
    什么叫做一级缓存命中
    简单理解就是通过oid在一级缓存中查找到了对应的对象
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐