JPA 入门 个人记录

JPA 入门

什么是JPA、为什么需要JPA、JPA优缺点/ORM的概念;
1.什么是JPA:
1.JPA是Java Persistence API的简称。
2.JPA作为 Java EE 5.0 平台标准的 对象关系映射(ORM) 规范

ORM:对象关系映射(object relational mapping,简称ORM)

idname
12

t_employee — 类对应上Employee

字段id/name — 类里面的属性 Id name

一行数据 — new Employee(1,‘星星’);

对象(Domain类 Entity<实体>类 对象)

3.将得到所有 Java EE 服务器的支持。 Sun 这次吸取了之前 EJB 规范惨痛失败的经历,在充分吸收现有 ORM 框架(如Hibernate)的基础上,得到了一个易于使用、伸缩性强的 ORM 规范。
从目前的开发社区的反应上看
JPA 受到了极大的支持和赞扬, JPA 作为 ORM 领域标准化整合者的目标已经实现。
2.为什么需要JPA

2.1以前使用JDBC,再对象和数据库之间转换特别麻烦

2.2JPA是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。

3.Hibernate和JPA的关系(面试)

Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级(相对于EJB这一套)的对象封装,它将POJO(就是咱们的domain)与数据库表建立映射关系,是一个全自动的orm框架,Hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

JPA:他是ORM的规范

Hibernate: 它是ORM这个规范实现的框架

JDBC和JPA的优缺点:

本质:处理Java对象和关系型数据库表之间的转换

JDBC优缺点:

操作数据库最底层,性能最高(前提是你要有相应的经验,并且是一个数据库高手)

1.使用复杂(重复代码太多)

2.移植数据库很麻烦,改动比较多

​ 主键的生成方式不同(mysql使用自增,oracle使用序列sequence)

​ 分页的sql语句也是不同(mysql使用limit,oracle使用ROWNUM)

  1. JDBC自身没有缓存(Cache),性能优化得自己处理,没有提供数据的缓存,需要自己实现
  2. JDBC是面向sql语句操作,不是面向对象的
  3. 比较简单,比较直接,就可以操作数据库

JPA优点:

1.面向对象操作,操作对象就相当于操作数据,比如 entityManager.perisit(employee)

2.移植数据比较方法,以后如果想换数据库,只需要换数据库的方言就OK了

3.JPA有缓存,效率不错(一级缓存 二级缓存 查询缓存)提供世界级的缓存,使用空间换取时间

JPA缺点:

1.不能干预sql语句的生成 查询一个数据 findOne, 默认查询所有字段(select * from)

2.有些优化JPA做不了,比如特别大的数据量的时候,jpa也不适合,mybatis也解决不了(架构,分布式)

3.一个项目里面对SQL要求比较高的话,就不适合JPA

总结:

  1. 什么是JPA?java persistence api 对象关系映射(ORM) 规范(持久化)
  2. Hibernate和JPA的关系? JPA是规范,Hibernate是它的一个实现。
  3. Hibernate是一个完整的对象关系映射框架 mybatis半自动ORM框架
  4. 什么是ORM? 对象关系映射
  5. JDBC与JPA的优缺点?

​ JDBC操作更加底层,它的性能是完全可控的(前提:有控制它性能的能力)

​ JPA对JDBC的封装,快速开发,自身已经有了很好的性能优化,兼容各种数据库

​ 缺点:不能干涉SQL生成(有些性能问题无法解决)

第一个JPA程序;

​ 导入jar包: pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>cn.itsource</groupId>
<artifactId>jpa-demo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>jpaday01</module>
</modules>

<dependencies>
<!-- hibernate的包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.8.Final</version>
</dependency>
<!-- hibernate对于jpa的支持包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.8.Final</version>
</dependency>
<!-- mysql的驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- junit的测试包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<finalName>pss</finalName>
<plugins>
<plugin>
<!-- Maven的编译插件-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

</project>

