- PVSM.RU - https://www.pvsm.ru -

Spring MVC 3, Аннотации Hibernate, MySQL. Туториал по интеграции

Не так давно я начал изучать фреймворк Spring и понял, что количество материала на русском языке ограниченно буквально парой стоящих статей. По быстрому пробежав, я захотел сделать что-то более интересное, но с наскоку взять не удалось. Пришлось погуглить по поводу нескольких вопросов касательно взаимодействия Spring и Hibernate. Неожиданно я наткнулся на блог [1] достаточно интересного разработчика Mark Serrano aka krams. Теперь вместе с вами я хотел бы начать цикл статей-переводов, а так же свое обучение в мире Spring.

Приступим…

В этом уроке мы создадим простое приложение для управления списком лиц с использованием Spring MVC 3. Мы построим простую CRUD (Create Read Update Delete) систему для просмотра, добавления, правки и удаления персон. В качестве слоя для работы с базой данных мы будем использовать Hibernate 3 и базу MySQL, хотя вы можете использовать другую базу данных. В этом уроке предполагается, что вы знакомы с MVC, ORM и SQL (от переводчика: не пугайтесь этих сложных слов, смело читаем, все будет довольно просто)

Что такое Hibernate?

Hibernate — библиотека для языка программирования Java, предназначенная для решения задач объектно-реляционного отображения (object-relational mapping — ORM). Данная библиотека предоставляет лёгкий в использовании каркас (фреймворк) для отображения объектно-ориентированной модели данных в традиционные реляционные базы данных.

Hibernate решает проблему между хранением объекта в базе данных и его объектно-ориентированном представлении на уровне языка.

Что такое MySQL?

База данных MySQL обеспечивает работу наиболее требовательных сетей, электронной комерции и обработки транзакций приложений. Она гарантирует безопасность транзакций, ACID совместимость дает возможность комита, отката, восстановления в случае сбоя, а также возможностей блокировки строк. MySQL обеспечивает простоту использования, масштабируемость и производительность, эти качества сделали MySQL наиболее популярной базой данных с открытым исходным кодом в мире. Некоторые из наиболее посещаемых ресурсов сети использует MySQL, такие как Facebook, Google, Ticketmaster и Ebay.

В начале давайте посмотрим на конечную структуру нашего проекта:

image

И посмотрим, как будет выглядеть наше приложение:

image

Мы начнем с определения нашего доменного объекта Person (сущности Person).

Person

package org.krams.tutorial.domain;
 
import java.io.Serializable;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
 
/**
 * For a complete reference see
 * <a href="http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/">
 * Hibernate Annotations Communit Documentations</a>
 */
@Entity
@Table(name = "PERSON")
public class Person implements Serializable {
 
 private static final long serialVersionUID = -5527566248002296042L;
  
 @Id
 @Column(name = "ID")
 @GeneratedValue
 private Integer id;
  
 @Column(name = "FIRST_NAME")
 private String firstName;
  
 @Column(name = "LAST_NAME")
 private String lastName;
  
 @Column(name = "MONEY")
 private Double money;
 
 public Integer getId() {
  return id;
 }
 
 public void setId(Integer id) {
  this.id = id;
 }
 
 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 Double getMoney() {
  return money;
 }
 
 public void setMoney(Double money) {
  this.money = money;
 }
}

Person простой POJO содержащий четыре приватных переменных:

id
firstName
lastName
money

Дополнение от переводчика: POJO (англ. Plain Old Java Object) — «простой Java-объект в старом стиле», простой Java-объект, не унаследованный от какого-то специфического объекта и не реализующий никаких служебных интерфейсов сверх тех, которые нужны для бизнес-модели (Wiki)

Каждой из этих переменных с аннотацией @Column соответствует колонка в базе данных:

ID
FIRST_NAME
LAST_NAME
MONEY

Вам нет необходимости иметь с ними дело, Hibernate возьмет это на себя. Тем не менее вы должны правильно объявить эти имена (например @Column(name = ``ID``)). Вы не объявляете их в базе данных. Помните — вашей базы данных еще не существует.

POJO ссылается на таблицу вашей базы данных, обратите внимание на аннотацию Table [2], где указано имя таблицы соответствующей данному объекту.

@Entity
@Table(name = "PERSON")
public class Person implements Serializable

Обратите внимание, аннотация Entity [3] стоит перед аннотацие Table [2], это говорит Hibernate, что POJO является отображением таблицы базы данных.

Мы будем манипулирувать списком лиц, поэтому создадим для этого сервис:

