林信良(良葛格)的专栏

http://caterpillar.onlyfun.net/

原创 第一个Hibernate with Annotation程式收藏

新一篇: 我只是一个小讲师、小作者。。。 | 旧一篇: 阙疑

Hibernate是ORM的解决方案,其底层对数据库的操作依赖于JDBC,所以您必须先取得JDBC驱动程序,在这边所使用的是MySQL,所以您必须至 MySQL® Connector/J 取得MySQL的JDBC驱动程序。

接下来至 Hibernate 官方网站 取得Hibernate 3.2Hibernate Annotations 3.2

您必须安装JDK 5.0才可以使用Hibernate Annotations的功能。

解开Hibernate 3.2的zip档案后,当中的hibernate3.jar是必要的,而在lib目录中还包括了许多jar档案,您可以在 Hibernate 3.0官方的参考手册 上找到这些jar的相关说明,其中必要的是 antlr、dom4j、CGLIB、asm、Commons Collections、Commons Logging、 EHCache,Hibernate底层还需要Java Transaction API,所以您还需要jta.jar。

解开Hibernate Annotations 3.2的zip档案后,您需要hibernate-annotations.jar、ejb3-persistence.jar这两个档案。

到这边为止,总共需要以下的jar档案:


Hibernate可以运行于单机之上,也可以运行于Web应用程序之中,如果是运行于单机,则将所有用到的jar档案(包括JDBC驱动程序)设定至CLASSPATH中,如果是运行于Web应用程序中,则将jar档案置放于WEB-INF/lib中。

如果您还需要额外的Library,再依需求加入,例如JUnit、Proxool等等,接下来可以将etc目录下的 log4j.properties复制至Hibernate项目的Classpath下,并修改一下当中的 log4j.logger.org.hibernate为error,也就是只在在错误发生时显示必要的讯息。

接着设置基本的Hibernate配置文件,可以使用XML或Properties档案,这边先使用XML,档名预设为hibernate.cfg.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
    <session-factory>
        <!-- 显示实际操作数据库时的SQL -->
        <property name="show_sql">true</property>
        <!-- SQL方言,这边设定的是MySQL -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- JDBC驱动程序 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- JDBC URL -->
        <property name="connection.url">jdbc:mysql://localhost/demo</property>
        <!-- 数据库使用者 -->
        <property name="connection.username">root</property>
        <!-- 数据库密码 -->
        <property name="connection.password">123456</property>
 
        <!-- 以下设置对象与数据库表格映像类别 -->
        <mapping class="onlyfun.caterpillar.User"/>
    </session-factory>
</hibernate-configuration>

这边以一个简单的单机程序来示范Hibernate的配置与功能,首先作数据库的准备工作,在MySQL中新增一个demo数据库,并建立user表格:
CREATE TABLE user (
id INT(11) NOT NULL auto_increment PRIMARY KEY,
name VARCHAR(100) NOT NULL default '',
age INT
);
对于这个表格,您有一个User类别与之对应,表格中的每一个字段将对应至User实例上的Field成员。

package onlyfun.caterpillar;
 
import javax.persistence.*;
 
@Entity
@Table(name="user") // 非必要,在表格名称与类别名称不同时使用
public class User {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
 
  @Column(name="name") // 非必要,在字段名称与属性名称不同时使用
    private String name;
 
  @Column(name="age")
    private Integer age; // 非必要,在字段名称与属性名称不同时使用
   
    // 必须要有一个预设的建构方法
    // 以使得Hibernate可以使用Constructor.newInstance()建立对象
    public User() {
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
   
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
}

其中id是个特殊的属性,Hibernate会使用它来作为主键识别,您可以定义主键产生的方式,这边设定为自动产生主键,可以看到,实体标识,主键生成,以及相关映像,都可以使用Annotation来完成。

接下来撰写一个测试的程序,这个程序直接以Java程序设计人员熟悉的语法方式来操作对象,而实际上也直接完成对数据库的操作,程序将会将一笔数据存入表格之中:
package onlyfun.caterpillar;
 
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
 
public class HibernateAnnotationDemo {
 
