Глава 17. Пример: Weblog-Приложение

17.1. Долгоживущие Классы (Persistent Classes)

Долгоживущие классы представляют сам weblog и заметки, которые были отосланы в него. Взаимоотношение между данными сущностями будет замэплено как стандартное отношение родитель/ребенок (parent/child), но мы будем использовать упорядоченный bag (ordered bag) вместо множества (set).

package eg;

import java.util.List;

public class Blog {
private Long _id;
private String _name;
private List _items;

public Long getId() {
return _id;
}
public List getItems() {
return _items;
}
public String getName() {
return _name;
}
public void setId(Long long1) {
_id = long1;
}
public void setItems(List list) {
_items = list;
}
public void setName(String string) {
_name = string;
}
}
package eg;

import java.text.DateFormat;
import java.util.Calendar;

public class BlogItem {
private Long _id;
private Calendar _datetime;
private String _text;
private String _title;
private Blog _blog;

public Blog getBlog() {
return _blog;
}
public Calendar getDatetime() {
return _datetime;
}
public Long getId() {
return _id;
}
public String getText() {
return _text;
}
public String getTitle() {
return _title;
}
public void setBlog(Blog blog) {
_blog = blog;
}
public void setDatetime(Calendar calendar) {
_datetime = calendar;
}
public void setId(Long long1) {
_id = long1;
}
public void setText(String string) {
_text = string;
}
public void setTitle(String string) {
_title = string;
}
}

17.2. Hibernate-Мэппинг

XML-мэппинг, в данном случае, должен быть достаточно простым.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping package="eg">

<class 
name="Blog" 
table="BLOGS" 
lazy="true">

<id 
name="id" 
column="BLOG_ID">

<generator class="native"/>

</id>

<property 
name="name" 
column="NAME" 
not-null="true" 
unique="true"/>

<bag 
name="items" 
inverse="true" 
lazy="true"
order-by="DATE_TIME" 
cascade="all">

<key column="BLOG_ID"/>
<one-to-many class="BlogItem"/>

</bag>

</class>

</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping package="eg">

<class 
name="BlogItem" 
table="BLOG_ITEMS" 
dynamic-update="true">

<id 
name="id" 
column="BLOG_ITEM_ID">

<generator class="native"/>

</id>

<property 
name="title" 
column="TITLE" 
not-null="true"/>

<property 
name="text" 
column="TEXT" 
not-null="true"/>

<property 
name="datetime" 
column="DATE_TIME" 
not-null="true"/>

<many-to-one 
name="blog" 
column="BLOG_ID" 
not-null="true"/>

</class>

</hibernate-mapping>

17.3. Hibernate-Код

Следующий класс демонстрирует некоторые вещи, которые мы может делать с этими классами, используя Hibernate.

package eg;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.tool.hbm2ddl.SchemaExport;

public class BlogMain {

private SessionFactory _sessions;

public void configure() throws HibernateException {
_sessions = new Configuration()
.addClass(Blog.class)
.addClass(BlogItem.class)
.buildSessionFactory();
}

public void exportTables() throws HibernateException {
Configuration cfg = new Configuration()
.addClass(Blog.class)
.addClass(BlogItem.class);
new SchemaExport(cfg).create(true, true);
}

public Blog createBlog(String name) throws HibernateException {

Blog blog = new Blog();
blog.setName(name);
blog.setItems( new ArrayList() );

Session session = _sessions.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.save(blog);
tx.commit();
}
catch (HibernateException he) {
if (tx!=null) tx.rollback();
throw he;
}
finally {
session.close();
}
return blog;
}

public BlogItem createBlogItem(Blog blog, String title, String text)
throws HibernateException {

BlogItem item = new BlogItem();
item.setTitle(title);
item.setText(text);
item.setBlog(blog);
item.setDatetime( Calendar.getInstance() );
blog.getItems().add(item);

Session session = _sessions.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.update(blog);
tx.commit();
}
catch (HibernateException he) {
if (tx!=null) tx.rollback();
throw he;
}
finally {
session.close();
}
return item;
}

public BlogItem createBlogItem(Long blogid, String title, String text)
throws HibernateException {

BlogItem item = new BlogItem();
item.setTitle(title);
item.setText(text);
item.setDatetime( Calendar.getInstance() );

Session session = _sessions.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Blog blog = (Blog) session.load(Blog.class, blogid);
item.setBlog(blog);
blog.getItems().add(item);
tx.commit();
}
catch (HibernateException he) {
if (tx!=null) tx.rollback();
throw he;
}
finally {
session.close();
}
return item;
}

public void updateBlogItem(BlogItem item, String text)
throws HibernateException {

item.setText(text);

Session session = _sessions.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.update(item);
tx.commit();
}
catch (HibernateException he) {
if (tx!=null) tx.rollback();
throw he;
}
finally {
session.close();
}
}

public void updateBlogItem(Long itemid, String text)
throws HibernateException {

Session session = _sessions.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
BlogItem item = (BlogItem) session.load(BlogItem.class, itemid);
item.setText(text);
tx.commit();
}
catch (HibernateException he) {
if (tx!=null) tx.rollback();
throw he;
}
finally {
session.close();
}
}

public List listAllBlogNamesAndItemCounts(int max)
throws HibernateException {

Session session = _sessions.openSession();
Transaction tx = null;
List result = null;
try {
tx = session.beginTransaction();
Query q = session.createQuery(
"select blog.id, blog.name, count(blogItem) " +
"from Blog as blog " +
"left outer join blog.items as blogItem " +
"group by blog.name, blog.id " +
"order by max(blogItem.datetime)"
);
q.setMaxResults(max);
result = q.list();
tx.commit();
}
catch (HibernateException he) {
if (tx!=null) tx.rollback();
throw he;
}
finally {
session.close();
}
return result;
}

public Blog getBlogAndAllItems(Long blogid)
throws HibernateException {

Session session = _sessions.openSession();
Transaction tx = null;
Blog blog = null;
try {
tx = session.beginTransaction();
Query q = session.createQuery(
"from Blog as blog " +
"left outer join fetch blog.items " +
"where blog.id = :blogid"
);
q.setParameter("blogid", blogid);
blog= (Blog) q.list().get(0);
tx.commit();
}
catch (HibernateException he) {
if (tx!=null) tx.rollback();
throw he;
}
finally {
session.close();
}
return blog;
}

public List listBlogsAndRecentItems() throws HibernateException {

Session session = _sessions.openSession();
Transaction tx = null;
List result = null;
try {
tx = session.beginTransaction();
Query q = session.createQuery(
"from Blog as blog " +
"inner join blog.items as blogItem " +
"where blogItem.datetime > :minDate"
);

Calendar cal = Calendar.getInstance();
cal.roll(Calendar.MONTH, false);
q.setCalendar("minDate", cal);

result = q.list();
tx.commit();
}
catch (HibernateException he) {
if (tx!=null) tx.rollback();
throw he;
}
finally {
session.close();
}
return result;
}
}