Hibernate 5学习笔记(四)

深夜里的一盏灯,要是昏黄的,有一个带着眼镜的孩子,正在奋笔疾书,那不是写代码是在写世界。好啦,回到正题,通常如果单标签操作都是比较容易上手的,但是涉及到多表就会让头发感到畏惧和无奈。所以,为了我们乌黑靓丽的头发,用Hibernate的注解一定太符合人心。

一、这些注解要注意

@OnetoOne,关联的一方才设置*/

@OneToOne(cascade=CascadeType.ALL)

@JoinColumn(name="外键列名",referencedColumnName="参考的另一个表中的哪一列",unique=true)

/**双向一对一,就是用主键关联。被关联的一方不需要设置@OnetoOne,关联的一方才设置其余属性照常*/

/**无外键关联方一般外键维护是交给有外键的关联方并且这边就不需要些joinColumn了*/

@OneToOne(mappedBy="另一方中关联本方的属性名,将外键维护交给对方",cascade=CascadeType.ALL)

/**有外键的关联方*/

@OneToOne(cascade=CascadeType.ALL)

@JoinColumn(name="外键列名",referencedColumnName="参考的另一个表中的哪一列(可不写)",unique=true)

//表示唯一性 多对多注解(因为外联的是中间表,一般级联操作都是all,就算是删除也是删除中间表中的属性) 例如学生对课程,这边是学生。

扫描二维码关注公众号,回复: 5388113 查看本文章
Path<Object> path = root.get("字段名");
CriteriaBuilder.In<Object> in = criteriaBuilder.in(path);
in.value(OrderRefund.Status.pending);
in.value(OrderRefund.Status.approved);
in.value(OrderRefund.Status.received);
in.value(OrderRefund.Status.receiveing);
restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.and(in));

二、Hibernate难道根据实体类来做事情的,一定要丢一个PO类给它吗?

答案是没错,是的,丢一个数字,字符串是想做啥子?人家Hibernate本来就是靠Entity持久化对象去数据库做数据持久化的操作。

Unknown entity: java.lang.Integer; nested exception is org.hibernate.MappingException: Unknown entity: java.lang.Integer
org.springframework.orm.hibernate5.HibernateSystemException: Unknown entity: java.lang.Integer; nested exception is org.hibernate.MappingException: Unknown entity: java.lang.Integer
	at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:302)
	at org.springframework.orm.hibernate5.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:102)
	at org.springframework.orm.hibernate5.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:73)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy39.deleteIdea(Unknown Source)
	at com.test.test.service.impl.TestServantImpl.delete(TestServantImpl.java:111)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.qq.tars.server.core.ServantHomeSkeleton.invoke(ServantHomeSkeleton.java:50)
	at com.qq.tars.server.core.TarsServantProcessor.process(TarsServantProcessor.java:107)
	at com.qq.tars.net.core.nio.WorkThread.run(WorkThread.java:80)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.MappingException: Unknown entity: java.lang.Integer
	at org.hibernate.metamodel.internal.MetamodelImpl.entityPersister(MetamodelImpl.java:670)
	at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1692)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:219)
	at org.hibernate.event.internal.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:38)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
	at org.hibernate.internal.SessionImpl.fireUpdate(SessionImpl.java:733)
	at org.hibernate.internal.SessionImpl.update(SessionImpl.java:725)
	at org.hibernate.internal.SessionImpl.update(SessionImpl.java:720)
	at com.test.test.service.impl.TestServantImpl.TestDaoImpl.delete(TestDaoImpl.java:95)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceException

四、java中的BigInteger和Integer有什么区别?

BigInteger被称为大整数类,而Integer是整数类。BigInteger能够存取比Long更大的整数,可以任意大小。

Hibernate在获取数据的总数时候,count(函数)在数据 返回Long对象,这样就需要使用BigInteger。要类比其他的函数

MAX MIN 返回类型是跟所使用的字段类型有关 
AVG 返回Double 
SUM 如使用字段是整形,返回Long(以前是返回BigInteger),如果是浮点类型那么就返回Double.