PersonService

package org.krams.tutorial.service;
 
import java.util.List;
 
import javax.annotation.Resource;
 
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.krams.tutorial.domain.Person;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
/**
 * Service for processing Persons
 *
 */
@Service("personService")
@Transactional
public class PersonService {
 
 protected static Logger logger = Logger.getLogger("service");
  
 @Resource(name="sessionFactory")
 private SessionFactory sessionFactory;
  
 /**
  * Retrieves all persons
  *
  * @return a list of persons
  */
 public List<person> getAll() {
  logger.debug("Retrieving all persons");
   
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
   
  // Create a Hibernate query (HQL)
  Query query = session.createQuery("FROM  Person");
   
  // Retrieve all
  return  query.list();
 }
  
 /**
  * Retrieves a single person
  */
 public Person get( Integer id ) {
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
   
  // Retrieve existing person first
  Person person = (Person) session.get(Person.class, id);
   
  return person;
 }
 /**
  * Adds a new person
  */
 public void add(Person person) {
  logger.debug("Adding new person");
   
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
   
  // Save
  session.save(person);
 }
  
 /**
  * Deletes an existing person
  * @param id the id of the existing person
  */
 public void delete(Integer id) {
  logger.debug("Deleting existing person");
   
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
   
  // Retrieve existing person first
  Person person = (Person) session.get(Person.class, id);
   
  // Delete
  session.delete(person);
 }
  
 /**
  * Edits an existing person
  */
 public void edit(Person person) {
  logger.debug("Editing existing person");
   
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
   
  // Retrieve existing person via id
  Person existingPerson = (Person) session.get(Person.class, person.getId());
   
  // Assign updated values to this person
  existingPerson.setFirstName(person.getFirstName());
  existingPerson.setLastName(existingPerson.getLastName());
  existingPerson.setMoney(existingPerson.getMoney());
 
  // Save updates
  session.save(existingPerson);
 }
}

Мы объявили простую CRUD систему со следующими методами:

getAll()
add()
delete()
edit()

В каждом методе мы получаем сессию:

Session session = sessionFactory.getCurrentSession();

Это похоже на соединение с базой данных, так что мы можем делать нашу работу. Объект Session предоставляет множество методов для работы объектами-сущностями. Для этого урока мы используем следующие методы класса Session:

session.createQuery()
session.save()
session.delete()

Мы создали доменный и сервисный слои, давайте создадим Spring контроллер.

MainController

package org.krams.tutorial.controller;
 
import java.util.List;
 
import javax.annotation.Resource;
 
import org.apache.log4j.Logger;
import org.krams.tutorial.domain.Person;
import org.krams.tutorial.service.PersonService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
 
 
/**
 * Handles and retrieves person request
 */
@Controller
@RequestMapping("/main")
public class MainController {
 
 protected static Logger logger = Logger.getLogger("controller");
  
 @Resource(name="personService")
 private PersonService personService;
  
 /**
  * Handles and retrieves all persons and show it in a JSP page
  *
  * @return the name of the JSP page
  */
    @RequestMapping(value = "/persons", method = RequestMethod.GET)
    public String getPersons(Model model) {
      
     logger.debug("Received request to show all persons");
      
     // Retrieve all persons by delegating the call to PersonService
     List<person> persons = personService.getAll();
      
     // Attach persons to the Model
     model.addAttribute("persons", persons);
      
     // This will resolve to /WEB-INF/jsp/personspage.jsp
     return "personspage";
 }
     
