Hibernate
public class AA{
@Setter
@Getter
@Id
@GenericGenerator(name = "systemUUID", strategy = "uuid")
@GeneratedValue(generator = "systemUUID")
@Column(name = "id", nullable = false)
private String id;
@OneToMany(mappedBy = "aa", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JsonIgnore
private List<BB> bbList;
}
public class BB{
@Setter
@Getter
@Id
@GenericGenerator(name = "systemUUID", strategy = "uuid")
@GeneratedValue(generator = "systemUUID")
@Column(name = "id", nullable = false)
private String id;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private AA aa;
}
两个类之间的关系如上,现在需要新建AA,BB的一些实例并相互关联保存到数据库。
1.没有开启事务
①
AA aa= new AA();
session.saveOrUpdate(aa); // 此时的 aa 实例会有id,数据库中也可以查到数据,
BB bb = new BB();
bb.setAa(aa);
session.saveOrUpdate(bb); // 此时的 bb实例会有id,数据库中也可以查到数据,
aa.getBbList() // 值null,获取需要重新查询aa的值
②
AA aa= new AA();
BB bb = new BB();
bb.setAa(aa); // aa一直没有id,数据库中也没有数据
session.saveOrUpdate(bb); // 此时的aa和bb实例都会有id,数据库中也可以查到数据,
aa.getBbList() // 值null,获取需要重新查询aa的值
重新查取aa的值优先在session中获取,所以需要先关闭session,再查询。
2.开启了事务
①、②两种情况下,数据库中都没有数据,会存在session
缓存中,只有方法运行完毕,关闭了事务,或者调用session.flush()
方法,数据库中才会有数据。
3. hql IN语句list传参
如果参数中有List则表示有IN语句若每次IN语句的list的size不同则每次查询会被QueryPlanCache视为不同sql语句分别存储有造成内存溢出的风险所以需要对list的size进行格式化。
private Object listFormat(Object param) {
List list = null;
if (param instanceof List) {
list = new ArrayList((List) param);
} else if (param instanceof Set) {
list = new ArrayList((Set) param);
} else {
return param;
}
int size = list.size();
int formatSize = size;
if (size <= 10) {
formatSize = 10;
} else if (size <= 100) {
formatSize = 100;
} else if (size <= 500) {
formatSize = 500;
} else if (size <= 1000) {
formatSize = 1000;
} else if (size <= 10000) {
formatSize = 10000;
} else if (size <= 20000) {
formatSize = 20000;
} else if (size <= 50000) {
formatSize = 50000;
}
while (size < formatSize) {
list.add("|=_=|");
size++;
}
return list;
}
4. sessionFactory.getCurrentSession()报错
- 必须要将使用了
sessionFactory.getCurrentSession()
获取session的代码所在的方法加入到事务管理器
中;否则获取不到session了。 sessionFactory.getCurrentSession()
是要基于事务的,才能实现session生命周期的管理。所以我们查询方法上用个只读事务就ok了。
https://www.cnblogs.com/zeng1994/p/7778145.html
http://blog.csdn.net/honghailiang888/article/details/53423941
5. @Entity 和 @Table的区别
https://www.cnblogs.com/softidea/p/6216722.html
- @Entity 表明是管理的一个实体
Bean
,HQL 语句From tableName
对应该属性值得 name属性值,同时也可以指定数据库中的表名 - Table
name 属性
用于指定数据库中表名
,当与@Entity通存时,以此处name为准 - @SecondaryTable 嵌套类的使用
6. orphanRemoval
https://blog.csdn.net/enthan809882/article/details/103840378?utm_source=distribute.pc_relevant.none-task
这个注解表示是否删除孤立元素,例如映射关系是一对一,或一对多。加上这个注解,即使不设置级联关系,删除一的时候,多的一方肯定是孤立元素了。orphanRemoval = true 这个一般加在一方
7.hql关联对象是不是null的查询
https://blog.csdn.net/linminqin/article/details/6370920?utm_source=blogxgwz4
- hql默认使用inner join 查询不出关联对象为null的数据,需要用的left join
- select a from A a left join a.b b where … 如果没有
select a
查询出来的是List<Object[]>
8.manytomany
9.inverse和cascade
https://www.cnblogs.com/zsping/p/5835765.html
10.Hibernate主键生成策略
主键生成策略
identity(主键自增)、assigned(程序维护)、increment(主键自增,单线程,maxID+1)
GenerateType的四种类型
@Id
// Oracle 数据库会自动是内部序列(fendo_seq)
// mysql 会生成一个中间表 seq_name 来每次获取net_val
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="fendo_seq")
@SequenceGenerator(name="fendo_seq", sequenceName="seq_name")
// Oracle 数据库会自动是内部序列(sequence)
// mysql 会生成一个中间表 hibernate_sequence 来每次获取net_val
@GeneratedValue(strategy = GenerationType.AUTO)
// mysql 生成的表,主键自增
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
11.JPA EntityManager & hibernateTemplate
entityManager、hibernateTemplate
1.
2.
hibernateTemplate 与session 相比,不用自己设置事务,事务的开启与关闭都交给它处理了