在使用select count()之后拿到的对象,居然先判断是Long类型还是Integer类型。

五、Hibernate的批处理

我想应该是有针对批处理进行操作的API但是,官方文档的批操作也不过是设置了属性hibernate.jdbc.batch_size(在要求驱动程序执行批处理之前,控制Hibernate将批处理的最大语句数)后,用for循环来保存。当然在保存前他进行了刷新和清除缓存的操作。

    int batchSize = 25;

	for ( int i = 0; i < entityCount; i++ ) {
		if ( i > 0 && i % batchSize == 0 ) {
			//flush a batch of inserts and release memory
			entityManager.flush();
			entityManager.clear();
		}

		Person Person = new Person( String.format( "Person %d", i ) );
		entityManager.persist( Person );
	}

	txn.commit();

六、getCurrentSession与OpenSession的区别

这两货都是用来创建session的,但是区别在于

  1. getCurrentSession创建的session会放在当前的线程中,而openSession不会
  2. getCurrentSession创建的Session会在commit和t或rollback后会自动关闭,而openSession需要手动关闭
  3. 使用Spring来托管session选用getCurrentSession为较好的选择。其使用的是Hibernate上下文中的Session,没有就创建,有就用的同一个session,适用于单线程。毕竟session是线程不安全的,如果是在多线程的环境为每一个请求创建一个全新的session用openSesion可好。

七、Hibenate的statelessSsession(了解)

StatelessSession statelessSession = null;
Transaction txn = null;
ScrollableResults scrollableResults = null;
try {
	SessionFactory sessionFactory = entityManagerFactory().unwrap( SessionFactory.class );
	statelessSession = sessionFactory.openStatelessSession();

	txn = statelessSession.getTransaction();
	txn.begin();

	scrollableResults = statelessSession
		.createQuery( "select p from Person p" )
		.scroll(ScrollMode.FORWARD_ONLY);

	while ( scrollableResults.next() ) {
		Person Person = (Person) scrollableResults.get( 0 );
		processPerson(Person);
		statelessSession.update( Person );
	}
  • StatelessSession没有缓存,通过StatelessSession来加载、保存或更新后的对象处于游离状态
  • StatelessSession不会与Hibernate的二级缓存交互
  • 当调用StatelessSession的save()、update()或delete()方法时,这些方法会立即执行相应的SQL语句,而不会仅计划执行一条SQL语句
  • StatelessSession不会进行脏检查,因此修改了Customer对象属性后,还需要调用StatelessSession的update()方法来更新数据库中数据
  • StatelessSession不会对关联的对象进行任何的级联操作
  • 通过同一个StatelessSession对象两次加载的OID为1的Customer对象,得到的两个对象内存地址不同
  • StatelessSession所做的操作可以被Interceptor拦截器捕获到,但是会被Hibernate的事件处理系统忽略掉。

八、了解Hibernate的缓存机制

Hibernate是有两级缓存的,一级缓存是Session,当实体被管理 ,该对象就会被添加到Session中。首先去缓存中看是否存在,如果不存在,再去数据库中查询 , 这就是hibernate的一级缓存(session缓存)。session级别的,所以如果session关闭后,缓存就没了,此时就会再次发sql去查数据库。

二级缓存是由sessionFactory级别的,SessionFactory对象的生命周期和应用程序的整个过程对应,因此第二级缓存是进程范围或者集群范围的缓存。但是他需要额外配置,需要额外的的二级缓存包,在配置文件里配置。并且二级缓存的使用策略有:read-only、nonstrict-read-write、read-write、transactional。注意:我们通常使用二级缓存都是将其配置成 read-only ,即我们应当在那些不需要进行修改的实体类上使用二级缓存,否则如果对缓存进行读写的话,性能会变差,这样设置缓存就失去了意义。

简单到这里,Hibernate的缓存机制是值得深入学习的。

猜你喜欢

转载自blog.csdn.net/LCF_lxf_ldy/article/details/85136182
今日推荐