Hibernate(带注释) - 如何入门

Why*_*ugo 17 hibernate

我正在尝试开始使用hibernate,但我找不到任何我理解的教程.我正在尝试创建一个简单的应用程序来开始,但我真的不知道从哪里开始.

虽然我只使用了eclipse,但我对java非常先进.那么..我在哪里配置它使用的DB,等等?

[编辑]
我熟悉ORM的概念,以及Hibernate的概念.我不知道或不了解的是,从哪里开始我的申请.我打算使用注释,但是,在注释我的POJO之后,我该怎么办?我在哪里指定数据库服务器,用户等?我还需要做什么?

Kyl*_*ull 26

我的经历和背景是相似的,我也很难找到一个解决我的开发偏好的教程(看起来与你的相似):

  • 首选JPA注释而不是XML,只在JPA版本不足时添加Hibernate注释
  • 使用Hibernate的SessionFactory/Session来访问持久数据而不是JPA EntityManager
  • 尽可能使用不可变类

我阅读了大多数使用HibernateJava Persistence,并且花了很长时间将这个用例与它提供的所有其他选项分开(Hibernate/JPA格式的XML配置,xdoclet"annotations"等等).

如果可用的文档能够采取立场并积极推动我朝着这个方向努力,而不是给我一堆选择并想知道去哪里,那对我来说会更有意义.缺乏这一点,我通过将标准的Hibernate教程转换为注释来学习以下课程.

组态

  • 将hibernate.cfg.xml保持在最低限度(见下文).
  • 使用JPA注释显式定义数据库列/表名,以便准确获得所需的模式.您可以使用SchemaExport.create(true,false)仔细检查它.请注意,如果Hibernate尝试更新现有数据库上的模式,您可能无法获得所需的确切模式(例如,您无法向已包含空值的列添加NOT NULL约束).
  • 使用AnnotationConfiguration.addAnnotatedClass()创建SessionFactory的配置.addAnnotatedClass()...

这是我的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>
        <!-- Information about the database to be used -->
        <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
        <property name="connection.username">sa</property>
        <property name="connection.password"></property>
        <property name="connection.pool_size">1</property>
        <property name="dialect">org.hibernate.dialect.HSQLDialect</property>

        <!-- Misc. Hibernate configuration -->
        <property name="hbm2ddl.auto">update</property>
        <property name="current_session_context_class">thread</property>
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <property name="show_sql">false</property>
    </session-factory>
</hibernate-configuration>
Run Code Online (Sandbox Code Playgroud)

范围

  • 每个Manager/DAO类之外的开始/提交/回滚事务.我不知道为什么教程的EventManager启动/提交自己的事务,因为本书将其识别为反模式.对于本教程中的servlet,可以通过创建一个启动事务的Filter,调用FilterChain的其余部分,然后提交/回滚事务来完成.
  • 类似地,将SessionFactory放在外面并将其传递给每个Manager/DAO类,然后在需要访问数据时调用SessionFactory.getCurrentSession().当需要对DAO类进行单元测试时,请创建自己的SessionFactory连接到内存数据库(例如"jdbc:hsqldb:mem:test")并将其传递给正在测试的DAO.

例如,我的EventManager版本中的一些片段:

public final class EventManager {

private final SessionFactory sessionFactory;

/** Default constructor for use with JSPs */
public EventManager() {

    this.sessionFactory = HibernateUtil.getSessionFactory();
}

/** @param Nonnull access to sessions with the data store */
public EventManager(SessionFactory sessionFactory) {

    this.sessionFactory = sessionFactory;
}

    /** @return Nonnull events; empty if none exist */
public List<Event> getEvents() {

    final Session db = this.sessionFactory.getCurrentSession();
    return db.createCriteria(Event.class).list();
}

/**
 * Creates and stores an Event for which no people are yet registered.
 * @param title Nonnull; see {@link Event}
 * @param date Nonnull; see {@link Event}
 * @return Nonnull event that was created
 */
public Event createEvent(String title, Date date) {

    final Event event = new Event(title, date, new HashSet<Person> ());
    this.sessionFactory.getCurrentSession().save(event);
    return event;
}

/**
 * Registers the specified person for the specified event.
 * @param personId ID of an existing person
 * @param eventId ID of an existing event
 */
public void register(long personId, long eventId) {

    final Session db = this.sessionFactory.getCurrentSession();
    final Person person = (Person) db.load(Person.class, personId);
    final Event event = (Event) db.load(Event.class, eventId);
    person.addEvent(event);
    event.register(person);
}

...other query / update methods...
}
Run Code Online (Sandbox Code Playgroud)

数据类

  • 字段是私有的
  • 由于Hibernate可以直接访问字段,因此Getter方法返回防御副本
  • 除非你真的需要,否则不要添加setter方法.
  • 当需要更新类中的某个字段时,请以保留封装的方式进行更新.调用event.addPerson(person)而不是event.getPeople()更安全.add(person)

例如,只要你记得Hibernate在需要时直接访问字段,我发现事件的这个实现更容易理解.

@Entity(name="EVENT")
public final class Event {

    private @Id @GeneratedValue @Column(name="EVENT_ID") Long id; //Nullable

    /* Business key properties (assumed to always be present) */
    private @Column(name="TITLE", nullable=false) String title;

    @Column(name="DATE", nullable=false) 
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;

    /* Relationships to other objects */
    @ManyToMany
    @JoinTable(
        name = "EVENT_PERSON",
        joinColumns = {@JoinColumn(name="EVENT_ID_FK", nullable=false)},
        inverseJoinColumns = {@JoinColumn(name="PERSON_ID_FK", nullable=false)})
    private Set<Person> registrants; //Nonnull

    public Event() { /* Required for framework use */ }

    /**
     * @param title Non-empty name of the event
     * @param date Nonnull date at which the event takes place
     * @param participants Nonnull people participating in this event
     */
    public Event(String title, Date date, Set<Person> participants) {

        this.title = title;
        this.date = new Date(date.getTime());
        this.registrants = new HashSet<Person> (participants);
    }

    /* Query methods */

    /** @return Nullable ID used for persistence */
    public Long getId() {

        return this.id;
    }

    public String getTitle() {

        return this.title;
    }

    public Date getDate() {

        return new Date(this.date.getTime());
    }

    /** @return Nonnull people registered for this event, if any. */
    public Set<Person> getRegistrants() {

        return new HashSet<Person> (this.registrants);
    }

    /* Update methods */

    public void register(Person person) {

        this.registrants.add(person);
    }
}
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!


duf*_*ymo 2

我假设您在使用Hibernate 参考文档时遇到了问题?

也许这个 Hibernate 教程会更好。