引导目录:
前言:
通过上一篇的增删改查小练习之后,咱们大概已经掌握了Hibernate的基本用法。
我们发现,在调用Hibernate API的过程中,虽然Hibernate里面为咱们提供了很多的类,但是常用的类只有很少的那么几个。
下面,一起着重地看一下其中配置相关的类 - Configuration & SessionFactory。
目录:
1. Configuration 类 (负责管理Hibernate的配置信息)
Configuration类负责管理Hibernate的配置信息。
当创建SessionFactory时,Configuration实例可以指定使用哪一个映射文档(xxx.cfg.xml)。
应用程序通常只是创建一个Configuration实例,并通过它创建一个SessionFactory实例。
例如下面的代码:
private static SessionFactory sessionFactory = null; static{ try { sessionFactory = new Configuration().configure().buildSessionFactory(); }catch (HibernateException ex){ throw new RuntimeException("Exception building SessionFacotry: "+ex.getMessage()); } }
当客户端发送一个请求线程时,SessionFactory初始化一个Session(大部分对数据库的操作都调用Session类的API来完成)。
代码如下:
public static final ThreadLocal sessionMap = new ThreadLocal(); public static Session currentSession() throws HibernateException{ Session s = (Session)sessionMap.get(); // 如果此线程还没有打开一个Session,则新建一个 if (s == null) { s = sessionFactory.openSession(); sessionMap.set(s); } return s; }
对于第一次使用Hibernate的初学者来说,下面的这段代码可以说是最常见的使用Configuration的方式了:
Configuration cfg = new Configuration().configure();
Configuration是Hibernate的入口,在新建一个Configuration的实例时(构造),Hibernate会在CLASSPATH环境变量中查找hibernate.properties文件。
如果该文件存在,则将文件的内容加载到内容中,如果不存在,则抛出例外。
.configure() 方法默认会在CLASSPATH环境变量下面寻找hibernate.cfg.xml文件,参见源码, configure() 的内部实现为:
public Configuration configure() throws HibernateException { return this.configure("hibernate.cfg.xml"); }
如果没有找到,系统会打印信息并抛出HibernateException;
如果找到该文件, configure() 方法会首先访问 <session-factory> 配置节点,并获取该元素的name属性;如果非空,将用这个配置的值来覆盖hibernate.properties的hibernate.session_factory_name的配置值。
从这里可以看出,hibernate.cfg.xml中的配置信息可以覆盖hibernate.properties的配置信息。
Configuration的configure()方法还支持带参数的访问形式,可以指定xxx.cfg.xml文件的位置,而不是使用默认的CLASSPATH中设置的hibernate.cfg.xml。
例如:
File file = new File("D:\\configs\\hibernate.cfg.xml"); Configuration cfg = new Configuration().configure(file);
Configuration还提供了一系列方法用来定制Hibernate的加载配置文件的过程,可以让应用更灵活。
常用的有以下几种:
- addProperties(Element)
- addProperties(Properties)
- setProperties(Properties)
- setProperty(String, String)
通过以上的几个方法,除了使用默认的hibernate.properties文件,还可以提供多个.properties配置文件。
使用Hibernate时可以根据不同的情况使用不同的配置文件,例如:
1 Properties p = new Properties(); p.load(new FileInputStream("my.properties")); Configuration cfg = new Configuration().setProperties(p).configure();
除了指定.properties文件外,还可以指定xxx.hbm.xml文件。
下面列出几个常用的方法:
- addClass(Class)
- addFile(File)
- addFile(String)
- addURL(URL)
前面已经讲过,configure()方法默认是通过访问hibernate.cfg.xml的<mapping>元素来加载程序员所提供的xxx.hbm.xml文件。
上面列出的方法可以直接指定xxx.hbm.xml文件,例如,addClass()方法可以直接通过指定Class类加载对应的映射文件,Hibernate会将提供的Class的全名(包括package)自动转化为文件路径。
如com.geeksss.entity.Student.class对应了com/geeksss/entity/Student.hbm.xml。
还可以使用addFile()方法直接指定映射文件,例如下面的例子:
Configuration cfg = new Configuration().addClass(Student.class);
或:
Configuration cfg = new Configuration().addURL(Configuration.class.getResource("Student.hbm.xml"));
或:
Configuration cfg = new Configuration().addFile("Student.hbm.xml");
Configuration提供的这些方法的优点如下:
- 一个应用程序中往往有很多xxx.hbm.xml映射文件,开发的过程中如果只是为了测试某个或几个Java PO (Persistence Object),则没有必要把所有的xxx.hbm.xml都加在到内存中。
这样可以通过addClass()或者addFile()方法直接加载,显得非常灵活。 - 学习Hibernate的过程中,往往需要通过练习来体会Hibernate提供的各种特征,而很多特征是需要修改配置文件的。
如果要观察相同的代码在不同特征下的表现是怎样的,就需要手工修改配置文件,这样太麻烦了,而且容易出错,但是可以提供多个配置文件,每个配置文件针对需要的特征而配置。
在调用程序时,把不同的配置文件作为参数传递进去,而程序代码中使用setProperties()和addFile()指定传入的配置文件参数即可。
2. SessionFactory 类 (负责创建Session的实例)
SessionFactory负责Session实例的创建。
为了能创建一个Session对象,必须在Hibernate初始化时创建一个Configuration类的实例,并将已经写好的映射文件交由它处理。
这样,Configuration对象就可以创建一个SessionFactory对象,当SessionFactory对象创建成功之后,Configuration对象就没有用了,可以简化的抛弃它。
例如下面的示例代码:
Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory();
SessionFactory是线程安全的,可以被多线程调用以取得Session,而且构造SessionFactory很消耗资源。
所以多数情况下一个应用中之初始化一个SessionFactory,为不同的线程提供Session。