    public static void main(String[] args) {
        // 需要AnnotationConfiguration读取Annotation讯息
        Configuration config = new AnnotationConfiguration().configure();
        // 根据 config 建立 SessionFactory
        // SessionFactory 将用于建立 Session
        SessionFactory sessionFactory = config.buildSessionFactory();
 
        // 将持久化的物件
        User user = new User();
        user.setName("caterpillar");
        user.setAge(new Integer(30));    
 
        // 开启Session,相当于开启JDBC的Connection
        Session session = sessionFactory.openSession();
        // Transaction表示一组会话操作
        Transaction tx= session.beginTransaction();
        // 将对象映像至数据库表格中储存
        session.save(user);
        tx.commit();
        session.close();
        sessionFactory.close();
      
        System.out.println("新增资料OK!请先用MySQL观看结果!");
    }
}

注意,使用Annotation时,需要的是AnnotationConfiguration类别。

如您所看到的,程序中只需要直接操作User对象,并进行Session与Transaction的相关操作,Hibernate就会自动完成对数据库的操作,您看不到任何一行JDBC或SQL的陈述,撰写好以上的各个档案之后,各档案的放置位置如下:


接着可以开始运行程序,结果如下:
Hibernate: insert into user (name, age) values (?, ?)
新增资料OK!请先用MySQL观看结果!

执行结果中显示了Hibernate所实际使用的SQL,由于这个程序还没有查询功能,所以要进入MySQL中看看新增的数据,如下:
mysql> select * from user;
+----+-----------------+------+
| id    | name         | age  |
+----+-----------------+------+
|  1    | caterpillar  | 30   |
+----+-----------------+------+
1 row in set (0.03 sec)

发表于 @ 2006年07月15日 21:47:00|评论(loading...)|编辑

新一篇: 我只是一个小讲师、小作者。。。 | 旧一篇: 阙疑

评论

#lighter 发表于2006-07-17 12:51:00  IP: 218.15.22.*
很简单的一个例子,对初学者有点启示.
对@Dependent,@DependentAttribute,继承用的@Inheritance,和@DiscriminatorColumn,@ManyToOne等方面都没有提到,你的许多文章写得不错,特别对入门者来说.特别是spring入门的46节,写得很好.
希望写得更好.
#s.w.pollux 发表于2006-07-17 16:45:00  IP: 58.246.176.*
lighter,说话也注意点,别人写的东西就应该尊重点。简单的例子怎么了?对初学者有点启示。什么口气?不知道你在java ee方面的造就有多深?每篇文章不可能面面俱到,我就觉得作者写的很好!另外山外有山,虚心学习点!如果你认为作者有什么遗漏的地方,你怎么不自己来写上?或者给个资源的链接?
支持作者的原创!

#林信良 发表于2006-07-17 23:07:00  IP: 219.86.67.*
摘要不是说了吗?我只是小试Annotation,留个记录而已。。。XD
#Richie 发表于2006-07-18 07:00:00  IP: 221.200.216.*
和EJB3的定义样式,倒也无什么不同。
而且还需要手动控制Session的生命周期。
#s.w.pollux 发表于2006-07-18 10:31:00  IP: 58.246.176.*
不知道楼上的朋友说用手动控制session的life circle是什么意思?
#k 发表于2006-07-19 10:30:00  IP: 60.16.89.*
您是台湾人吗?

程式...很吃苍蝇
#dennis 发表于2006-07-19 12:44:00  IP: 58.23.92.*
很感谢,还未接触到hibernate的Annotation,看起来确实和EJB3几乎完全一致,统一的持久层API感觉不错
#goby 发表于2006-07-21 22:45:00  IP: 218.14.146.*
良兄,你的<<spring技术手册>>写得很好,我已经看完了,现在想写struts+hibernate+spring的程序,但关于分页显示方面,应该如何处理.
我看了你网站上的struts和hibernate教程,里面也没有提到关于数据分页显示的方法,你可以在这里写一些关于这方面的方法好吗?
#goby 发表于2006-07-21 22:54:00  IP: 218.14.146.*
良兄,你的<<spring技术手册>>写得很好,我已经看完了,现在想写struts+hibernate+spring的程序,但关于分页显示方面,应该如何处理.
我看了你网站上的struts和hibernate教程,里面也没有提到关于数据分页显示的方法,你可以在这里写一些关于这方面的方法好吗?
#林信良 发表于2006-07-21 23:40:00  IP: 61.216.99.*
数据分页可以是个专门的主题,可以到http://www.javaworld.com.tw找到不少讨论,甚至找到别人写好的元件!另一方面,Blog并不是个适合一来一往讨论的地方,所以就请恕不在这边讨论了。。。Orz...
#jackyrong 发表于2006-08-05 22:57:00  IP: 219.137.55.*
林老师,想问个AOP的问题,在你的书的191页环绕通知那里的那个例子,想问下,为什么运行的结果是
log...methods star........
log methods end...
Hello,justin 呢?

按道理应该是先是执行 log stars,然后执行
真正的业务输出(输出Hello,justin),最后才是logs ends的呀?
为什么会这样呢?
#林信良 发表于2006-08-06 08:42:00  IP: 218.166.211.*
logging的优先权与standard out不同,有机会就会输出。。
#Levin 发表于2006-08-11 09:59:00  IP: 60.63.93.*


林老师,在您的《Spring技术手册》第九章9.2邮件服务SimpleMailDemo中,程序执行时抱错,需要什么

验证,您能帮解决一下吗?
源程序:
package com.eimagesoft;

import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.SimpleMailMessage;

public class SimpleMail {
public static void main(String[] args) throws Exception {
JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();

senderImpl.setHost("smtp.163.com");

SimpleMailMessage mailMessage = new SimpleMailMessage();


mailMessage.setTo("zhanganjie001@sina.com.cn");
mailMessage.setFrom("zhanganjie001@163.com");
mailMessage.setSubject("Test");
mailMessage.setText("This is a test!!!");


senderImpl.send(mailMessage);

System.out.println("邮件传送OK..");
}
}
下面是错误提示:
Exception in thread "main" org.springframework.mail.MailSendException: Could not send mails:

553 authentication is required,smtp5,wKjRECjAIgEe4NtEmNYpAQ==.16534S2

com.sun.mail.smtp.SMTPSendFailedException: 553 authentication is

required,smtp5,wKjRECjAIgEe4NtEmNYpAQ==.16534S2

at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1275)
at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:895)
#林信良 发表于2006-08-11 10:22:00  IP: 219.80.41.*
您的SMTP Server需要验证身份,例如提供密码、名称之类的,这跟Spring无关,每个SMTP Server需要的验证方式不同,该示例是找一个不用验证身份的SMTP Server来运作的。。。

