SpringMVC+Hibernate CRUD Application

I am going to create today a complete End-to-End SpringMVC 3, Hibernate 3 CRUD tutorial which uses MySQL as a database to store records. This will be a simple Bookstore application where user can Create, Update, View of Delete book records. We will use Hibernate 3 as an ORM tool with Spring MVC as a MVC Framework.

In this tutorial you will learn how we integrate SpringMVC with Hibernate using JPA annotations and I will also going to use Spring annotation configuration for Controller, Service and Repository annotations. The main advantage of using @Repository or @Service over @Component is that it’s easy to write an AOP pointcut that targets, for instance, all classes annotated with @Repository.

Upon completion of this tutorial the Application will look like following screenshot.


Lets Start

First of all, We need a SQL Table to save our Books details in RDBMS. You can create this table by the help of Hibernate also but its good to follow Bottom-Up approach to create an Application. Following SQL used to create a Books table in MySQL database.

CREATE TABLE IF NOT EXISTS books (
  id int(10) NOT NULL auto_increment,
  book_name varchar(100) NOT NULL,
  author varchar(100) NOT NULL,
  price int(10) NOT NULL,
  qty int(10) NOT NULL,
  PRIMARY KEY  (id)
);

Hibernate Entity Class: Book

The @Entity annotation is used to mark this class as an Entity bean. So the class should atleast have a package scope no-argument constructor.

The @Table annotation is used to specify the table to persist the data. The name attribute refers to the table name. If @Table annotation is not specified then Hibernate will by default use the class name as the table name.

The @Id annotation is used to specify the identifier property of the entity bean. The placement of the @Id annotation determines the default access strategy that Hibernate will use for the mapping. If the@Id annotation is placed over the field, then filed access will be used. Instead if it placed over the getter method of that field, then property access will be used. Here we use property access.

The @GeneratedValue annotation is used to specify the primary key generation strategy to use. If the strategy is not specified by default AUTO will be used.

package com.mmc.bean;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="books",schema="test")
public class Book {
	@Id
	@Column(name="ID")
	@GeneratedValue
	private Integer id;
	@Column(name="BOOK_NAME")
	private String bookName;
	@Column(name="AUTHOR")
	private String author;
	@Column(name="PRICE")
	private int price;
	@Column(name="QTY")
	private int quantity;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public int getQuantity() {
		return quantity;
	}
	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}
	
	
}

Data Access Layer

Data access layer of our application consist of one BookDoa Interface and its implementation BookDaoImpl class. The BookDaoImpl class has a @Repository annotation which used to enable this class to eligible for persistence exception translation.

package com.mmc.dao;

import java.util.List;

import com.mmc.bean.Book;


public interface BookDao {
	public void addBook(Book book);
	public void updateBook(Book book);
	public List<Book> listBooks();
	public Book getBookById(Integer bookId);
	public void removeBook(Integer id);
}

BookDaoImpl.java
package com.mmc.dao;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.mmc.bean.Book;
@Repository
public class BookDaoImpl implements BookDao {
	@Autowired
	private SessionFactory sessionFactory;
	
	@Override
	public void addBook(Book book) {
		sessionFactory.getCurrentSession().save(book);

	}

