JPA的理解

JPA的总体思想和现有hibernate、TopLink,JDO等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:

  1. ORM映射元数据,JPA支持XML和JDK 5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
  2. JPA的API,用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
  3. 查询语言JPQL,这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

JPA 实体生命周期理解

jpa 实体生命周期有四种状态
JPA生命周期.png

  • New:瞬时对象,尚未有id,还未和Persistence Context建立关联的对象。
  • Managed:持久化受管对象,有id值,已经和Persistence Context建立了关联的对象。
  • Datached:游离态离线对象,有id值,但没有和Persistence Context建立关联的对象。
  • Removed:删除的对象,有id值,尚且和Persistence Context有关联,但是已经准备好从数据库中删除

Managed状态下的数据保存,更新以及删除数据下的Removed状态,数据都不会立即更新到数据库,只有当你事务提交或者em.flush(),才会立即更新到数据库。

Datached的状态,可以调用em.merge()方法,这个方法会根据实体类的id来更新数据库数据,这时实体类变成了Managed状态。

四种状态总结:

状态名 作为java对象存在 在实体管理器中存在 在数据库存在
New yes no no
Managed yes yes no
Datached no no no
Removed yes yes no
  1. @Transactional
  2. public void save(){
  3. //New 状态
  4. Task t = new Task();
  5. t.setTaskName("task" + new Date().getTime());
  6. t.setCreateTime(new Date());
  7. //Managed状态
  8. em.persist(t); //实体类t已经有id t.getId();
  9. t.setTaskName("kkk"); //更新任务名称,这时,如果提交事务,则直接将kkk更新到数据库
  10. //Detached状态 事务提交或者调用em.clear都直接将实体任务状态变为Detached
  11. em.clear();
  12. t.setTaskName("kkk"); //更新数据不会更新到数据库
  13. //Removed状态
  14. em.remove(t);
  15. }

JPA 实体管理器

实体管理器(EntityManager)用于管理系统中的实体,它是实体与数据库之间的桥梁,通过调用实体管理器的相关方法可以把实体持久化到数据库中,同时也可以把数据库中的记录打包成实体对象。

JPA的persistence.xml文件

persistence.xml 是JPA的持久化配置文件,用来映射PU(Persist Unit)的。作用是映射表和类,里面也可以配置数据库连接信息

https://www.cnblogs.com/luxh/archive/2012/05/24/2516282.html

https://www.cnblogs.com/116970u/p/11584418.html

  1. 注意:配置参数hibernate.hbm2ddl.auto 各个取值的含义
  2. validate update create create-drop
  3. 这几个参数的作用主要用于:自动创建 更新 验证数据库表结构
  4. 如果不是此方面的需求取none
  5. validate:加载hibernate时,验证创建数据库表结构
  6. create:每次加载hibernate,重新创建数据库表结构,这就是导致数据库表结构丢失的原因
  7. create-drop:加载hibernate时创建,退出是删除表结构
  8. update:加载hibernate自动更新数据库结构

列注解

当将Java bean映射到实体时,可以使用注解 @Column 表示物理数据库列的特定特征。

  1. @Target({ElementType.METHOD, ElementType.FIELD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface Column {
  4. String name() default "";
  5. // 设置列值是否具有唯一性,默认不唯一
  6. boolean unique() default false;
  7. // 设置列是否允许为空,默认允许为空
  8. boolean nullable() default true;
  9. boolean insertable() default true;
  10. boolean updatable() default true;
  11. // 声明对应数据库列类型
  12. String columnDefinition() default "";
  13. String table() default "";
  14. // 设置字段长度
  15. int length() default 255;
  16. // 设置字段精度
  17. int precision() default 0;
  18. // 设置字段尺度
  19. int scale() default 0;
  20. }

参数columnDefinition
columnDefinition = “VARCHAR(40)”

使用name属性设置对应表字段

默认情况下,JPA使用字段名作为数据库表列名。可以使用name属性来设置列名称。

  1. @Column(name = "sal")
  2. private long salary; // 表明当前字段与数据表sal映射

使用length字段设置字段长度

使用JPA,我们可以设置字段的列长度。例如,当将字符串字段映射到VARCHAR时,我们可以在@Column 注释中设置VARCHAR长度。

  1. @Column(length=40)
  2. private String name; // 字段name varchar(40)

设置列精度范围

当将Java float或double值映射到数据库表列时,我们可以设置数字类型列的精度尺度。

以下代码将浮点值映射到具有精度8和尺度2的数据库表列。

  1. @Column(precision=8, scale=2)
  2. private float hourlyRate;

使用@Transient注释标记该字段不映射数据库字段

  1. @Transient
  2. private String convertedName;

此时,在对象关系映射时,字段convertedName不参与,数据表中没有字段与之对应。