另外,有问题可以至我的网站http://caterpillar.onlyfun.net/phpBB2/,Blog并不适合讨论问题。。。:)
#Levin 发表于2006-08-15 11:31:00  IP: 60.63.93.*
林老师您好!
我在学习您的<<Spring技术手册>>第10章时遇到了问题,麻烦您帮我解决以下好吗?因为我对源程序的配置做了一点改动,所以我已经把整个项目程序发到您的邮箱里了.在线等候您.
因为我对繁体字不是很熟,所以您的网站我看的不是很顺利,所以就在扎给您留言了.
#Levin 发表于2006-08-16 12:30:00  IP: 60.63.93.*
林老师您好!
这是我在测试您编写的《Spring技术手册》第十章的在线书签时遇到的问题:

HTTP Status 500 -

--------------------------------------------------------------------------------

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Servlet.init() for servlet dispatcherServlet threw exception
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
java.lang.Thread.run(Unknown Source)


root cause

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'registerController' defined in ServletContext resource [/WEB-INF/web-config.xml]: Can't resolve reference to bean 'userDAO' while setting property 'userDAO'; nested exception is org.springframework.beans.factory.BeanCreationException: Error cr
#林信良 发表于2006-08-16 22:01:00  IP: 211.74.204.*
您给的资讯不足,不知道您确切错在哪边…XD

