第一部分 - 第一个Hibernate程序
首先我们将创建一个简单的控制台(console-based)Hibernate程序。我们使用内置数据库(in-memory database) (HSQL DB),所以我们不必安装不论什么数据库server。
让我们如果我们希望有一个小程序能够保存我们希望关注的事件(Event)和这些事件的信息。 (译者注:在本教程的后面部分,我们将直接使用Event而不是它的中文翻译“事件”,以免混淆。)
我们做的第一件事是建立我们的开发文件夹,并把全部须要用到的Java库文件放进去。 从Hibernate站点的下载页面下载Hibernate分发版本号。 解压缩包并把/lib以下的全部库文件放到我们新的开发文件夹以下的/lib文件夹以下。 看起来就像这样:
. +lib antlr.jar cglib-full.jar asm.jar asm-attrs.jars commons-collections.jar commons-logging.jar ehcache.jar hibernate3.jar jta.jar dom4j.jar log4j.jar
This is the minimum set of required libraries (note that we also copied hibernate3.jar, the main archive) for Hibernate. See the README.txt file in the lib/ directory of the Hibernate distribution for more information about required and optional third-party libraries. (Actually, Log4j is not required but preferred by many developers.) 这个是Hibernate执行所须要的最小库文件集合(注意我们也拷贝了Hibernate3.jar,这个是最重要的库)。 能够在Hibernate分发版本号的lib/文件夹下查看README.txt,以获取很多其它关于所需和可选的第三方库文件信息 (其实,Log4j并非必须的库文件可是很多开发人员都喜欢用它)。
接下来我们创建一个类,用来代表那些我们希望储存在数据库里面的event.
2.2.1. 第一个class
我们的第一个持久化类是 一个简单的JavaBean class,带有一些简单的属性(property)。 让我们来看一下代码:
import java.util.Date; public class Event { private Long id; private String title; private Date date; Event() {} public Long getId() { return id; } private void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
你能够看到这个class对属性(property)的存取方法(getter and setter method) 使用标准的JavaBean命名约定,同一时候把内部字段(field)隐藏起来(private visibility)。 这个是个受推荐的设计方式,但并非必须这样做。 Hibernate也能够直接訪问这些字段(field),而使用訪问方法(accessor method)的优点是提供了程序重构的时候健壮性(robustness)。
id 属性(property) 为一个Event实例提供标识属性(identifier property)的值- 假设我们希望使用Hibernate的全部特性,那么我们全部的持久性实体类(persistent entity class)(这里也包含一些次要依赖类) 都须要一个标识属性(identifier property)。而其实,大多数应用程序(特别是web应用程序)都须要识别特定的对象,所以你应该 考虑使用标识属性而不是把它当作一种限制。然而,我们通常不会直接操作一个对象的标识符(identifier), 因此标识符的setter方法应该被声明为私有的(private)。这样当一个对象被保存的时候,仅仅有Hibernate能够为它分配标识符。 你会发现Hibernate能够直接訪问被声明为public,private和protected等不同级别訪问控制的方法(accessor method)和字段(field)。 所以选择哪种方式来訪问属性是全然取决于你,你能够使你的选择与你的程序设计相吻合。
全部的持久类(persistent classes)都要求有无參的构造器(no-argument constructor); 由于Hibernate必需要使用Java反射机制(Reflection)来实例化对象。构造器(constructor)的訪问控制能够是私有的(private), 然而当生成执行时代理(runtime proxy)的时候将要求使用至少是package级别的訪问控制,这样在没有字节码编入 (bytecode instrumentation)的情况下,从持久化类里获取数据会更有效率一些。
我们把这个Java源码文件放到我们的开发文件夹以下一个叫做src的文件夹里。 这个文件夹如今应该看起来像这样:
. +lib <Hibernate and third-party libraries> +src Event.java
在下一步里,我们将把这个持久类(persisten class)的信息通知Hibernate
2.2.2. 映射文件
Hibernate须要知道如何去载入(load)和存储(store)我们的持久化类的对象。这里正是Hibernate映射文件(mapping file)发挥作用的地方。 映射文件告诉Hibernate它应该訪问数据库里面的哪个表(table)和应该使用表里面的哪些字段(column)。
一个映射文件的基本结构看起来像这样:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> [...] </hibernate-mapping>
注意Hibernate的DTD是很复杂的。 你能够在你的编辑器或者IDE里面使用它来自己主动提示并完毕(auto-completion)那些用来映射的XML元素(element)和属性(attribute)。 你也能够用你的文本编辑器打开DTD-这是最简单的方式来浏览全部元素和參数,查看它们的缺省值以及它们的凝视,以得到一个总体的概观。 同一时候也要注意Hibernate不会从web上面获取DTD文件,尽管XML里面的URL或许会建议它这样做,可是Hibernate会首先查看你的程序的classpath。 DTD文件被包含在hibernate3.jar,同一时候也在Hibernate分发版的src/路径下。
在以后的样例里面,我们将通过省略DTD的声明来缩短代码长度。可是显然,在实际的程序中,DTD声明是必须的。
在两个hibernate-mapping标签(tag)中间, 我们包括了一个 class元素(element)。全部的持久性实体类(persistent entity classes)(再次声明, 这里也包括那些依赖类,就是那些次要的实体)都须要一个这种映射,来映射到我们的SQL database。
<hibernate-mapping> <class name="Event" table="EVENTS"> </class> </hibernate-mapping>
我们到如今为止做的一切是告诉Hibernate如何从数据库表(table)EVENTS里持久化和 载入Event类的对象,每一个实例相应数据库里面的一行。如今我们将继续讨论有关唯一标识属性(unique identifier property)的映射。 另外,我们不希望去考虑如何产生这个标识属性,我们将配置Hibernate的标识符生成策略(identifier generation strategy)来产生代用主键。
<hibernate-mapping> <class name="Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="increment"/> </id> </class> </hibernate-mapping>
id元素是标识属性(identifer property)的声明, name="id" 声明了Java属性(property)的名字 - Hibernate将使用getId()和setId()来訪问它。 字段參数(column attribute)则告诉Hibernate我们使用EVENTS表的哪个字段作为主键。 嵌套的generator元素指定了标识符的生成策略 - 在这里我们使用increment,这个是很easy的在内存中直接生成数字的方法,多数用于測试(或教程)中。 Hibernate同一时候也支持使用数据库生成(database generated),全局唯一性(globally unique)和应用程序指定(application assigned) (或者你自己为不论什么已有策略所写的扩展) 这些方式来生成标识符。
最后我们还必须在映射文件中面包含须要持久化属性的声明。缺省的情况下,类里面的属性都被视为非持久化的:
<hibernate-mapping> <class name="Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="increment"/&
洛谷P1433吃奶酪(正向暴力递归,回溯更新)
洛谷P1434滑雪(逆向图的遍历搜索递归+记忆化,最长路问题)
洛谷P1192台阶问题(逆向递推递归dfs+记忆化)
洛谷p1025数的划分(正向暴力递归,数学排列与组合问题)
洛谷P1141 01迷宫(图的遍历搜素递归dfs或bfs,连痛块回溯更新问题,记忆化或者并查集根结点)
Git 版本更新--Windows
plop-templates自动新建项目文件
前端-随机生成测试数据-mockjs
cookie、seseionStorage、localStorage的区别