jpa使用
一、而我都根据类名去反射获取表名。
二、entity必须存在无参构造函数(因为,底层使用的是entity.class.newInstance()来产生实例对象。)
三、需要配置方言,mysql和oracle会有不同:
1.方言 spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
2.mysql的分页和oracle的分页方式不一样,需要根据方言的设置,jpa就能自动转换。
四、jpq ddl auto:
1.create-drop: 创建表和删除表的时间是entityManagerFactory创建和关闭的时间;
2.create: 先删除表,再创建表。
3.update: 更多使用的时候,保持数据不会被删除。
1.没有表会生成表。
2.有表,只是修改字段,不会更新表,会多加一个字段出来。
3.添加字段,会更新表。
4.删除一个字段,也不会更新表。
4.validate: 用在系统已经上线或是客户给定了数据库。
1.表不存在,会抛出异常。
2.映射文件少属性,表比entity多属性,不会报错。
3.反之,报错。
五、错误:
1.不能设置String属性的length为0。
2.不能在一个工程中存在两个同名的entity class,哪怕设置table Name不同也不行。
六、Jpa对于表列的属性设置:
1.@Column(unique=true, length=20, nullable=false);
unique: 唯一约束。
length: 字段长度约束。
nullable: 非空约束。
2.@Lob: 放置超大文本数据的字段,longText。
3.时间:
1.年月日: @Temporal(TemporalType.DATE);
2.时分秒: @Temporal(TemporalType.TIME);
3.年月日时分秒: @Temporal(TemporalType.TIMESTAMP);
4.设置默认值:
1.@Column(insertable = false, columnDefinition= "int(11) default '25'"); 所有的insert语句,都没有这个字段,不会修改默认值。而且,这里对字段的定义会修改表的结构。因为固定了语法,所以,只能在mysql中使用,在oracle中得手动修改语句。
5.不能update: @Column(updatetable = false)
6.check约束(mysql不支持check约束)
1\. @Column(columnDefinition="decimal(19, 2) check (salary>0)")
7.集合:
1.@OrderBy("price DESC"): 使用场景是加载list上,可以对list中entity的某个字段排序。
2.使用集合只能使用接口,不能使用实现类,因为,jpa底层是实现集合接口的。
3.一般使用set集合,只要组合关系使用list。
七、数据库五种约束: 非空、唯一、主键、外键、check(检查)。
八、JPA缓存:
1. 一级缓存:
1.命中条件:
1.同一个EntityManagerFactory.
2.同一个EntityManager.
3.同一个OID(entity的全限定名+主键)
2.JTA事务:多库多表之间保证事务的同步。多用于银行的跨行转账。
内部实现:事务列表List list
提交的时候,判断list是否全为true,然后决定是否全部提交。
九、Entity之间的关系:
1.双向一对多: 配置的外键名称要一致,不然会出现两个外键。 两边都可以获取到另外一边的数据。
1.1: @OneToMany(LAZY, mappedBy="dir") #表示一方的关系参照多方的dir属性(不是列名)来管理。
//@JoinCloumn(name="foregin_key") #foregin_key得是一样的。
private School school;
1.2: @ManyToOne(LAZY)
@JoinCloumn(name="foregin_key")
private Set<Student>student;
1.3:需要在多方维护关系,这样性能高,减少SQL的执行。 维护在一方,还是和以前的一对多一样。 减少的就是一对多时候,update语句。
1.4:实现: 就是原本是创建多方的数据,add到一方的集合属性中。 现在,是创建一方的数据,set到多方的属性中。
2.
十、级联操作:
1.级联保存: 下有图2。
在一方配置 cascadeType=cascadeType.presist, mapperBy; cascadeType保证保存一方的时候,多方也会同时保存。 mapperby指定外键,否则,会创建一张中间表,来关联两个表之间的数据。
2.级联删除:
十一、JPQL:
一、都根据类名去反射获取表名。
二、entity必须存在无参构造函数(因为,底层使用的是entity.class.newInstance()来产生实例对象。)
三、需要配置方言,mysql和oracle会有不同:
1.方言 spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
2.mysql的分页和oracle的分页方式不一样,需要根据方言的设置,jpa就能自动转换。
四、jpq ddl auto:
1.create-drop: 创建表和删除表的时间是entityManagerFactory创建和关闭的时间;
2.create: 先删除表,再创建表。
3.update:
1.没有表会生成表。
2.有表,只是修改字段,不会更新表。
3.添加、删除字段,会更新表。
4.validate: 用在系统已经上线或是客户给定了数据库。
1.表不存在,会抛出异常。
2.映射文件少属性,表比entity多属性,不会报错。
3.反之,报错。
五、错误:
1.不能设置String属性的length为0。
2.不能在一个工程中存在两个同名的entity class,哪怕设置table Name不同也不行。
六、Jpa对于表列的属性设置:
1.@Column(unique=true, length=20, nullable=false);
unique: 唯一约束。
length: 字段长度约束。
nullable: 非空约束。
2.@Lob: 放置超大文本数据的字段,longText。
3.时间:
1.年月日: @Temporal(TemporalType.DATE);
2.时分秒: @Temporal(TemporalType.TIME);
3.年月日时分秒: @Temporal(TemporalType.TIMESTAMP);
4.设置默认值:
1.@Column(insertable = false, columnDefinition= "int(11) default '25'"); 所有的insert语句,都没有这个字段,不会修改默认值。而且,这里对字段的定义会修改表的结构。因为固定了语法,所以,只能在mysql中使用,在oracle中得手动修改语句。
5.不能update: @Column(updatetable = false)
6.check约束(mysql不支持check约束)
1\. @Column(columnDefinition="decimal(19, 2) check (salary>0)")
7.集合:
1.@OrderBy("price DESC"): 使用场景是加载list上,可以对list中entity的某个字段排序。
2.使用集合只能使用接口,不能使用实现类,因为,jpa底层是实现集合接口的。
3.一般使用set集合,只要组合关系使用list。
七、数据库五种约束: 非空、唯一、主键、外键、check(检查)。
八、JPA缓存:
1. 一级缓存:
1.命中条件:
1.同一个EntityManagerFactory.
2.同一个EntityManager.
3.同一个OID(entity的全限定名+主键)
2.JTA事务:多库多表之间保证事务的同步。多用于银行的跨行转账。
内部实现:事务列表List list
提交的时候,判断list是否全为true,然后决定是否全部提交。
九、Entity之间的关系:
1.双向一对多: 配置的外键名称要一致,不然会出现两个外键。 两边都可以获取到另外一边的数据。
1.1: @OneToMany(LAZY, mappedBy="dir") #表示一方的关系参照多方的dir属性(不是列名)来管理。
//@JoinCloumn(name="foregin_key") #foregin_key得是一样的。
private School school;
1.2: @ManyToOne(LAZY)
@JoinCloumn(name="foregin_key")
private Set<Student>student;
1.3:需要在多方维护关系,这样性能高,减少SQL的执行。 维护在一方,还是和以前的一对多一样。 减少的就是一对多时候,update语句。
1.4:实现: 就是原本是创建多方的数据,add到一方的集合属性中。 现在,是创建一方的数据,set到多方的属性中。
2.
十、级联操作:
1.级联保存: 下有图2。
在一方配置 cascadeType=cascadeType.presist, mapperBy; cascadeType保证保存一方的时候,多方也会同时保存。 mapperby指定外键,否则,会创建一张中间表,来关联两个表之间的数据。
2.级联删除:
十一、JPQL:
1.语法和sql语法差不多,只是使用的是类名和属性,不再使用表名和列名。
2.使用连表语句的时候,直接使用对象点属性: eg: select new Employee(o.name, o.department.name) from Employee o;
需要提供对应的构造函数。 若不使用构造方法的形式,返回的就是一个Object[];
** 3.最重要的一点: 使用的是面向对象的形式去编写sql,都可以使用自己内部的属性,去使用属性自己的属性。**
4.
十二、缓存:
1.一级缓存: 只在自己的entityManager中有效。
2.二级缓存: 在类上添加@Cacheable。
3.二级缓存中集合的缓存: 在集合属性上@Cache(usage=CacheConcurrencyStrategy.READ_WREITE), 同时需要在集合的domain类上添加@Cacheable。
4.使用规则:
1.读取大于修改。
2.对数据要有独享控制,数据不会被第三方修改(直接操作数据库的工具)。
3.可以容忍无效数据,非关键数据(不是财务数据等等)。
4.数据量不能超过内存容量,数据量特别巨大,不适合二级缓存。
image.png
jpa的一级缓存、二级缓存和查询缓存
image.png双向多对一级联保存的正确 (赋值)方式
image.png多对多删除2
image.png多对多删除3
image.png多对多删除4
image.png多对多更新
image.png一对一,不能配置fetchLazy,默认就可以一次性leftJoin拿取到所有的数据。
image.png唯一外键和共享主键一对一
image.png唯一外键和共享主键一对一,需要给QQ设置@PrimaryKeyJoinColumn
image.pngJpql使用set.size
image.pngJPQL (LEFT join)
image.png毫秒级事务管理(秒杀)
JPA可以处理第一类丢失和第二类丢失,其余的都需要数据库去设置。
image.png image.png image.png image.png image.png悲观锁会出现用户操作的排队现象,需要上一个操作事务提交,才能再次访问
image.png乐观锁,使用version这个私有字段,当事务在提交的时候,会修改这个值。出现冲突则,会抛出异常。
image.png优化JPA
image.png