配置 核心配置文件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="cn.itsource.jpa" transaction-type="RESOURCE_LOCAL">
		<properties>
			<!-- 必须配置4个连接数据库属性 -->
			<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
			<property name="hibernate.connection.url" value="jdbc:mysql:///jpa" />
			<property name="hibernate.connection.username" value="root" />
			<property name="hibernate.connection.password" value="admin" />

			<!-- 必须配置1个方言属性 -->
			<!-- 实现跨数据库关键类 :查询MySQLDialect的getLimitString方法 -->
			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />

			<!-- 可选配置 -->
			<!-- 是否自动生成表-->
                
                /*
                create:创建策略,每次都要删除再创建新的
                
                update:修改策略,不用每次都删除再创建 如果发现没有表,
                也会创建表  如果是表里面新增的字段,配置都有效果,
                如果这个表里面已经存在该字段 去修改属性是没有效果的 
                比如length长度   一般都用这个update策略
                
                create-drop:先删除 再创建 再删除 不怎么会用 面试会问
                	而且要使用的话必须把 entityManager手动关闭了才行
                	一般临时表才会用  用一次就不要了
                
                validate:验证策略,当前配置和数据库的配置进行对比验证,
                	如果有对应实体,但是没有对应的数据库表 就会报错
                	必须表数据等于或者大于实体类
                	不能表数据小于实体类  否则会报错丢失列
                	使用场景:比如已知数据库的前提下
                	就可以把实体的配置和数据库的配置进行对比
                */
                
			<property name="hibernate.hbm2ddl.auto" value="create" />
			<!-- 是否显示sql -->
			<property name="hibernate.show_sql" value="true" />
			<!-- 格式化sql -->
			<!-- <property name="hibernate.format_sql" value="true" /> -->
		</properties>
	</persistence-unit>
</persistence>

@Entity  //表示这个类是一个实体类  @Entity表示一个由jpa管理的持久对象,对应数据库的一个表

@Id     // @Id是必须的,是对应表的主键

@GeneratedValue   // @GeneratedValue表示主键的生成方式,多数都是使用AUTO

@GeneratedValue(strategy = GenerationType.AUTO)//默认省略了后面的(strategy = GenerationType.AUTO)

//strategy: 策略    GenerationType:生成

@Table(name = "t_employee")// table 写数据库的表名

 @Column(name = "e_id") //定义列的名字

 // AUTO自动选择数据库本地的策略:
 // mysql:AUTO_INCREMENT自增
 // oracle:序列


// 对应配置文件里面的persistence-unit name="cn.itsource.jpa"  

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("cn.itsource.jpa");//得到EntityManagerFactory  实体管理工厂

// createEntityManager : 创建实体管理对象

//getTransaction(): 获取事务

// gettransaction.begin();开启事务

// gettransaction.commit():提交事务

//通过entityManager就可以管理实体   persist(“对象”): 持久化方法
   entityManager.persist(user);
// gettransaction.close(); 清理
// entityManagerFactory.close();关闭资源

 //create:创建策略,每次都要删除再创建新的
 //update:修改策略,不用每次都删除再创建


JPA抽取工具类

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();
  }
}

JPA的CRUD (极其重要);
//查询一条数据
 System.out.println(entityManager.find(User.class,1L));//传入字节码文件和对象
/*
	查询所有数据 
    使用JPQL语句:类似于sql的语句 jpa提供查询数据库的语言
    写法: 面向对象的思维
    	jpql: select o(对象的别名) from User o(设置的别名);
    如果查询某一个 就: select o.name(写出属性名) from User o;
    entityManager.createQuery(jpql,User.class);
    query.getResultList(); //获取结果集
    
    list.iter  遍历for循环
     */
    list.forEach(user->{
    	System.out.println(user);
    })  //新特性增强for循环
 
  /*
  	删除  一个游离状态的数据的时候就会报错, 没有和实体类关联起来
  	先让需要删除的数据跟entitymanager发生关系再删除
  	就是通过获取ID来先查询再进行删除
  	User user = entitymanager.find(User.class,1L);
  	if( user != null){
  		entityMangeger.remove(user);
  	}
  */
    
    @Column(name = "e_id",length=255)
        