	@Override
	public void updateBook(Book book) {
		sessionFactory.getCurrentSession().update(book);

	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Book> listBooks() {
		
		return sessionFactory.getCurrentSession().createQuery("from Book").list();
	}

	@Override
	public Book getBookById(Integer bookId) {
		Session session = sessionFactory.getCurrentSession();
		Query query = session.createQuery("from Book b where b.id = :bookId");
		query.setParameter("bookId", bookId);
		List<Book> list = query.list();
		
		return list.size() > 0 ? (Book)list.get(0) : null;
	}

	@Override
	public void removeBook(Integer id) {
		Book book = (Book)sessionFactory.getCurrentSession().load(Book.class, id);
		if(book!=null){
			sessionFactory.getCurrentSession().delete(book);
		}

	}

}<span style="color:#e04b39;">
</span>

Service Layer

Service layer also consist of one Service interface BookService and its implementation classBookServiceImpl.java. We have annotated BookServiceImpl class with @Service annotation.

package com.mmc.service;


package com.mmc.service;

import java.util.List;

import com.mmc.bean.Book;

public interface BookService {
	public void addBook(Book book);
	public void updateBook(Book book);
	public Book getBookById(Integer bookId);
	public List<Book> listBooks();
	public void removeBook(Integer id);
}

BookServiceImpl.java
<span style="color:#333333;">package com.mmc.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mmc.bean.Book;
import com.mmc.dao.BookDao;
@Service
public class BookServiceImpl implements BookService {
	@Autowired
	private BookDao bookDao;
	@Transactional
	@Override
	public void addBook(Book book) {
		bookDao.addBook(book);

	}
	@Transactional
	@Override
	public void updateBook(Book book) {
		bookDao.updateBook(book);

	}
	@Transactional
	@Override
	public Book getBookById(Integer bookId) {
		
		return bookDao.getBookById(bookId);
	}
	@Transactional
	@Override
	public List<Book> listBooks() {
		
		return bookDao.listBooks();
	}
	@Transactional
	@Override
	public void removeBook(Integer id) {
		bookDao.removeBook(id);

	}

}</span><span style="color:#e04b39;">
</span>

Book Controller

Now create a BookController which will have all the method we need for our CRUD operations. We need to wire the bookService for this controller using @Autowired annotation.

package com.mmc.controller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.mmc.bean.Book;
import com.mmc.service.BookService;

@Controller
public class BookController {
	@Autowired
	private BookService bookService;
	@RequestMapping("/index")
	public String bookList(Map<String, Object> map){
		map.put("book", new Book());
		map.put("listBooks", bookService.listBooks());
		return "book";
	}
	@RequestMapping(value="/book/add",method=RequestMethod.POST)
	public String addBook(@ModelAttribute("book") Book book,BindingResult result){
		if(null == book.getId()){
			bookService.addBook(book);
		} else{
			bookService.updateBook(book);
		}
		return "redirect:/index";
	}
	@RequestMapping(value="/edit/{bookId}")
	public String editBook(@PathVariable("bookId")Integer bookId,
			Map<String, Object> map){
		map.put("book", bookService.getBookById(bookId));
		map.put("listBooks", bookService.listBooks());
		return "book";
	}
	@RequestMapping(value="/delete/{bookId}")
	public String deleteBook(@PathVariable("bookId") Integer bookId){
		bookService.removeBook(bookId);
		return "redirect:/index";
	}
}

SpringMVC Configuration

Now we are all set with our java changes and we need to add spring relate configuration in xml files. First we add DispatcherServlet reference in web.xml file. Following xml tags will add a DispatcherServlet reference to web.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>spring01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <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>/</url-pattern>
	</servlet-mapping>
	
</web-app>

Now create a  jdbc.properties  file which is used to set Database related properties into it. We can add those properties directly into spring xml file but it’s good to create a separate file and have all details of DB into it.
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456

Hibernate Configuration

We have created a Hinerbate Entity Book which is annotation base Entity. The benefit of creating an annotation based Entity class is We don’t need to create a .hbm.xml file for that entity but we need to create hibernate.cfg.xml file for Hibernate related configuration. Following XML shows the mininum Hibernate configuration File.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    
<hibernate-configuration>
	<session-factory>
		<mapping class="com.mmc.bean.Book"/>
	</session-factory>
</hibernate-configuration>

Spring Configuration

Now we need to add spring-servler.xml file which contain all beans and others MVC, Transaction related Tags. XML file is minimal and self-explanatory.

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:lang="http://www.springframework.org/schema/lang"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
		http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
		
	<context:annotation-config></context:annotation-config>
	<context:component-scan base-package="com.mmc"></context:component-scan>
	<mvc:resources location="/images/" mapping="/images/**"/>
	<mvc:annotation-driven/>
	
	<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	
	<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<property name="basename" value="resources/messages" />
		<property name="defaultEncoding" value="UTF-8" />
	</bean>
	
	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
		p:location="/WEB-INF/jdbc.properties" />
		
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
		p:driverClassName="${jdbc.driverClassName}"
		p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
		p:password="${jdbc.password}" />
	
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation">
			<value>resources/hibernate.cfg.xml</value>
		</property>
		<property name="configurationClass">
			<value>org.hibernate.cfg.AnnotationConfiguration</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${jdbc.dialect}</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
	</bean>
	
