使用了maven之后我们可以将项目的构件与发布变得非常的简单。Maven与Hibernate也是可以结合在一起的。首先我们创建一个Maven的项目。在依赖中我们要加入Hibernate的依赖,pom文件可以这样写:
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernate.tutorials</groupId>
<artifactId>hibernate-tutorial</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>First Hibernate Tutorial</name>
<dependencies>
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>4.0.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jandex</artifactId>
<version>1.2.2.Final</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.2-GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.1.0.CR2</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.1_spec</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-annotations</artifactId>
<version>1.2.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0-6</version>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>javaee-api</artifactId>
<version>5.0-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
同时要手工创建一些必须的包,建好之后的项目文件结构如下:
然后按照正常的Hibernate的编写顺序写配置文件,Entity类以及Mapping文件:
hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="Event.hbm.xml"/>
<mapping resource="Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Event.java:
package com.smile.pansoft.mavenhibernate.domains;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Event {
private int id;
private String title;
private Date date;
private Set participants = new HashSet();
public Event() {}
public int getId() {
return id;
}
private void setId(int id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Set getParticipants() {
return participants;
}
public void setParticipants(Set participants) {
this.participants = participants;
}
}
Event.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.smile.pansoft.mavenhibernate.domains">
<class name="Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="native"/>
</id>
<property name="date" type="timestamp" column="EVENT_DATE"/>
<property name="title"/>
<!-- inverse=“true” -->
<set name="participants" table="PERSON_EVENT" inverse="true">
<key column="EVENT_ID"/>
<many-to-many column="PERSON_ID" class="Person"/>
</set>
</class>
</hibernate-mapping>
Person.java:
package com.smile.pansoft.mavenhibernate.domains;
import java.util.HashSet;
import java.util.Set;
public class Person {
private int id;
private int age;
private String firstname;
private String lastname;
private Set events = new HashSet();
private Set emailAddresses = new HashSet();
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Set getEvents() {
return events;
}
public void setEvents(Set events) {
this.events = events;
}
public void addToEvent(Event event) {
this.getEvents().add(event);
event.getParticipants().add(this);
}
public void removeFromEvent(Event event) {
this.getEvents().remove(event);
event.getParticipants().remove(this);
}
public Set getEmailAddresses() {
return emailAddresses;
}
public void setEmailAddresses(Set emailAddresses) {
this.emailAddresses = emailAddresses;
}
}
Person.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.smile.pansoft.mavenhibernate.domains">
<class name="Person" table="PERSON">
<id name="id" column="PERSON_ID">
<generator class="native"/>
</id>
<property name="age"/>
<property name="firstname"/>
<property name="lastname"/>
<set name="events" table="PERSON_EVENT">
<key column="PERSON_ID"/>
<many-to-many column="EVENT_ID" class="Event"/>
</set>
<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
<key column="PERSON_ID"/>
<element type="string" column="EMAIL_ADDR"/>
</set>
</class>
</hibernate-mapping>
这里需要注意的是用到的是many-to-many的设置,其中还用到了一个element的设置。具体的数据库表结构为:
各个文件位置如下:
配置文件全都放到resources目录的下面,注意引用时的路径。
可以先建立测试类进行测试,注意测试类名字的命名规则,在之前的文章中已有介绍:
EventManagerTest.java:
package com.smile.pansoft.mavenhibernate.test;
import org.hibernate.Session;
import org.junit.Test;
import com.smile.pansoft.mavenhibernate.domains.Event;
import com.smile.pansoft.mavenhibernate.domains.Person;
import com.smile.pansoft.mavenhibernate.util.HibernateUtil;
public class EventManagerTest {
public static void main(String[] args) {
EventManagerTest mgr = new EventManagerTest();
// mgr.createAndStoreEvent("My Event", new Date());
HibernateUtil.getSessionFactory().close();
}
/*
@Test
public void createAndStoreEvent() {
System.out.println("start test");
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Event theEvent = new Event();
theEvent.setTitle("teacher");
theEvent.setDate(new Date());
session.save(theEvent);
session.getTransaction().commit();
}
@Test
public void listEvents() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List result = session.createQuery("from Event").list();
session.getTransaction().commit();
for (int i = 0; i < result.size(); i++) {
Event theEvent = (Event) result.get(i);
System.out.println(
"Event: " + theEvent.getTitle() + " Time: " + theEvent.getDate()
);
}
}
*/
@Test
public void addPersonToEvent() {
//第一種方式 直接操作list 這樣直接在persistent状态进行操作时,Hibernate会直接进行校验automatic dirty checking 直接持久化到数据库中
// Session session = HibernateUtil.getSessionFactory().getCurrentSession();
// session.beginTransaction();
//
// Person aPerson = (Person) session.load(Person.class, 1);
// Event anEvent = (Event) session.load(Event.class, 1);
// aPerson.getEvents().add(anEvent);
// System.out.println(aPerson.getFirstname());
// Set stuSet = aPerson.getEvents();
// System.out.println(stuSet.size());
// session.getTransaction().commit();
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
//fetch的作用 Hibernate默认的load方式是lazy只会加载当前对象 而对于list不进行加载 而当我们设置lazy=false的时候 又会全部加载 所以使用fetch可以主动进行提取 进行热加载
Person aPerson = (Person) session
.createQuery("select p from Person p left join fetch p.events where p.id = :pid")
.setParameter("pid", 2)
.uniqueResult(); // Eager fetch the collection so we can use it detached
Event anEvent = (Event) session.load(Event.class, 2);
session.getTransaction().commit();
// End of first unit of work
aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
// Begin second unit of work
Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
session2.beginTransaction();
session2.update(aPerson); // Reattachment of aPerson
session2.getTransaction().commit();
}
@Test
public void addEmailToPerson() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person aPerson = (Person) session.load(Person.class, 1);
// adding to the emailAddress collection might trigger a lazy load of the collection
aPerson.getEmailAddresses().add("ga_smile_nk@sina.com");
session.getTransaction().commit();
}
}
HibernateUtil.java:
package com.smile.pansoft.mavenhibernate.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
// SessionFactory sc = new Configuration().configure().buildSessionFactory(
// new StandardServiceRegistryBuilder().build());
Configuration cfg = new Configuration().configure();
SessionFactory sc = cfg.buildSessionFactory(new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build());
return sc;
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
可以在IDE中直接执行测试类的方法。或者使用mvn的test命令进行执行,执行结果如下:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.smile.pansoft.mavenhibernate.test.EventManagerTest
09:06:51,881 WARN org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl:93 - HHH000402: Using Hibernate built-in connection pool (not for production use!)
09:06:52,780 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:182 - HHH000228: Running hbm2ddl schema update
09:06:52,781 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:193 - HHH000102: Fetching database metadata
09:06:52,783 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:205 - HHH000396: Updating schema
09:06:52,808 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.events
09:06:52,809 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [title, event_date, event_id]
09:06:52,809 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: []
09:06:52,810 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [primary]
09:06:52,819 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.person
09:06:52,820 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [person_id, age, lastname, firstname]
09:06:52,821 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: []
09:06:52,821 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [primary]
09:06:52,832 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.person_email_addr
09:06:52,833 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [person_id, email_addr]
09:06:52,833 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [fk_fipu5nseny7muu1yknf93rf3e]
09:06:52,835 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [fk_fipu5nseny7muu1yknf93rf3e]
09:06:52,846 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.person_event
09:06:52,847 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [person_id, event_id]
09:06:52,847 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [fk_8xsbl2jbyqaf5ocifr7hcjt2x, fk_7bh2i9xjn8v93x5ku5w61npwf]
09:06:52,848 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [primary, fk_7bh2i9xjn8v93x5ku5w61npwf]
09:06:52,849 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:242 - HHH000232: Schema update complete
Hibernate:
select
person0_.PERSON_ID as PERSON_I1_1_0_,
person0_.age as age2_1_0_,
person0_.firstname as firstnam3_1_0_,
person0_.lastname as lastname4_1_0_
from
PERSON person0_
where
person0_.PERSON_ID=?
Hibernate:
select
emailaddre0_.PERSON_ID as PERSON_I1_1_0_,
emailaddre0_.EMAIL_ADDR as EMAIL_AD2_2_0_
from
PERSON_EMAIL_ADDR emailaddre0_
where
emailaddre0_.PERSON_ID=?
Hibernate:
select
person0_.PERSON_ID as PERSON_I1_1_0_,
event2_.EVENT_ID as EVENT_ID1_0_1_,
person0_.age as age2_1_0_,
person0_.firstname as firstnam3_1_0_,
person0_.lastname as lastname4_1_0_,
event2_.EVENT_DATE as EVENT_DA2_0_1_,
event2_.title as title3_0_1_,
events1_.PERSON_ID as PERSON_I2_1_0__,
events1_.EVENT_ID as EVENT_ID1_3_0__
from
PERSON person0_
left outer join
PERSON_EVENT events1_
on person0_.PERSON_ID=events1_.PERSON_ID
left outer join
EVENTS event2_
on events1_.EVENT_ID=event2_.EVENT_ID
where
person0_.PERSON_ID=?
Hibernate:
update
PERSON
set
age=?,
firstname=?,
lastname=?
where
PERSON_ID=?
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.942 sec
Results :
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.849 s
[INFO] Finished at: 2014-12-23T09:06:53+08:00
[INFO] Final Memory: 7M/18M
[INFO] ------------------------------------------------------------------------
这样就完成了Hibernate与maven的集成。在Hibernate中有一个比较重要的内容较Open Session in View。这里我们写一个Servlet进行简单的演示。
首先把我们当前的项目转换为web project。这步就不再赘述。
然后我们新建一个Servlet叫EventManagerServlet:
package com.smile.pansoft.mavenhibernate.web;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.smile.pansoft.mavenhibernate.domains.Event;
import com.smile.pansoft.mavenhibernate.util.HibernateUtil;
//Imports
public class EventManagerServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
try {
// Begin unit of work
HibernateUtil.getSessionFactory().getCurrentSession()
.beginTransaction();
// Process request and render page...
// Write HTML header
PrintWriter out = response.getWriter();
out.println("<html><head><title>Event Manager</title></head><body>");
// Handle actions
if ("store".equals(request.getParameter("action"))) {
String eventTitle = request.getParameter("eventTitle");
String eventDate = request.getParameter("eventDate");
if ("".equals(eventTitle) || "".equals(eventDate)) {
out.println("<b><i>Please enter event title and date.</i></b>");
} else {
createAndStoreEvent(eventTitle,
dateFormatter.parse(eventDate));
out.println("<b><i>Added event.</i></b>");
}
}
// Print page
printEventForm(out);
listEvents(out, dateFormatter);
// Write HTML footer
out.println("</body></html>");
out.flush();
out.close();
// End unit of work
HibernateUtil.getSessionFactory().getCurrentSession()
.getTransaction().commit();
} catch (Exception ex) {
HibernateUtil.getSessionFactory().getCurrentSession()
.getTransaction().rollback();
if (ServletException.class.isInstance(ex)) {
throw (ServletException) ex;
} else {
throw new ServletException(ex);
}
}
}
private void printEventForm(PrintWriter out) {
out.println("<h2>Add new event:</h2>");
out.println("<form>");
out.println("Title: <input name='eventTitle' length='50'/><br/>");
out.println("Date (e.g. 24.12.2009): <input name='eventDate' length='10'/><br/>");
out.println("<input type='submit' name='action' value='store'/>");
out.println("</form>");
}
private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) {
List result = HibernateUtil.getSessionFactory()
.getCurrentSession().createCriteria(Event.class).list();
if (result.size() > 0) {
out.println("<h2>Events in database:</h2>");
out.println("<table border='1'>");
out.println("<tr>");
out.println("<th>Event title</th>");
out.println("<th>Event date</th>");
out.println("</tr>");
Iterator it = result.iterator();
while (it.hasNext()) {
Event event = (Event) it.next();
out.println("<tr>");
out.println("<td>" + event.getTitle() + "</td>");
out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>");
out.println("</tr>");
}
out.println("</table>");
}
}
protected void createAndStoreEvent(String title, Date theDate) {
Event theEvent = new Event();
theEvent.setTitle(title);
theEvent.setDate(theDate);
HibernateUtil.getSessionFactory()
.getCurrentSession().save(theEvent);
}
}
这个Servlet包含了添加和展示的操作。
这时候我们在pom.xml中增加如下配置:
<packaging>war</packaging>
<build>
<finalName>web-app-event</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.5</version>
<configuration>
<outputDirectory>E:\SSH_Maven</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
表明我们打包整war包,默认是jar。
然后执行mvn install或者mvn package命令:
[INFO] --- maven-war-plugin:2.5:war (default-war) @ hibernate-tutorial ---
[INFO] Packaging webapp
[INFO] Assembling webapp [hibernate-tutorial] in [E:\SSH_Maven\maven-hibernate\target\web-app-event]
[INFO] Processing war project
[INFO] Copying webapp resources [E:\SSH_Maven\maven-hibernate\src\main\webapp]
[INFO] Webapp assembled in [125 msecs]
[INFO] Building war: E:\SSH_Maven\web-app-event.war
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hibernate-tutorial ---
[INFO] Installing E:\SSH_Maven\web-app-event.war to E:\Maven\m2\repository\org\hibernate\tutorials\hibernate-tutorial\1.0.0-SNAPSHOT\hibernate-tutorial-1.0.0-SNAPSHOT.war
[INFO] Installing E:\SSH_Maven\maven-hibernate\pom.xml to E:\Maven\m2\repository\org\hibernate\tutorials\hibernate-tutorial\1.0.0-SNAPSHOT\hibernate-tutorial-1.0.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.995 s
[INFO] Finished at: 2014-12-23T09:13:19+08:00
[INFO] Final Memory: 9M/22M
[INFO] ------------------------------------------------------------------------
war包就会直接打到我们制定的目录下。我们将war包拷贝到应用服务器下面,然后进行访问。
一个简单的添加展示界面就显示出来了。这也算是一个maven对Hibernate的web项目的集成吧。