JPA的核心 API 认识;

[外链图片转存失败(img-dOBns2kC-1563871210833)(file:///C:/Users/kira/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)]

Persistence:

​ 获取EntitymanagerFactory工厂的

EntitymanagerFactory:实体管理工厂 这个类他是重量级的,

不要频繁的创建和销毁,很消耗性能,这个类该怎么设计呢?

1:1:1 设计 1给应用程序 对应一个entityManagerFactory 对应1个数据库

这个类也应该设计成共享的。再设计成共享的时候尽量线程安全(ThreadLocal <加锁>)

  1. 《重量级》数据库库配置信息他里面有一个连接池(本身就中,创建和销毁太费时间)
  2. 又二级缓存(查询缓存,…)
  3. 预定义的JPQL语句(JPQL,SQL)
  4. 维护所有实体以及他们之间的关系

entityManager:

​ 它是实体管理的类,可以管理实体(CRUD),是一个轻量级的类,可以频繁的创建

和销毁,不会消耗太多的性能,它是线程不安全的,但是再设计,多个线程来访问的时候,尽量的保证线程是安全的,如果没有线程安全,出现事务并发带来的问题;

事务并发:多个事务同时操作同一个数据的时候(转账的例子)

1.管理实体(CRUD)

2.entitymanager里面又一个一级缓存

​ 缓存:Cache 在内存里面开辟一个空间来临时存储数据

​ 目的:提高查询的效率,空间换取时间

​ 缓存什么时候才能用上:(一级缓存命中之后就可以用了)

​ 同一个EntityManagerFactory 同一个EntityManager 痛一个OID(实体对象的ID–主键ID)

EntityTransaction:

​ 实体事务对象

​ 现在EntityTransaction – 都是本地事务,同一个库里面的事务

​ 不同数据库的事务:(不同的银行转账) 分布式事务

persist持久化方法,保存方法

配置自动生成表(掌握);

​ 建表策略

   /*
                create:创建策略,每次都要删除再创建新的
                
                update:修改策略,不用每次都删除再创建 如果发现没有表,
                也会创建表  如果是表里面新增的字段,配置都有效果,
                如果这个表里面已经存在该字段 去修改属性是没有效果的 
                比如length长度   一般都用这个update策略
                
                create-drop:先删除 再创建 再删除 不怎么会用 面试会问
                	而且要使用的话必须把 entityManager手动关闭了才行
                	一般临时表才会用  用一次就不要了
                
                validate:验证策略,当前配置和数据库的配置进行对比验证,
                	如果有对应实体,但是没有对应的数据库表 就会报错
                	必须表数据等于或者大于实体类
                	不能表数据小于实体类  否则会报错丢失列
                	使用场景:比如已知数据库的前提下
                	就可以把实体的配置和数据库的配置进行对比
                */
			<property name="hibernate.hbm2ddl.auto" value="create" />
单表映射细节(掌握);
  @Id   
  @GeneratedValue   	
  private Long id; //要求:主键,使用数据库的自动生成策略
  @Column(length=20,name="username",)
  private String name;  //要求:varchar(20),数据库名称为username,不能为空,唯一
  private String password; 
  @Column(columnDefiniton="int(20) default 25",)
  private Integer age = 25; //要求:默认值是25,在插入数据时不允许覆盖(添加数据时不操作该字段)
  private Boolean sex;// 数据库没有布尔类型,bit对象 
  @Column(columnDefiniton="decimal(19,2)")
  private BigDecimal salary;// 19,2 

  @Column(updatable = false)
  @Temporal(TemporalType.TIMESTAMP)
  private Date createTime;//包含年月日时分秒,不允许修改
  
  @Temporal(TemporalType.DATE)   
  private Date birthday;//包含年月日

  @Temporal(TemporalType.TIME)
  private Date time;//包含时分秒

  @Lob
  private String text;//这是一个大文本 longtext

  @Transient
  private String temp;//这一个字段不要同步到数据库

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值