不是不hibernate版本问题,你的事5.x版本吧。看到用了StandardServiceRegistryBuilder
老师用的是4.X版本,大版本更新有区别的
Session在创建时会分配得一个独一无二的hashcode码,可用此来区分是否是同一个Siession,在关闭后此hashcode码会消失,事务提交后加一个 if(!session.isOpen()),可以判断session是否会自动关闭
transaction.commit();
if(!session.isOpen())
{
System.out.println("session已关闭");
}
资料查的,共同学习
openSession()每次创建一个session对象,需要手动关闭,不关闭提交过多后连接池溢出.
getCurrentSession()每次创建的是同一个session对象,自动关闭,
通过getCurrentSession获得的是当前的对话,hash code是一样的
测试类贴出来。
同感,我也心疼老师并且,身为小白这种免费精品课,,真的是,福音啊.....
框架自动调用的,只需要获取就可以了
因为你的数据库名字不是hibernate.STUDENTS
Junit是作用于单个方法的测试,相对main方法来说,对于模块化的测试的效率更高,因为在main方法中测试的话需要加载其他所有关联的方法,增加了代码量,而使用Junit则只需要为需要测试的方法添加标签就可以对目标方法进行测试。
重新生成以下Students的xml配置文件
doWork()方法中的参数是Connection链接对象。session在链接中充当的是Connection对象。当你openSession()的时候,doWork()就能够获取Connection对象。主要原因还是openSession()方法打开的session需要手动关闭。
这与session的生成方式有关。一般使用单例模式进行生成,可以不用手动的释放资源。
你好,我试了一你的下代码是没有问题的,hashcode是相同的。你看看是不是运行的不是这个方法,还是看错地方了
@Test public void testSaveStudentWithGetCurrentSession(){ Configuration config = new Configuration().configure(); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); Session session1 = sessionFactory.getCurrentSession(); Transaction t = session1.beginTransaction(); Student s = new Student(1,"张三","男",new Date(),"北京"); session1.doWork(new Work(){ @Override public void execute(Connection conn) throws SQLException { System.out.println("connection hasCode:"+conn.hashCode()); } }); session1.save(s); t.commit(); Session session2 = sessionFactory.getCurrentSession(); t = session2.beginTransaction(); s = new Student(2,"李四","男",new Date(),"上海"); session2.doWork(new Work(){ @Override public void execute(Connection conn) throws SQLException { System.out.println("connection hasCode:"+conn.hashCode()); } }); session2.save(s); t.commit(); }
配置文件
<hibernate-configuration> <session-factory> <property name="connection.username">root</property> <property name="connection.password">12721931</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql:///hibernate?useUnicode=true&characterEncoding=UTF-8</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="hibernate.default_schema">hibernate</property> <property name="hbm2ddl.auto">create</property> <property name="hibernate.current_session_context_class">thread</property> <mapping resource="Student.hbm.xml"/> </session-factory> </hibernate-configuration>
运行结果
connection hasCode:737077247 Hibernate: insert into hibernate.STUDENT (NAME, GENDER, BIRTHDAY, ADDRESS, SID) values (?, ?, ?, ?, ?) connection hasCode:335359181 Hibernate: insert into hibernate.STUDENT (NAME, GENDER, BIRTHDAY, ADDRESS, SID) values (?, ?, ?, ?, ?)
不是,如下图源码,openSession每次都会创建新的SessionImpl的对象,而不会调用以前的session,所以和getCurrentSession不一样。
从上课的内容来说,openSession()方法实际上是打开一个新的session,在原有session关闭的情况下会使用原有的connection对象,这时两次输出的hashcode是相同的。
而getCurrentSession()方法是调用原有的session,在第一个session提交事务后会自动释放占有的资源,这时第二个session就会使用原来第一个session使用的connection,两次输出的hashcode相同。
当getCurrentSession()方法同时创建两个session时,从实验来看,用的是同一个connection,输出的hashcode是先相同的。
getCurrentSession()是单例操作,会在事务提交或者回滚之后会自动关闭,因此getCurrentSession()获取的session对象是同一个session对象
如果多用户同时对数据库进行操作,那么肯定是按流程来,session对象只创建一个,谁先提交事务,谁拿。用完放回去,下一个用户,继续拿着用
不会的
getCurrentSession1 connection hashCode1648001170 Hibernate: insert into STUDENTS (NAME, GENDER, BIRTHDAY, ADDRESS, SID) values (?, ?, ?, ?, ?) getCurrentSession2 connection hashCode1648001170 Hibernate: insert into STUDENTS (NAME, GENDER, BIRTHDAY, ADDRESS, SID) values (?, ?, ?, ?, ?)
我试了一下你的代码,上面是运行结果,是一样的
废话啊,本来就是为了证明,利用opensession()的方法不会自动关闭会话会生成不同的连接,占用连接池,你关闭第一个session,第二个session相当于重新占用了session1的连接池空间啊,hashCode就一样啊
仔细找找,看哪块错了
我用的是这样子的 感觉还行
对,2个opensession,我敢肯定你关闭的一定是第一个session会话,这就证明了老师所说的:opensession不能自动关闭,而getCurrentSession()能自动关闭,因为,如果自动(或手动关闭)session的话。下次再进行connection对象的时候hashcode值一定是相同的。你可以再看看老师的视频