    /**
     * Retrieves the add page
     *
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/persons/add", method = RequestMethod.GET)
    public String getAdd(Model model) {
     logger.debug("Received request to show add page");
     
     // Create new Person and add to model
     // This is the formBackingOBject
     model.addAttribute("personAttribute", new Person());
 
     // This will resolve to /WEB-INF/jsp/addpage.jsp
     return "addpage";
 }
  
    /**
     * Adds a new person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     *
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/add", method = RequestMethod.POST)
    public String add(@ModelAttribute("personAttribute") Person person) {
  logger.debug("Received request to add new person");
   
     // The "personAttribute" model has been passed to the controller from the JSP
     // We use the name "personAttribute" because the JSP uses that name
   
  // Call PersonService to do the actual adding
  personService.add(person);
 
     // This will resolve to /WEB-INF/jsp/addedpage.jsp
  return "addedpage";
 }
     
    /**
     * Deletes an existing person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     *
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/delete", method = RequestMethod.GET)
    public String delete(@RequestParam(value="id", required=true) Integer id,
              Model model) {
    
  logger.debug("Received request to delete existing person");
   
  // Call PersonService to do the actual deleting
  personService.delete(id);
   
  // Add id reference to Model
  model.addAttribute("id", id);
      
     // This will resolve to /WEB-INF/jsp/deletedpage.jsp
  return "deletedpage";
 }
     
    /**
     * Retrieves the edit page
     *
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/persons/edit", method = RequestMethod.GET)
    public String getEdit(@RequestParam(value="id", required=true) Integer id, 
              Model model) {
     logger.debug("Received request to show edit page");
     
     // Retrieve existing Person and add to model
     // This is the formBackingOBject
     model.addAttribute("personAttribute", personService.get(id));
      
     // This will resolve to /WEB-INF/jsp/editpage.jsp
     return "editpage";
 }
     
    /**
     * Edits an existing person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     *
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/edit", method = RequestMethod.POST)
    public String saveEdit(@ModelAttribute("personAttribute") Person person,
                 @RequestParam(value="id", required=true) Integer id,
                Model model) {
     logger.debug("Received request to update person");
     
     // The "personAttribute" model has been passed to the controller from the JSP
     // We use the name "personAttribute" because the JSP uses that name
      
     // We manually assign the id because we disabled it in the JSP page
     // When a field is disabled it will not be included in the ModelAttribute
     person.setId(id);
      
     // Delegate to PersonService for editing
     personService.edit(person);
      
     // Add id reference to Model
  model.addAttribute("id", id);
   
     // This will resolve to /WEB-INF/jsp/editedpage.jsp
  return "editedpage";
 }
     
}

Контроллер объявляет следующие представления:

/persons — для получения всех лиц
/persons/add (GET) — показать форму «Добавить»
/persons/add (POST) — сохраняет новую персону
/persons/delete — удаляет существующую персону
/persons/edit (GET) — показывает форму «Правка»
/persons/edit (POST) — сохраняет «исправленную» персону

Каждое представление вызывает PersonService. Когда PersonService завершает обработку, крнтроллер пересылает запрос на JSP-страницу, которая показывает сообщение с подтверждением. Вот страницы JSP:

personspage.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Persons</h1>
 
<c:url var="addUrl" value="/krams/main/persons/add" />
<table style="border: 1px solid; width: 500px; text-align:center">
 <thead style="background:#fcf">
  <tr>
   <th>First Name</th>
   <th>Last Name</th>
   <th>Money</th>
   <th colspan="3"></th>
  </tr>
 </thead>
 <tbody>
 <c:forEach items="${persons}" var="person">
   <c:url var="editUrl" value="/krams/main/persons/edit?id=${person.id}" />
   <c:url var="deleteUrl" value="/krams/main/persons/delete?id=${person.id}" />
  <tr>
   <td><c:out value="${person.firstName}" /></td>
   <td><c:out value="${person.lastName}" /></td>
   <td><c:out value="${person.money}" /></td>
   <td><a href="${editUrl}">Edit</a></td>
   <td><a href="${deleteUrl}">Delete</a></td>
   <td><a href="${addUrl}">Add</a></td>
  </tr>
 </c:forEach>
 </tbody>
</table>
 
<c:if test="${empty persons}">
 There are currently no persons in the list. <a href="${addUrl}">Add</a> a person.
</c:if>
 
</body>
</html>

editpage.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 
<h1>Edit Person</h1>
<c:url var="saveUrl" value="/krams/main/persons/edit?id=${personAttribute.id}" />
<form:form modelAttribute="personAttribute" method="POST" action="${saveUrl}">
 <table>
  <tr>
   <td><form:label path="id">Id:</form:label></td>
   <td><form:input path="id" disabled="true"/></td>
  </tr>
  
  <tr>
   <td><form:label path="firstName">First Name:</form:label></td>
   <td><form:input path="firstName"/></td>
  </tr>
 
  <tr>
   <td><form:label path="lastName">Last Name</form:label></td>
   <td><form:input path="lastName"/></td>
  </tr>
   
  <tr>
   <td><form:label path="money">Money</form:label></td>
   <td><form:input path="money"/></td>
  </tr>
 </table>
  
 <input type="submit" value="Save" />
</form:form>
 
</body>
</html>

addpage.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 
<h1>Create New Person</h1>
<c:url var="saveUrl" value="/krams/main/persons/add" />
<form:form modelAttribute="personAttribute" method="POST" action="${saveUrl}">
 <table>
  <tr>
   <td><form:label path="firstName">First Name:</form:label></td>
   <td><form:input path="firstName"/></td>
  </tr>
 
  <tr>
   <td><form:label path="lastName">Last Name</form:label></td>
   <td><form:input path="lastName"/></td>
  </tr>
   
  <tr>
   <td><form:label path="money">Money</form:label></td>
   <td><form:input path="money"/></td>
  </tr>
 </table>
  
 <input type="submit" value="Save" />
</form:form>
 
</body>
</html>

editedpage.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="java.util.Date" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 
<h1>Persons</h1>
<p>You have edited a person with id ${id} at <%= new java.util.Date() %></p>
 
<c:url var="mainUrl" value="/krams/main/persons" />
<p>Return to <a href="${mainUrl}">Main List</a></p>
 
</body>
</html>

addedpage.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="java.util.Date" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 
<h1>Persons</h1>
<p>You have added a new person at <%= new java.util.Date() %></p>
 
<c:url var="mainUrl" value="/krams/main/persons" />
<p>Return to <a href="${mainUrl}">Main List</a></p>
 
</body>
</html>

deletedpage.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="java.util.Date" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 
<h1>Persons</h1>
<p>You have deleted a person with id ${id} at <%= new java.util.Date() %></p>
 
<c:url var="mainUrl" value="/krams/main/persons" />
<p>Return to <a href="${mainUrl}">Main List</a></p>
 
</body>
</html>

Давайте сконфигурируем наше приложение.
Для работы Spring MVC в web.xml добавим:

web.xml

<servlet>
  <servlet-name>spring</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
  
 <servlet-mapping>
  <servlet-name>spring</servlet-name>
  <url-pattern>/krams/*</url-pattern>
 </servlet-mapping>
 
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

Обратите внимание на шаблон URL. При обращении к страницам нашего приложения к имени хоста должна быть добавка в виде:

/krams

В web.xml мы указали в качестве имени сервлета spring. По соглашению мы также должны создать файл spring-servlet.xml.

spring-servlet.xml

<!-- Declare a view resolver -->
 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

Мы также должны создать файл applicationContext.xml.

applicationContext.xml

<!-- Activates various annotations to be detected in bean classes -->
 <context:annotation-config />
  
 <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
  For example @Controller and @Service. Make sure to set the correct base-package-->
 <context:component-scan base-package="org.krams.tutorial" />
  
 <!-- Configures the annotation-driven Spring MVC Controller programming model.
 Note that, with Spring 3.0, this tag works in Servlet MVC only!  -->
 <mvc:annotation-driven />
  
 <!-- Load Hibernate related configuration -->
 <import resource="hibernate-context.xml" />

Обратите внимание, что в файле applicationContext.xml мы объявили следующий импорт:

<import resource="hibernate-context.xml" />

Он содержит файлы конфигурации Hibernate.

Hibernate-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
      ">
 
 <context:property-placeholder location="/WEB-INF/spring.properties" />
     
    <!-- Enable annotation style of managing transactions -->
 <tx:annotation-driven transaction-manager="transactionManager" />
    
    <!-- Declare the Hibernate SessionFactory for retrieving Hibernate sessions -->
    <!-- See http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.html -->       
 <!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/SessionFactory.html -->
 <!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/Session.html -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
     p:dataSource-ref="dataSource"
     p:configLocation="${hibernate.config}"
     p:packagesToScan="org.krams.tutorial"/>
  
 <!-- Declare a datasource that has pooling capabilities--> 
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close"
    p:driverClass="${app.jdbc.driverClassName}"
    p:jdbcUrl="${app.jdbc.url}"
    p:user="${app.jdbc.username}"
    p:password="${app.jdbc.password}"
    p:acquireIncrement="5"
    p:idleConnectionTestPeriod="60"
    p:maxPoolSize="100"
    p:maxStatements="50"
    p:minPoolSize="10" />
 
 <!-- Declare a transaction manager-->
 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
          p:sessionFactory-ref="sessionFactory" />
   
</beans>

В этом файле мы инкапсулировали все связанные конфигурации Hibernate и Spring.
Комментарии по конфигурации:

1. Включаем поддержку транзакций через использование аннотаций Spring.

<tx:annotation-driven transaction-manager="transactionManager" />

2. Объявили SessionFactory для Hibernate.


<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
     p:dataSource-ref="dataSource"
     p:configLocation="${hibernate.config}"
     p:packagesToScan="org.krams.tutorial"/>

SessionFactory — фабрика, генерирующая нам объяекты-сессии. Это похоже на Автомобильный завод, работа которого заключается в производстве автомобилей для людей.

Что такое сессия (Session)?

Основная функция Сессии — создание, чтение, удаление объектов классов-сущностей(классов помеченных аннотацией Entity [3]).

Для SessionFactory требуется источник данных, которым в данном уроке является база данных.
SessionFactory требует наличие файла со специфической конфигурацией Hibernate.

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>
   <!-- We're using MySQL database so the dialect needs to MySQL as well-->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
    <!-- Enable this to see the SQL statements in the logs-->
    <property name="show_sql">false</property>
    <!-- This will drop our existing database and re-create a new one.
      Existing data will be deleted! -->
    <property name="hbm2ddl.auto">create</property>
  </session-factory>
</hibernate-configuration>

Здесь мы указали тип нашей базы данных. Мы используем MySQL dialect. Мы используем особенный диалект — MySQL5InnoDBDialect, потому что мы используем потому что мы используем InnoDB движок для управления памятью.

Что такое MySQL InnoDB?

InnoDB — MySQL движок, обеспечивающий безопасность транзакций, позволяющий комиты, откат и восстановление для защиты пользовательских данных.

Так вот, вернемся обратно к бину SessionFactory, ему необходимо знать, где расположены наши объекты-сущности. Поэтому мы указываем в этом уроке, что они расположены в пакете org.krams.tutorial.

3. Укажем в файле hibernate-context.xml источники данных.

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
 destroy-method="close"
 p:driverClass="${app.jdbc.driverClassName}"
 p:jdbcUrl="${app.jdbc.url}"
 p:user="${app.jdbc.username}"
 p:password="${app.jdbc.password}"
 p:acquireIncrement="5"
 p:idleConnectionTestPeriod="60"
 p:maxPoolSize="100"
 p:maxStatements="50"
 p:minPoolSize="10" />

Для эффективного доступа к нашей базе данных мы используем C3p0 пул. Зачем нам необходимо оборачивать наши данные в пул?

Соединения JDBC чаще управляются через пул, нежели напрямую через драйвер. Примеры пулов соединений BoneCP, C3P0 и DBCP.

Зачем нужен пул?

При разработке программного пул соединений является кешем для открытых соединений. Пулы необходимы для повышения производительности. Открытие и проведение соединения с базой, каждым пользователем, требуют много ресурсов. А при использовании пулов, требуется только извлечь нужное соединение из кеша, а не снова устанавливать соединение.

Особенности подкдючения к базе данных мы указываем в файле spring.properties.

spring.properties

# database properties
app.jdbc.driverClassName=com.mysql.jdbc.Driver
app.jdbc.url=jdbc:mysql://localhost/mydatabase
app.jdbc.username=root
app.jdbc.password=
 
#hibernate properties
hibernate.config=/WEB-INF/hibernate.cfg.xml

Имя моей базы данных — mydatabase.

Как альтернатива мы можем указать эти особенности прям в файле hibernate-context.xml.

Преимущество использования раздельных файлов—конфигураций, в инкапсуляции данных касающихся соединения с базой данных.

Мы завершили наше приложение. Нам удалось создать простое Spring MVC приложение с использованием Hibernate, для доступа к MySQL.

Для доступа к главной странице введите следующий URL: localhost [4]:8080/spring-hibernate-mysql/krams/main/persons

Лучший способ изучения — попытаться создать приложение самому.

Для скачивания проекта перейдите по ссылке: spring-mvc-hibernate-annotations-integration-tutorial.googlecode.com/files/spring-hibernate-mysql.zip [5]

UPD: Как и обещал — ссылка на github: github.com/sa4ek/spring-hibernate-mysql/tree/master [6]

Автор: Sa4ek

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/java/80305

Ссылки в тексте:

[1] блог: http://krams915.blogspot.ru

[2] Table: http://habrahabr.ru/users/table/

[3] Entity: http://habrahabr.ru/users/entity/

[4] localhost: http://localhost

[5] spring-mvc-hibernate-annotations-integration-tutorial.googlecode.com/files/spring-hibernate-mysql.zip: http://spring-mvc-hibernate-annotations-integration-tutorial.googlecode.com/files/spring-hibernate-mysql.zip

[6] github.com/sa4ek/spring-hibernate-mysql/tree/master: https://github.com/sa4ek/spring-hibernate-mysql/tree/master

[7] Источник: http://habrahabr.ru/post/248541/