	<tx:annotation-driven/>
	
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
		
</beans>

View creation

Now last but not the least, creating view to show our Book Add Form. I have also created a Table grid which show the List of all available Books after Book Entry form. You can click on Book Name and it will show the details for the Book. Further you can edit the details and Save it to Update the Changes.

book.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>Spring 3 MVC Hibernate - Book CRUD</title>
	<style type="text/css">
		body {
			font-family: verdana;
			font-size: 12px;
			margin: 40px;
		}
		.bookTable, .bookTable td {
			border-collapse: collapse;
			border: 1px solid #aaa;
			margin: 2px;
			padding: 2px 2px 2px 10px;
			font-size: 12px;
		}
		.bookTable th {
			font-weight: bold;
			font-size: 12px;
			background-color: #5C82FF;
			color: white;
		}
		.bookLabel {
			font-family: verdana;
			font-size: 12px;
			font-weight: bold;
		}
		a, a:AFTER {
			color: blue;
		}
	</style>
	<script type="text/javascript">
	function deleteBook(bookId){
		if(confirm('Do you want to delete this Book ?')){
			var url = 'delete/' + bookId;
			window.location.href = url;
		}
	}
	</script>
</head>
<body>
	<h2>Book Store - SpringMVC-Hibernate CRUD Application</h2>
	<p style="color:green;font-weight:bold;">To add a New Book please click <a href="<c:url value='/index' />" >
		<img src="<c:url value='/images/vcard_add.png' />" title="Add a New Book"/></a>
	</p>
	<c:url var="action" value="/book/add.html" ></c:url>
	<form:form action="${action }" commandName="book" cssClass="bookForm" method="post">
		<table>
			<c:if test="${!empty book.bookName }">
				<tr>
					<td>
						<form:label path="id" cssClass="bookLabel">
							<spring:message code="label.bookId"></spring:message>
						</form:label>
					</td>
					<td>
						<form:input path="id" readonly="true" size="8"  disabled="true" />
						<form:hidden path="id" />
					</td> 
				</tr>
			</c:if>
			<tr>
				<td>
					<form:label path="bookName" cssClass="bookLabel">
						<spring:message code="label.bookName" />
					</form:label>
				</td>
				<td>
					<form:input path="bookName" />
				</td>
			</tr>
			<tr>
				<td>
					<form:label path="author" cssClass="bookLabel">
						<spring:message code="label.author" />
					</form:label>
				</td>
				<td>
					<form:input path="author" />
				</td>
			</tr>
			<tr>
				<td>
					<form:label path="price" cssClass="bookLabel">
						<spring:message code="label.price" />
					</form:label>
				</td>
				<td>
					<form:input path="price" />
				</td>
			</tr>
			<tr>
				<td>
					<form:label path="quantity" cssClass="bookLabel">
						<spring:message code="label.qty" />
					</form:label>
				</td>
				<td>
					<form:input path="quantity" />
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<c:if test="${!empty book.bookName}">
						<input type="submit" value="<spring:message code="label.editbook"/>" />
					</c:if>
					<c:if test="${empty book.bookName}">
						<input type="submit" value="<spring:message code="label.addbook"/>" />
					</c:if>
				</td>
			</tr>
			
		</table>
	</form:form>
	<h3>List of Books in Library</h3>
	
	<c:if test="${!empty listBooks }">
		<table class="bookTable">
		<tr>
			<th width="180">Book Name</th>
			<th width="160">Author Name</th>
			<th width="60">Price</th>
			<th width="80">Quantity</th>
			<th width="60">Action</th>
		</tr>
		<c:forEach items="${listBooks }" var="book">
			<tr>
				<td>${book.bookName }</td>
				<td>${book.author }</td>
				<td>${book.price }</td>
				<td>${book.quantity }</td>
				<td><img src="<c:url value='/images/vcard_delete.png' />" title="Delete Book" οnclick="javascript:deleteBook(${book.id})" />
					<a href="<c:url value='/edit/${book.id}' />"  >
					<img src="<c:url value='/images/vcard_add.png' />" title="Edit Book"/>
				</a>
				</td>
			</tr>
		</c:forEach>
		</table>
	</c:if>
</body>
</html>






  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值