gpt4 book ai didi

Hibernate(带有注释)——如何开始

转载 作者:行者123 更新时间:2023-12-03 06:31:14 25 4
gpt4 key购买 nike

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

虽然我只使用过 eclipse,但我对 java 非常熟悉。那么..我在哪里配置它使用的数据库等等?

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

最佳答案

我的经历和背景很相似,而且我也很难找到适合我的开发偏好的教程(这看起来与您的相似):

  • 与 XML 相比,更喜欢 JPA 注释,仅在 JPA 对应项无法满足要求时才添加 Hibernate 注释
  • 使用 Hibernate 的 SessionFactory/Session 来访问持久数据,而不是 JPA EntityManager
  • 尽可能使用不可变类

我读了大部分 Java Persistence with Hibernate ,并且花了很长时间才将该用例与它提供的所有其他选项(Hibernate/JPA 格式的 XML 配置、xdoclet“注释”等)分开。

如果可用的文档能够表明立场并积极插入我朝这个方向发展,而不是给我一堆选择并想知道该去哪里,那对我来说会更有意义。缺乏这一点,我通过转换标准 Hibernate Tutorial 学到了以下教训转到注释。

配置

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

这是我的 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>

范围

  • 在每个 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...
}

数据类

  • 字段是私有(private)的
  • Getter 方法返回防御性副本,因为 Hibernate 可以直接访问字段
  • 除非确实必要,否则不要添加 setter 方法。
  • 当需要更新类中的某些字段时,请以保留封装的方式进行更新。调用类似 event.addPerson(person) 的方法比调用 event.getPeople().add(person) 更安全

例如,我发现 Event 的实现更容易理解,只要您记住 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);
}
}

希望有帮助!

关于Hibernate(带有注释)——如何开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1263425/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com