At line 1 changed 1 line. |
__Part I:__ [在AppFuse建立DAO和对象|CreateDAO_zh] - 一个建立对象(代表数据库的表)和把这些对象存储到数据库的Java类的教程。 |
__Part I:__ [在AppFuse建立DAO和POJO |CreateDAO_zh] - 一个建立对象(代表数据库的表)和把这些对象存储到数据库的Java类的教程。 |
At line 3 changed 2 lines. |
!!About this tutorial |
This tutorial will show you how to create a new table in the database, and how the create Java code to access this table. |
!!关于本教程 |
本教程将向你展示如何在一个数据库里创建表,以及如何完成访问这些表的Java代码。 |
At line 6 changed 1 line. |
We will create an object and then some more classes to persist (save/retrieve/delete) that object from the database. In Java speak, we call the object a Plain Old Java Object (a.k.a. a [POJO|http://forum.java.sun.com/thread.jsp?forum=92&thread=425300&tstart=0&trange=15]). This object basically represents a database table. The ''other classes'' will be: |
我们将建立一个对象以及处理(保存/检索/删除)这些类到数据库的一些代码。用Java术语,我们叫它Plain Old Java Object(a.k.a. a [POJO|http://forum.java.sun.com/thread.jsp?forum=92&thread=425300&tstart=0&trange=15])。这个对象通常代表了数据库中的一个表,''其他的类''包括: |
At line 8 changed 2 lines. |
* A Data Access Object (a.k.a. a [DAO|http://java.sun.com/blueprints/patterns/DAO.html]), an [Interface|http://java.sun.com/docs/books/tutorial/java/concepts/interface.html] and a Hibernate Implementation |
* A [JUnit|http://www.junit.org] class to test our DAO is working |
* 一个数据访问对象Data Access Object (a.k.a. a [DAO|http://java.sun.com/blueprints/patterns/DAO.html]), 一个 [Interface|http://java.sun.com/docs/books/tutorial/java/concepts/interface.html]和一个Hibernate实现 |
* 一个 [JUnit|http://www.junit.org] 类来测试我们的DAO对象 |
At line 11 changed 1 line. |
%%note __NOTE:__ If you're using MySQL and you want to use transactions (which you probably will) you have to use InnoDB tables. To do this, add the following to your mysql configuration file ({{/etc/my.cnf}} or {{c:\Windows\my.ini}}). The 2nd setting (for a UTF-8 character set) is needed for 4.1.7+. |
%%note __NOTE:__ 如果你使用MySQL并且希望使用事务 (很有可能是这个情况),你需要使用InnoDB tables,为了做到这一点, 添加以下两句话到 ({{/etc/my.cnf}} 或者 {{c:\Windows\my.ini}})。 其中第二个设置 (设置使用UTF-8字符)是4.1.7+所必需的。 |
At line 17 changed 1 line. |
If you're using PostgreSQL and you get confusing errors about batch processing, try turning it off by adding {{<prop key="hibernate.jdbc.batch_size">0</prop>}} to your {{src/dao/**/hibernate/applicationContext-hibernate.xml}} file. |
如果你使用PostgreSQL并且在成批处理时得到许多迷惑的错误,试着把关闭它,方法是增加 {{<prop key="hibernate.jdbc.batch_size">0</prop>}} 到你的 {{src/dao/**/hibernate/applicationContext-hibernate.xml}}文件。 |
At line 20 changed 1 line. |
AppFuse uses [Hibernate|http://www.hibernate.org] for its default persistence layer. Hibernate is an Object/Relational (O/R) Framework that allows you to relate your Java Objects to database tables. It allows you to very easily perform CRUD (Create, Retrieve, Update, Delete) on your objects. |
AppFuse使用[Hibernate|http://www.hibernate.org] 作为持久化层, Hibernate是一套对象/关系Object/Relational (O/R)框架,他允许你把Java对象和数据库之间联系起来,它可以很方便的对你的对象执行CRUD (Create, Retrieve, Update, Delete)操作。 |
At line 22 changed 1 line. |
;:''You can also use [iBATIS|http://ibatis.com] as a persistence framework option. To install iBATIS in AppFuse, view the README.txt in {{extras/ibatis}}. If you're using iBATIS over Hibernate, I expect you have your reasons and are familiar with the framework. I also expect that you can figure out how to adapt this tutorial to work with iBATIS. ;-)'' |
;:''你也可以选择使用[iBATIS|http://ibatis.com]作为持久化层,如果要在AppFuse里安装iBATIS, 请查看{{extras/ibatis}}中的README.txt。如果你选择iBATIS而不是Hibernate, 希望你有自己的原因并且熟悉这个框架,我也希望你能够领会到如何将教程应用到iBATIS ;-)'' |
At line 24 changed 4 lines. |
!Font Conventions (work in progress) |
;:Literal strings intended to be executed at the command prompt look like this: __ant test-all__. |
;:References to files, directories and packages which exist in your source tree: <font size="2">{{build.xml}}</font>. |
;:%%(color: blue)''And suggestions for how to do stuff in the "Real World" are in blue italics.''%% |
!字体惯例 (进行中) |
;:要在命令行下执行的命令是这个样子: __ant test-all__. |
;:对目录或者包中的文件的引用是这个样子: <font size="2">{{build.xml}}</font>. |
;:%%(color: blue)''我在真实世界中实际操作的方式用蓝色斜体表示。''%% |
At line 29 changed 1 line. |
Let's get started on creating a new Object, DAO and Test in AppFuse's project structure. |
让我们继续在AppFuse项目的结构下创建一个新的对象、DAO和测试。 |
At line 31 changed 7 lines. |
!Table of Contents |
* [1] Create a new Object and add [XDoclet|http://xdoclet.sf.net] tags |
* [2] Create a new database table from the object using Ant |
* [3] Create a new DaoTest to run JUnit tests on the DAO |
* [4] Create a new DAO to perform CRUD on the object |
* [5] Configure Spring for the Person object and PersonDao |
* [6] Run the DaoTest |
!目录 |
* [1] 建立一个对象,并且作[XDoclet|http://xdoclet.sf.net]标记 |
* [2] 使用Ant根据对象建立数据库中的表 |
* [3] 创建一个DaoTest来运行DAO对象的JUnit测试 |
* [4] 创建一个新的DAO来执行关于这个对象的CRUD操作 |
* [5] 在spring里配置Person和PersonDao |
* [6] 运行DaoTest |
At line 39 changed 1 line. |
!!Create a new Object and add XDoclet tags [#1] |
!!建立一个对象,并且作XDoclet标记 [#1] |
At line 41 changed 1 line. |
The first thing we need to do is create an object to persist. Let's create a simple "Person" object (in the {{src/dao/**/model}} directory) that has an id, a firstName and a lastName (as properties). |
我们要做的第一件事情就是建立一个需要持久化的对象,我们要在{{src/dao/**/model}}目录下建立一个简单的Person对象,这个对象包括id、firstName和lastName属性。 |
At line 43 changed 1 line. |
%%note __NOTE:__ Copying the Java code in these tutorials [doesn't work in Firefox|http://raibledesigns.com/page/rd?anchor=java2html_plugin_for_jspwiki_causes]. A workaround is to CTRL+Click (Command+Click on OS X) the code block and then copy it.%% |
%%note __注意:__ [不能在FireFox中|http://raibledesigns.com/page/rd?anchor=java2html_plugin_for_jspwiki_causes]直接拷贝本教程的代码 ,但我们可以通过CTRL+Click选定一个代码所在的工作区(OS X下是Command+Click),然后再拷贝。%% |
At line 62 changed 1 line. |
This class should extend [BaseObject|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/model/BaseObject.java.html], which has 3 abstract methods: (equals(), hashCode() and toString()) that you will need to implement in the Person class. The first two are required by Hibernate. The easiest way to do this is using [Commonclipse|http://commonclipse.sf.net]. More information on using this tool can be found on [Lee Grey's site|http://www.leegrey.com/hmm/2004/09/29/1096491256000.html]. Another Eclipse Plugin you can use is [Commons4E|http://commons4e.berlios.de/]. I haven't used it, so I can't comment on its functionality. |
这个类必须扩展[BaseObject|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/model/BaseObject.java.html],而这个BaseObject有三个抽象方法(equals(), hashCode()和toString())需要你在Person类里实现,前两个是Hibernate的需要。为了完成这部分工作最简单的方式是使用[Commonclipse|http://commonclipse.sf.net],关于这个工具更多的信息可以在[Lee Grey的站点|http://www.leegrey.com/hmm/2004/09/29/1096491256000.html]里看到,另外一个你可以使用的Eclipse的插件是[Commons4E|http://commons4e.berlios.de/],我还没有使用过,这里不便对其功能作出评论。 |
At line 64 changed 1 line. |
;:''If you're using [IntelliJ IDEA|http://www.jetbrains.com/idea], you can generate equals() and hashCode(), but not toString(). There is a [ToStringPlugin|http://www.intellij.org/twiki/bin/view/Main/ToStringPlugin] that works reasonably well.'' |
;:''如果你使用[IntelliJ IDEA|http://www.jetbrains.com/idea],你可以自动产生equals()和hashCode(),但没有toString(),有一个 [ToStringPlugin|http://www.intellij.org/twiki/bin/view/Main/ToStringPlugin]插件做得非常不错'' |
At line 66 changed 1 line. |
Now that we have this POJO created, we need to add XDoclet tags to generate the Hibernate mapping file. This mapping file is used by Hibernate to map objects → tables and properties (variables) → columns. |
现在我们已经创建了这个POJO对象,我们需要增加XDoclet标记来产生Hibernate的映射文件,这些文件用来映射对象→ 表和属性(变量) → 字段。 |
At line 68 changed 1 line. |
First of all, we add a [@hibernate.class|http://xdoclet.sourceforge.net/tags/hibernate-tags.html#@hibernate.class%20(0..1)] tag that tells Hibernate what table this object relates to: |
首先,我们增加[@hibernate.class|http://xdoclet.sourceforge.net/tags/hibernate-tags.html#@hibernate.class%20(0..1)] 来告诉Hibernate我们将要和那个表作关联: |
At line 78 changed 1 line. |
We also have to add a primary key mapping or XDoclet will puke when generating the mapping file. Note that all @hibernate.* tags should be placed in the __getters'__ Javadocs of your POJOs. |
我们也要增加主键的映射,否则XDoclet会在产生映射文件时出错,注意所有的@hibernate.*标签必须在__getters'__的Javadocs里面。 |
At line 93 changed 1 line. |
;:%%(color: blue)''I'm using {{generator-class="increment"}} instead of {{generate-class="native"}} because I [found some issues|AppFuseOnDB2] when using "native" on other databases. If you only plan on using MySQL, I __recommend you use the "native" value__. This tutorial uses increment.''%% |
;:%%(color: blue)''我使用{{generator-class="increment"}}而不使用{{generate-class="native"}} 是因为我对数据库使用"native"时[发现一些问题|AppFuseOnDB2],如果你只是希望使用MySQL,__推荐使用"native"值__,本教程使用increment。''%% |
At line 95 changed 2 lines. |
!!Create a new database table from the object using Ant [#2] |
At this point, you can create the person table by running __ant setup-db__. This task creates the {{Person.hbm.xml}} file and creates a database table called "person". From the ant console, you can see the table schema the Hibernate creates for you: |
|
!!使用Ant根据对象产生数据库表[#2] |
在这种情况下,你可以通过运行__ant setup-db__来建立person表,这个任务会产生文件{{Person.hbm.xml}}并且会建立叫做"person"的表,从Ant的控制台窗口,你可以看到Hibernate为你建立的表结构的内容。 |
At line 104 changed 1 line. |
If you want to look at the {{Person.hbm.xml}} file that Hibernate generates for you, look in the {{build/dao/gen/**/model}} directory. Here's the contents of {{Person.hbm.xml}} (so far): |
如果你查看Hibernate生成的文件{{Person.hbm.xml}},可以到{{build/dao/gen/**/model}}目录,这里是{{Person.hbm.xml}}的内容(目前的内容): |
At line 143 changed 1 line. |
Now we'll add additional [@hibernate.property|http://xdoclet.sourceforge.net/tags/hibernate-tags.html#@hibernate.property%20(0..1)] tags for our other columns (first_name, last_name): |
现在我们要为其它的字段(first_name, last_name)添加额外的[@hibernate.property|http://xdoclet.sourceforge.net/tags/hibernate-tags.html#@hibernate.property%20(0..1)]标签: |
At line 146 added 1 line. |
|
At line 162 changed 1 line. |
In this example, the only reason for adding the ''column'' attribute is because the column name is different from our property name. If they're the same, you don't need to specify the ''column'' attribute. See the [@hibernate.property|http://xdoclet.sourceforge.net/tags/hibernate-tags.html#@hibernate.property%20(0..1)] reference for other attributes you can specify for this tag. |
在这个例子里,添加''column''属性的唯一原因是因为这个字段名与它的属性名不相同,如果他们相同,你没有必要来指定''column''属性,关于其它可以使用的标签请看[@hibernate.property|http://xdoclet.sourceforge.net/tags/hibernate-tags.html#@hibernate.property%20(0..1)]。 |
At line 164 changed 1 line. |
Run __ant setup-db__ again to get the additional columns added to your table. |
再次运行__ant setup-db__把新加的属性加到数据库表里。 |
At line 173 changed 1 line. |
If you want to change the size of your columns, modify the ''length'' attribute in your @hibernate.property tag. If you want to make it a required field (NOT NULL), add not-null="true". |
如果期望修改字段的长度,修改@hibernate.property标签的''length''属性,如果希望把字段改为必添字段(NOT NULL),可以增加属性not-null="true"。 |
At line 175 changed 1 line. |
!!Create a new DaoTest to run JUnit tests on your DAO [#3] |
!!建立新的DaoTest来对你的DAO运行JUnit测试[#3] |
At line 177 changed 1 line. |
%%note <a name="appgen"></a>__NOTE:__ AppFuse versions 1.6.1+ contain include an [AppGen] tool that can be used to generate all the classes for the rest of these tutorials. However, it's best that you go through these tutorials before using this tool - then you'll know what code it's generating.%% |
%%note <a name="appgen"></a>__注意:__从Appfuse版本1.6.1+开始包括了一个[AppGen]工具,可以用来生成本教程余下的所有的类的代码,不过,我们最好还是先过一遍教程再使用这个工具产生代码。%% |
At line 179 changed 1 line. |
Now we'll create a DaoTest to test that our DAO works. "Wait a minute," you say, "we haven't created a DAO!" You are correct. However, I've found that [Test-Driven Development|http://www.artima.com/intv/testdriven.html] breeds higher quality software. For years, I thought __write your test before your class__ was hogwash. It just seemed stupid. Then I tried it and I found that it works great. The only reason I do all this test-driven stuff now is because I've found it rapidly speeds up the process of software development. |
现在,我们要创建一个DaoTest来测试我们的DAO的工作,等会儿,你说,我们还不曾创建DAO呢!,你说得对。无论如何,我发现[测试驱动开发|http://www.artima.com/intv/testdriven.html]大大的促进了软件质量,在许多年里我一直认为__在写代码之前写测试__是胡说八道,这看起来很愚蠢,但当我尝试之后我认为这样非常好,现在我按照测试驱动的方式工作完全因为我发现这样可以大大提高我软件开发的效率。 |
At line 181 changed 1 line. |
To start, create a {{PersonDaoTest.java}} class in the {{test/dao/**/dao}} directory. This class should extend [BaseDaoTestCase|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDaoTestCase.java.html], a subclass of JUnit's [TestCase|http://junit.sourceforge.net/javadoc/junit/framework/TestCase.html] which already exists in this package. This parent class is used to load [Spring's|http://www.springframework.org] ApplicationContext (since Spring binds the layers together), and for (optionally) loading a .properties file (ResourceBundle) that has the same name as your {{*Test.class}}. In this example, if you put a {{PersonDaoTest.properties}} file in the same directory as {{PersonDaoTest.java}}, this file's properties will be available via an "rb" variable. |
开始,我们在{{test/dao/**/dao}}目录下建立类{{PersonDaoTest.java}},这个类必须扩展[BaseDaoTestCase|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDaoTestCase.java.html],而BaseDAOTestCase这个类是JUnit类[TestCase|http://junit.sourceforge.net/javadoc/junit/framework/TestCase.html]的子类,这个类用来加载[Spring|http://www.springframework.org]的ApplicationContext(因为Spring把各个层绑定)和单元测试类同一目录下同你的测试类文件同名的.properties文件(ResourceBundle),这个属性文件的属性可以通过rb属性来访问。 |
At line 183 changed 1 line. |
;:%%(color: blue)''I usually copy (open → save as) an existing test (i.e. UserDaoTest.java) and find/replace [[Uu]ser with [[Pp]erson, or whatever the name of my object is.''%% |
;:%%(color: blue)''我经常拷贝(打开→另存为)一个已存在的测试(如UserDaoTest.java),然后查找/替换 [[Uu]ser为[[Pp]erson,或者任何其它需要替换的内容。''%% |
At line 197 changed 3 lines. |
protected void setUp() throws Exception { |
super.setUp(); |
dao = (PersonDao) ctx.getBean("personDao"); |
public void setPersonDao(PersonDao dao) { |
this.dao = dao; |
At line 201 removed 5 lines. |
|
protected void tearDown() throws Exception { |
super.tearDown(); |
dao = null; |
} |
At line 209 changed 1 line. |
The code you see above is what we need for a basic JUnit test that initializes and destroys our PersonDao. The "ctx" object is a reference to Spring's ApplicationContext, which is initialized in a static block of the [BaseDaoTestCase's|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDaoTestCase.java.html] class. |
以上是我们使用JUnit测试而初始化和销毁PersonDao的基本代码,对象ctx引用了Spring的ApplicationContext,它在[BaseDaoTestCase|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDaoTestCase.java.html]类的静态代码区里被初始化。 |
At line 211 changed 1 line. |
Now we need to actually test that the CRUD (create, retrieve, update, delete) methods work in our DAO. To do this we created methods that begin with "test" (all lower case). As long as these methods are public, have a void return type and take no arguments, they will be called by our <junit> task in our Ant build.xml file. Here's some simple tests for testing CRUD. An important thing to remember is that each method (also known as a test), should be autonomous. Add the following methods to your {{PersonDaoTest.java}} file: |
现在我们需要实际测试DAO中的CRUD(create, retrieve, update, delete)方法,为此我们需要为每个方法建立以test(全部小写)开头的测试方法,只要这个方法是公共的,返回类型是void,它们就会被我们build.xml中的Ant的<junit>任务调用,如下是一些简单的CRUD测试,需要注意的一点是所有的方法(或者叫做测试)必须是自治的,添加如下代码到文件{{PersonDaoTest.java}}: |
At line 268 removed 1 line. |
;:%%(color: blue)''In the testGetPerson method, we're creating a person and then calling a get. I usually enter a record in the database that I can always rely on. Since [DBUnit|http://www.dbunit.org] is used to populate the database with test data before our tests are run, you can simply add the new table/record to the metadata/sql/sample-data.xml file:''%% |
At line 265 added 2 lines. |
;:%%(color: blue)''在testGetPerson方法,我们创建了一个person并且调用get方法,我通常会增加一条我所需要的记录到数据库,因为在测试运行之前[DBUnit|http://www.dbunit.org]会为数据库准备测试数据,我们可以简单的在metadata/sql/sample-data.xml里添加测试所必须的记录''%% |
|
At line 285 changed 1 line. |
;:%%(color: blue)''This way, you can eliminate the "create new" functionality in the testGetPerson method. If you'd rather add this record directly into the database (via SQL or a GUI), you can rebuild your {{sample-data.xml}} file using __ant db-export__ and then __cp {{db-export.xml metadata/sql/sample-data.xml}}__.''%% |
;:%%(color: blue)''通过这种方式你可以在testGetPerson方法里消除创建新纪录的动作,如果你愿意直接插入记录到数据库(使用SQL或者GUI),你可以用__ant db-export__和__cp {{db-export.xml metadata/sql/sample-data.xml}}__重新构建你的{{sample-data.xml}}文件。''%% |
At line 287 changed 2 lines. |
In the above example, you can see that we're calling person.set*(value) to populate our object before saving it. This is easy in this example, but it could get quite cumbersome if we're persisting an object with 10 required fields (not-null="true"). This is why I created the ResourceBundle in the BaseDaoTestCase. Simply create a {{PersonDaoTest.properties}} file in the same directory as {{PersonDaoTest.java}} and define your property values inside it: |
;:%%(color: blue)''I tend to just hard-code test values into Java code - but the .properties file is an option that works great for large objects.''%% |
在上面的例子里,你可以看到我们调用person.set*(value)来准备我们需要保存的对象,在这个例子里很简单,但是当你要插入10条必添字段(not-null="true")时就比较麻烦了,这就是我为什么要在BaseDaoTestCase使用ResourceBundle文件,只要在{{PersonDaoTest.java}}同一个目录创建一个{{PersonDaoTest.properties}}并且在里面定义你的属性值: |
;:%%(color: blue)''我通常只是在Java里硬编码,但是这个.properties对于大对象很有用。''%% |
At line 293 changed 1 line. |
Then, rather than calling person.set* to populate your objects, you can use the BaseDaoTestCase.populate(java.lang.Object) method: |
此时,你要通过调用BaseDaoTestCase.populate(java.lang.Object)方法来准备对象,而不是使用person.set*。 |
At line 301 changed 1 line. |
At this point, the PersonDaoTest class won't compile yet because there is no PersonDao.class in our classpath, we need to create it. PersonDAO.java is an interface, and PersonDAOHibernate.java is the Hibernate implementation of that interface. Let's go ahead and create those. |
在目前情况下,还不可以编译PersonDaoTest,因为在类路径里还没有PersonDao.class,我们需要创建它。PersonDao.java是一个接口,PersonDaoHibernate.java是它的Hibernate实现,让我们继续,开始创建。 |
At line 303 changed 2 lines. |
!!Create a new DAO to perform CRUD on the object [#4] |
First off, create a PersonDao.java interface in the {{src/dao/**/dao}} directory and specify the basic CRUD methods for any implementation classes. ''I've eliminated the JavaDocs in the class below for display purposes.'' |
!!创建一个对对象执行CRUD操作的新DAO[#4] |
马上,在{{src/dao/**/dao}}目录里建立PersonDao.java接口,并且指定所有实现类要实现的基本CRUD操作,为了显示方便,我已经去掉了所有JavaDocs。 |
At line 319 changed 1 line. |
Notice in the class above there are no exceptions on the method signatures. This is due to the power of [Spring|http://www.springframework.org] and how it wraps Exceptions with RuntimeExceptions. At this point, you should be able to compile all the source in {{src/dao}} and {{test/dao}} using __ant compile-dao__. However, if you try to run __ant test-dao -Dtestcase=PersonDao__, you will get an error: <span style="color: red">No bean named 'personDao' is defined</span>. This is an error message from Spring - indicating that we need to specify a bean named ''personDAO'' in {{applicationContext-hibernate.xml}}. Before we do that, we need to create the PersonDao implementation class. |
注意,在以上的方法声明上并没有exceptions说明,这是因为[Spring|http://www.springframework.org]使用RuntimeExceptions来包裹Exceptions的方式,此时,你已经可以使用__ant compile-dao__来编译{{src/dao}}和{{test/dao}}下的所有源文件,然而当你运行__ant test-dao -Dtestcase=PersonDao__进行测试时,你会得到一个错误:<span style="color: red">No bean named 'personDao' is defined</span>,这是一个Spring的错误,说明你必须在{{applicationContext-hibernate.xml}}指定一个名字为''personDAO''的bean,在此之前我们需要创建PersonDao的实现类。 |
At line 321 changed 1 line. |
;:''The ant task for running dao tests is called __test-dao__. If you pass in a testcase parameter (using __-Dtestcase=name__), it will look for {{**/*${testcase}*}} - allowing us to pass in Person, PersonDao, or PersonDaoTest - all of which will execute the PersonDaoTest class.'' |
;:''运行dao测试的ant任务叫做__test-dao__,如果你传递testcase参数(用__-Dtestcase=name__),它会查看{{**/*${testcase}*}}允许我们传递Person、PersonDao、或者PersonDaoTest以及所有会执行PersonDaoTest的类。'' |
At line 323 changed 1 line. |
Let's start by creating a PersonDaoHibernate class that implements the methods in PersonDao and uses Hibernate to get/save/delete the Person object. To do this, create a new class in {{src/dao/**/dao/hibernate}} and name it {{PersonDAOHibernate.java}}. It should extend [BaseDaoHibernate|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDAOHibernate.java.html] and implement PersonDAO. ''Javadocs eliminated for brevity.'' |
让我们创建一个实现PersonDao的类PersonDaoHibernate并使用Hibernate来get/save/delete这个Person对象,为此,我们在{{src/dao/**/dao/hibernate}}创建一个新类{{PersonDaoHibernate.java}},它应该扩展[BaseDaoHibernate|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDAOHibernate.java.html],并且实现PersonDao。''为了简洁,省略Javadocs。'' |
At line 356 changed 1 line. |
Now, if you try to run __ant test-dao -Dtestcase=PersonDao__, you will get the same error. We need to configure Spring so it knows that PersonDaoHibernate is the implementation of PersonDAO, and we also need to tell it about the Person object. |
现在,如果你运行__ant test-dao -Dtestcase=PersonDao__,你会得到同样的错误,我们必须配置Spring来让它知道PersonDaoHibernate是PersonDao的实现,同样的,我们也要告诉它还有个Person对象。 |
At line 358 changed 1 line. |
!!Configure Spring for the Person object and PersonDao [#5] |
!!配置Spring中的Person和PersonDao [#5] |
At line 360 changed 1 line. |
First, we need to tell Spring where the Hibernate mapping file is located. To do this, open {{src/dao/**/dao/hibernate/applicationContext-hibernate.xml}} and add {{"Person.hbm.xml"}} to the following code block. |
首先我们要告诉Spring所有Hibernate文件的位置,为此,打开{{src/dao/**/dao/hibernate/applicationContext-hibernate.xml}},在以下代码块添加{{"Person.hbm.xml"}}。 |
At line 368 changed 2 lines. |
<value>org/appfuse/model/User.hbm.xml</value> |
<value>org/appfuse/model/UserCookie.hbm.xml</value> |
<value>org/appfuse/model/User.hbm.xml</value> |
At line 374 changed 1 line. |
Now we need to add some XML to this file to bind PersonDaoHibernate to PersonDao. To do this, add the following at the bottom of the file: |
现在我们需要添加一些XML数据来绑定PersonDaoHibernate到PersonDao,为此,添加如下代码到文件底部: |
At line 384 changed 1 line. |
;:''You could also use __autowire="byName"__ to the <bean> and get rid of the "sessionFactory" property''. %%(color: blue)''Personally, I like having the dependencies of my objects documented (in XML).''%% |
;:''你也可以为<bean>使用__autowire="byName"__属性来消除"sessionFactory"属性''。%%(color: blue)''从个人来讲,我喜欢在XML文件里保留对象的依赖。''%% |
At line 386 changed 2 lines. |
!!Run the DaoTest [#6] |
Save all your edited files and try running __ant test-dao -Dtestcase=PersonDao__ one more time. |
!!运行DaoTest[#6] |
保存所有修改的文件,运行__ant test-dao -Dtestcase=PersonDao__。 |
At line 395 changed 1 line. |
''Next Up:'' __Part II:__ [Creating new Managers|CreateManager] - A HowTo for creating Business Facades, which are similar to [Session Facades|http://java.sun.com/blueprints/patterns/SessionFacade.html], but don't use EJBs. These facades are used to provide communication from the front-end to the DAO layer. |
''下一部分:'' __Part II:__ [创建新的Manager|CreateManager_zh] - 是一个建立类似于[Session Facades|http://java.sun.com/blueprints/patterns/SessionFacade.html]的,但不使用EJBs的业务Facade说明,这个facades用来建立从前端到DAO层的联系。 |