JPA入门
JPA概述Java Persistence API什么是JPA就是一款ORM规范什么是JDBCjdbc是操作数据库的唯一技术 ,sun公司只提供了jdbc规范sun公司在jdbc很难用的情况下 推出了第一款EJBEJB企业级的javabean特点:功能强大提供了非常多的api的文档简单理解就是他对domain,dao,service进行了强大的封装,你要完成对应的crud,直接...
文章目录
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的区别:
- jpa底层是基于jdbc实现的,他对jdbc进行了层层封装 jpa操作数据库更加简单了 因为只需要传入相应的对象 底层会自动生成对应的sql语句
- 不需要是sql高手 也可以操作数据库
- 由于jpa对jdbc进行了层层封装 所以sql语句不需要自己编写 所以执行性能方面要比原生的jdbc低得多
- jpa移植数据库很简单 不需要改sql语句 只需要改一下方言即可
- jpa提供了缓存 一级缓存和二级缓存 而jdbc没有 如果需要缓存还需要自己编写
- 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"/>
建表策略
- create:先删除表,再创建表 使用场景: 学习和测试
- create-drop: 先删表,再创建表,再删表(前提:关闭EntityManagerFactory) 不多 使用场景: 学习和测试
- update: 只增不减 注意:真实开发我们都用它
- 如果没有表,它会根据domain自动生成表
- 如果数据库有表, 并且 domain要比表多属性, 它会自动把多余的属性同步到数据库表中
- 如果数据库有表, 并且domain要比表少属性,正常运行
- 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是非常不容易的 所以一般我们不会去轻易的销毁
主要重在哪里
- 会去检查xml的语法格式
- 解析xml之后,把基本信息放到EntityManagerFactory内部
- 它管理着交给jpa管理的所有对象
- 内部装了一个连接池对象
- 内部还装着二级缓存
- 内部还装了预定义的sql语句
使用EntityManagerFactory我们有一句口号叫1:1:1
一个项目对象一个EntityManagerFactory对应一个数据库
EntityManager
它是由EntityManagerFactory创建的一个轻量级对象
- 内部装着一个一级缓存
- 内部也装了一个连接对象
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);
一级缓存命中满足的条件:
- 同一个EntityManager
- 同一个OID
- 同一个EntityManagerFactory
缺一不可
什么叫做一级缓存命中
简单理解就是通过oid在一级缓存中查找到了对应的对象
更多推荐
所有评论(0)