#gogolong 发表于2006-08-20 19:04:00  IP: 219.82.136.*
林先生您好:

林先生好,今天在china-pub,,下载了您的二章
spring,一会的功夫我看懂了,原以深不可测,
神龙见首,不见尾的spring,在您犀利的笔峰下
是那样的亲切,易懂!

谢谢您了,我就想找一本spring的入门书,
刚刚去书店买回一本您的spring技术手册,还热着呢? :)

再麻烦问您一下,我想入门再了解一下EJB,
您看那一本好一些!

祝您全家平安
#林信良 发表于2006-08-21 00:16:00  IP: 211.74.255.*
EJB 2?老实说我并没有研究,当初看EJB 2,只觉得很繁杂,后来因为没时间就没再研究了…

感谢您支持Spring技术手册…Orz...
#spring  发表于2006-09-22 23:58:00  IP: 61.129.63.*
林先生你好,

我大用在线书签时,连的是Postger 数据库,当插入数据时,遇到问题:org.springframework.jdbc.BadSqlGrammarException: Hibernate operation: could not get next sequence value; bad SQL grammar [select nextval ('hibernate_sequence')]; nested exception is org.postgresql.util.PSQLException: ERROR: relation "hibernate_sequence" does not exist
org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:223)
org.springframework.orm.hibernate3.HibernateAccessor.convertJdbcAccessException(HibernateAccessor.java:424)
org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:411)
#林信良 发表于2006-09-24 15:54:00  IP: 218.164.148.*
我没用过Postger,不过从讯息中看,应该是Postger中,使用Hibernate的自动增生主键机制时,需要自己建立sequence(类似Oracle?),您得自行研究一下Hibernate的主键设定以及Postger中如何建立sequence…

#bestwinner 发表于2006-09-27 01:12:00  IP: 219.232.163.*
林先生你好!
我在做SpirngMVC时遇到异常:javax.servlet.ServletException: Neither Errors instance nor plain target object for bean name 'command' available as request attribute
页面文件片段:
<spring:bind path="command.*">
<font color="red">
<c:forEach items="${status.errorMessages}" var="error">
错误:${error}</br>
</c:forEach>
</font>
</spring:bind>
<FORM method="post" action="/login.do">
<spring:bind path="command.name">
<spring:message code="userName"/>:<INPUT type="text" name="${status.expression}" value="${status.value}"/>
<font color="red">
<br>
<c:if test="${status.error}">
<font color="red">
<c:forEach items="${status.errorMessages}" var="error">
错误:${error}</br>
</c:forEach>
</font>
</c:if>
</font>
</spring:bind>
配置文件片段:
<bean id="loginValidator" class="validate.LoginValidate"></bean>
<bean id="login" class="action.LoginAction">
<property name="commandClass">
<value>vo.LoginVO</va
#林信良 发表于2006-09-27 14:13:00  IP: 219.80.140.*
请先参考…
http://www.javaworld.com.tw/jute/post/view?bid=42&id=152074&tpg=1&ppg=1&sty=1&age=0#152074
#wfnlibo 发表于2006-12-16 09:17:03  IP: 124.234.162.*
你这个例子不可以运行啊。请问还需要hibernate.cfg.xml这个文件吗?如果要这个文件应该怎么写?
#zhngling 发表于2007-09-20 07:56:33  IP: 125.38.123.*
不错,very good!
#qqwwssaagg 发表于2008-07-27 09:37:45  IP: 220.201.133.*
就是annotations的关系怎么设置啊没弄明白请给小弟个实例吧谢谢了我的邮箱375391019@qq.com谢谢了先
#qqwwssaagg 发表于2008-07-27 09:37:50  IP: 220.201.133.*
就是annotations的关系怎么设置啊没弄明白请给小弟个实例吧谢谢了我的邮箱375391019@qq.com谢谢了先
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © 良葛格