Hibernate学习笔记(二)基本配置

Hibernate可以使用XML档案或properties档案来配置SessionFactory,默认的配置文件名称为hibernate.cfg.xml或hibernate.properties,使用下面的方式来读入文件以配置Hibernate:

Configurationconfig = new Configuration().configure();

当您使用new建构Configuration对象时,会读取Classpath路径下的 hibernate.properties,如果您呼叫Configuration的configure()方法没有指定路径与文件名时,则会再读取Classpath路径下的hibernate.cfg.xml,如果有与hibernate.properties相同的属性设定,则hibernate.cfg.xml中的设定会覆盖hibernate.properties中的设定。


默认的XML配置文件名称是hibernate.cfg.xml,您也可以自行指定档案路径与名称,例如:

Configuration config = newConfiguration().configure("/config/db.cfg.xml");

在取得Configuration实例后,您还可以撰写程序的方式来设定新的属性,或甚至读入另一个HBM配置文件案,例如:

Configuration config = new Configuration
                             .configure()
                             .setProperty(Environment.FORMAT_SQL,"true")
                            .addResource("Room.hbm.xml");

所有的属性设定,在Hibernate中都对应于Environment类别中的一个静态成员,例如format_sql就对 应于Enviromnent.FORMAT_SQL,connection.driver_class就对应于Environment.DRIVER。


为了配置文件时更有弹性,您可以使用系统属性来指定,例如在hibernate.cfg.xml中撰写:

...
 

 <property name="show_sql">${displaysql}</property>
    <!-- 将显示的SQL排版,方便观看 -->
...


如此,若在启动Java时,加上-Ddisplaysql=true,则可观看到产生的SQL语句。

使用属性档案进行配置时,文件名是hibernate.properties,必须放置在Classpath之下,一个例子如下:

  • hibernate.properties

hibernate.show_sql = true
hibernate.format_sql = true
hibernate.dialect = org.hibernate.dialect.MySQLDialect 
hibernate.connection.driver_class = com.mysql.jdbc.Driver 
hibernate.connection.url = jdbc:mysql://localhost/demo
hibernate.connection.username = caterpillar 
hibernate.connection.password = 123456

由于properties档案中不包括映像文件的名称,为了要取得对象至资 料库表格的映像文件,您必须在程序中如下加载:

Configuration cfg = new Configuration().addClass(User.class).addClass(Room.class);

第一个addClass()加入位于Classpath根目录下的User.hbm.xml,第二个addClass()加入Room类别的映像文件,该 文件必须位于与User类别同一个目录,也就是/Room.hbm.xml。

在Hibernate下载文件中的etc目录下,有hibernate.cfg.xml与hibernate.properties可供设定参考。

Configuration的实例管理Hibernate的配置讯息,通常用于建立SessionFactory,例如:

SessionFactory sessionFactory =config.buildSessionFactory();
SessionFactory一旦建立,就被赋予当时Configuration的配置讯息,之后您改变Configuration并不会影响已建立的 SessionFactory实例,如果对Configuration改动后,则要建立一个新的SessionFactory实例,新的实例中会包括新的配置讯息, SessionFactory是被设计为「线程安全的」(Thread-safe)。


每个内建的Hibernate类型,在 org.hibernate.Hibernate类别中都有对应的常数,例如Hibernate.STRING。基本上,Hibernate会使用 Reflection自动找出属性的数据型态,所以type属性在使用POJO时可以省略不设,如果有特别设定,则Hibernate就不用使用 Reflection来找出类型,不过在使用 态模型(Dynamic Model,type属性则是必须设定的,用以得知动态模型中应放入哪种类型的对象。

<generator>设定主键的生成方式,可以设定"native"表示由Hibernate自动根据Dialect选择 采用 identity、hilo、sequence等作为主键生成方式,也可以考虑采用uuid由Hibernate根据128位UUID算法(128- bit UUID algorithm)生成16进位制数值,并编码为32位长度的字符串,还有其它的主键生成方式,可以参考官方手册的Generator 说明。

您可以在<hibernate-mapping>上设定package属性,如此一来,文件中要设置类别名称时,就不用写出完整的package,例如:

<hibernate-mapping package="onlyfun.caterpillar">
    <!--类别名称与表格名称映像-->
    <classname="User" table="user">
       ....
   </class> 
</hibernate-mapping>

在使用HQL时,您可以只使用类别名称来替代完整名称:

// 相当于写"from onlyfun.caterpillar.User"
Query query = session.createQuery("fromUser"); 
这是Hibernate的auto-import功能,然而如果在不同的package下都有User类别,则Hibernate将无从得知是要使用哪个User类别,您可以在<hibernate-mapping>上设定auto-import属性为false,关闭auto-import功能,并在HQL中撰写完整的类别名称。


另一种解决的方式,是在<hibernate-mapping>中使用<import>设定别名,例如:

<hibernate-mapping> 
    <importclass="onlyfun.caterpillar.User" rename="DemoUser"/>
</hibernate-mapping>

之后在指定HQL中,即可使用这个别名:

Query query = session.createQuery("from DemoUser"); 

对于一些不能为空的属性,可以在<property>上加上not-null属性为true,如此Hibernate可以直接检查属性是否为null,而不用等进入到数据库中再作检查。


如果有某个属性,其值取决于表格字段自己产生的值,而非程序中主动设定的值,例如数据新增时,会由数据库产生新增时的时间,而这个值想要主动提取至对象的对应属性,则可以在<property>上设定generated属性,例如:

...   

 <propertyname="time" column="time" 
             insert="false" update="false"generated="always"/>
...


如上设定之后,当对象储存时,time属性并不会参与储存,而是由数据库产生time域值,再SELECT出来设定给time属性,由于并非实际要储存属性,所以设定insert为false,而由于这个字段由数据库维护,所以update设定为false。

如果对象上有个属性,实际上并没有字段与之对应,您只是想借由数据库中的字段查询来取得,例如使用COUNT函式来取得所有的笔数,则您可以使用formula属性,例如:

... 

   <propertyname="average" formula="(SELECT AVG(u.age) FROM T_USERu)"/>
...

 


发布了50 篇原创文章 · 获赞 1 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章