(二)hibernate进阶
1.hibernate.cfg.xml常用配置
以上节代码为例
<session-factory> <property name="connection.username">root</property> <property name="connection.password">123</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="hbm2ddl.auto">create</property> <mapping resource="Students.hbm.xml" /> </session-factory>
hbm2ddl.auto:如何将数据生成的表插入数据库
create:覆盖原表(删除原表,重新生成)
update:更新(原有的表结构不会被删除)
create-drop:先生成,后删除。
validate:将现有的表结构和原有的表结构进行验证,如果不同,就不创建新的表结构。
default_schema:填写数据库名
生成的SQL语句中会在表名和表结构之前加上数据库名。
2.session简介
首先要明白Hibernate是对JDBC的一个封装,所以不建议使用jdbc的connection操作数据库,而是通过使用session操作数据库。 2.1. 所以Session可以理解为操作数据库的对象。要使用Hibernate操作数据库,就先要获得Session的实例。 2.2. session与connection,是多对一的关系。每个session都有一个与之对应的connection,一个connection不同时刻可以供多个session使用。 2.3. 把对象保存在关系数据库中需要调用session的各种方法,如:save(),update(),delete(),createQuery()等。
要特别注意的是:当执行某一个Session对象的方法时,必须要开启一个事务。也就是说,这些方法要封装在事务中。在执行这些方法之后要提交事务,再关闭Session。
结合上节代码:
package hibernate_01; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; //测试的源程序要写在新建的Source Folder里 //测试类 public class StudentsTest { private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before public void init(){ //创建配置对象 Configuration config =new Configuration().configure(); //创建服务注册对象 ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); //创建会话工厂对象 sessionFactory=config.buildSessionFactory(serviceRegistry); //会话对象 session =sessionFactory.openSession(); //开启事务 transaction =session.beginTransaction(); } @After public void destory(){ transaction.commit();//提交事务 session.close();//关闭会话 sessionFactory.close();//关闭会话工厂 } @Test public void testSaveStudents(){ //生成学生对象 Students s=new Students(1,"张三","男",new Date(),"山东"); //保存对象进数据库 session.save(s); } }
3.transaction简介
3.1 hibernate默认不自动提交事务,将<2.session简介>中测试类 StudentsTest 中的的事务相关代码注释
//开启事务 //transaction =session.beginTransaction();
@After public void destory(){ //transaction.commit();//提交事务
运行后控制台如下输出(没有insert 代码)
说明表输入失败
要想不开启事务向数据库加入数据,可采用如下方法:
在save()方法之前带调用doWork()方法,重写其execute()方法,设置自动提交,最后不要忘了session提交后用flush()方法强制输出sql语句。
@Test public void testSaveStudents(){ //生成学生对象 Students s=new Students(1,"张三","男",new Date(),"山东"); session.doWork(new Work(){ @Override public void execute(Connection connection) throws SQLException { // TODO Auto-generated method stub connection.setAutoCommit(true); } }); //保存对象进数据库 session.save(s); //强制输出sql语句 session.flush(); }
控制台输出sql语句,表结构创建完成。
4.session详解
4.1. 获得session对象的两种方法
package hibernate_01; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry;//不要导错了 import org.hibernate.service.ServiceRegistryBuilder; import org.junit.Test; public class SessionTest { //为方便,将所有方法写在@Test里 @Test public void testOpenSession(){ //获得配置对象 Configuration config = new Configuration().configure(); //获得服务注册对象 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); //获得sessionFactory对象 SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); //获得session对象 Session session =sessionFactory.openSession(); if(session!=null){ System.out.println("session创建成功!"); }else{ System.out.println("session创建失败!"); } } @Test public void testGetCurrentSession(){ //获得配置对象 Configuration config = new Configuration().configure(); //获得服务注册对象 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); //获得sessionFactory对象 SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); //获得session对象 Session session =sessionFactory.getCurrentSession(); if(session!=null){ System.out.println("session创建成功!"); }else{ System.out.println("session创建失败!"); } } }
getCurrentSession配置本地事务(在hibernate.cfg.xml文件中进行配置 )
<propertyname="hibernate.current_session_context_class">thread</property>
4.2.两种方法的区别
4.2.1 验证openSession()方法创建对象hashCode不同
@Test public void testSaveStudentsWithOpenSession(){ //获得配置对象 Configuration config = new Configuration().configure(); //获得服务注册对象 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); //获得sessionFactory对象 SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); //获得session对象 Session session1=sessionFactory.openSession(); //开启事务 Transaction transaction = session1.beginTransaction(); //生成一个学生对象 Students s=new Students(1,"李四","男",new Date(),"北京"); session1.doWork(new Work(){ @Override public void execute(Connection connection) throws SQLException { // TODO Auto-generated method stub System.out.println("connection hashCode:" +connection.hashCode()); } }); session1.save(s); // session1.close(); transaction.commit();//提交事务 Session session2=sessionFactory.openSession(); transaction = session2.beginTransaction(); s=new Students(2,"王五","男",new Date(),"武汉");//表的主键问题要主意 session2.doWork(new Work(){ @Override public void execute(Connection connection) throws SQLException { // TODO Auto-generated method stub System.out.println("connection hashCode:" +connection.hashCode()); } }); session2.save(s); transaction.commit();//提交事务 }
4.2.2 创建 session方式不同
Session session1 =sessionFactory.openSession();
Session session2 =sessionFactory.openSession(); System.out.println(session1==session2); //false
Session session1 =sessionFactory.getCurrentSession(); Session session2 =sessionFactory.getCurrentSession(); System.out.println(session1==session2); //true
5.对象关系映射(hbm文档)常用配置
5.1 mapping标签
5.2 class标签
5.3 id标签
5.4 主键生成策略