A Complete CRUD Application with Spring MVC and MyBatis/iBatis

Welcome back, Developing a Web Application in Java/J2EE is really really good, there are so many frameworks available out there. So today, in this article, let’s discuss one of the popular Java framework, Spring MVC and MyBatis/iBatis, using these two frameworks let’s create complete CRUD application



MyBatis is a Java persistence framework that couples objects with stored procedures or SQL statements using an XML descriptor or annotations. MyBatis is free software that is distributed under the Apache License 2.0. MyBatis is a fork of iBATIS 3.0 and is maintained by a team that includes the original creators of iBATIS.

The Spring Framework is an application framework and inversion of control container for the Java platform. The framework’s core features can be used by any Java application, but there are extensions for building web applications on top of the Java EE (Enterprise Edition) platform. Although the framework does not impose any specific programming model, it has become popular in the Java community as an addition to, or even replacement for the Enterprise JavaBeans (EJB) model. The Spring Framework is open source.

Steps to be followed:



Step 1: Create a maven project

Step 2: Configure web.xml and spring-servlet.xml file

Step 3: Add required dependencies to pom.xml



Step 4: Create 4 packages, Controller, DAO, Entity, and Util

Step 5: Create 1 Resources folder, add the mybatis-config.xml file to it. Inside that file specify JDBC properties

Step 6: Create a folder named jsps inside the WEB-INF

Let’s design the DB first,

NOTE: I am using MySQL DB throughout this article, you can use any other DB.



Execute the below command to create DB,

create database employeedirectory;

Execute the below command to use DB,

use employeedirectory;

Let’s design our employee table,

create table employee
 
(
 
    id int not null primary key auto_increment,
 
    fullname varchar(50) not null,
 
    email varchar(50) not null,
 
    gender varchar(50) not null,
 
    hobbies varchar(50) not null,
 
    country varchar(50) not null,
 
    address varchar(50) not null
 
)

Next step is to create a maven project in eclipse



pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>in.bushansirgur</groupId>
	<artifactId>springmybatis</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>springmybatis Maven Webapp</name>
	<url>http://maven.apache.org</url>

	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>

		<!-- For spring dependency -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>5.1.5.RELEASE</version>
		</dependency>

		<!-- java 7 support -->
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-api</artifactId>
			<version>7.0</version>
			<scope>provided</scope>
		</dependency>

		<!-- jstl tag libaray support -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<!--support for mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.0.4</version>
		</dependency>

		<!-- spring mybatis integration -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.0.0</version>
		</dependency>

		<!-- mysql connector java support -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.13</version>
		</dependency>

		<!-- C3P0 support -->
		<dependency>
			<groupId>c3p0</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.1.2</version>
		</dependency>


	</dependencies>
	<build>
		<finalName>springmybatis</finalName>
	</build>
</project>

web.xml

<?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" 
		xmlns:web="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_2_5.xsd" id="WebApp_ID" version="2.5">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <display-name>Spring3-Mybatis</display-name>
  <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>

spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:beans="http://www.springframework.org/schema/beans"
	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:p="http://www.springframework.org/schema/p"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	
		<!-- Add support for conversion, formatting and validation support -->
		<context:component-scan base-package="in.bushansirgur" />
		<mvc:annotation-driven />
		
		<!-- Define Spring MVC view resolver -->
		<beans:bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
			<beans:property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
			<beans:property name="prefix" value="/WEB-INF/jsps/" />
			<beans:property name="suffix" value=".jsp" />
		</beans:bean>

</beans:beans>

Employee.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="s"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<body>

	<div class="container">
		<h1>Employee Details</h1>
		<hr />
		<s:form action="saveProcess" modelAttribute="employee">
			<s:hidden path="id" />
			<s:hidden path="" value="${employee.hobbies}" id="hobbies" />
			
			<div class="form-group">
				<s:input path="fullname" class="form-control"
				placeholder="Enter Full Name" />
			</div>

			<div class="form-group">
				<s:input path="email" placeholder="Enter Email" class="form-control" />
			</div>
			
			<div class="form-group">
				<div class="form-check-inline">
					<label class="form-check-label">
						<s:radiobutton path="gender" value="Male" class="form-check-input"/>Male
					</label>
				</div>
			
				<div class="form-check-inline">
					<label class="form-check-label">
						<s:radiobutton path="gender" value="Female" class="form-check-input"/>Female
					</label>
				</div>
			</div>
			
			<div class="form-group">
				<div class="form-check-inline">
					<label class="form-check-label">
						<s:checkbox path="hobbies" value="Sports" class="form-check-input"/>Sports
					</label>
				</div>
				
				<div class="form-check-inline">
					<label class="form-check-label">
						<s:checkbox path="hobbies" value="Browsing" class="form-check-input"/>Browsing
					</label>
				</div>
				
				<div class="form-check-inline">
					<label class="form-check-label">
						<s:checkbox path="hobbies" value="Running" class="form-check-input"/>Running
					</label>
				</div>
				
				<div class="form-check-inline">
					<label class="form-check-label">
						<s:checkbox path="hobbies" value="Chatting" class="form-check-input"/>Chatting
					</label>
				</div>
			</div>
				
			<div class="form-group">
				<s:select path="country" class="form-control">
					<s:option value="0">--Select--</s:option>
					<s:option value="India">India</s:option>
					<s:option value="Australia">Australia</s:option>
					<s:option value="Japan">Japan</s:option>
					<s:option value="America">America</s:option>
					<s:option value="South Africa">South Africa</s:option>
					<s:option value="Sri Lanka">Sri Lanka</s:option>
				</s:select>
			</div>
				
			<div class="form-group">
				<s:textarea path="address" placeholder="Enter Address"
				class="form-control" />
			</div>
			<input type="submit" value="Save" class="btn btn-info" />&nbsp; 
			<input type="reset" value="Reset" class="btn btn-danger" />

		</s:form>
		<hr />
		<a href="listOfEmployee">Back to List</a>
	</div>
	<script
		src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.1.1.min.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var hobbies = $("#hobbies").val().split(",");
			var $checkboxes = $("input[type=checkbox]");
			$checkboxes.each(function(idx, element) {
				if (hobbies.indexOf(element.value) != -1) {
					element.setAttribute("checked", "checked");
					$("#hobbies").val("");
				} else {
					element.removeAttribute("checked");
				}
			});
		});
	</script>
</body>
</html>

ListEmployees.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="s"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<body>

	<div class="container">
		<h1>Employee Details</h1>
		<p align="right">
			<button
				onclick="window.location.href = 'showFormForAdd.html'; return false;"
				class="btn btn-primary">Add Employee</button>
		</p>
		<hr />
		<table border="1" class="table table-striped table-bordered">
			<thead class="thead-dark">
				<tr>
					<th>Full Name</th>
					<th>Email</th>
					<th>Gender</th>
					<th>Hobbies</th>
					<th>Country</th>
					<th>Address</th>
					<th>Actions</th>
				</tr>
			</thead>
			<c:forEach items="${employeeList}" var="e">
				<c:url var="updateLink" value="/employee/displayUpdateForm.html">
					<c:param name="employeeId" value="${e.id}" />
				</c:url>

				<c:url var="deleteLink" value="/employee/displayDeleteForm.html">
					<c:param name="employeeId" value="${e.id}" />
				</c:url>
				<tbody>
					<tr>
						<td>${e.fullname}</td>
						<td>${e.email}</td>
						<td>${e.gender}</td>
						<td>${e.hobbies}</td>
						<td>${e.country}</td>
						<td>${e.address}</td>
						<td><a href="${updateLink}">Update</a> | <a
							href="${deleteLink}"
							onclick="if(!(confirm('Are you sure want to delete this Employee permanently?'))) return false">Delete</a>
						</td>
					</tr>
				</tbody>
			</c:forEach>
		</table>
	</div>

</body>
</html>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <typeAliases>
     <typeAlias type="in.bushansirgur.entity.Employee" alias="employee"/>
  </typeAliases>  
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/employeedirectory"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="in/bushansirgur/dao/EmployeeMapper.xml" />
  </mappers>
</configuration>

MyBatisUtil.java

package in.bushansirgur.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
	private static SqlSessionFactory sqlSessionFactory;
	static {
		Reader reader;
		try {
			reader = Resources.getResourceAsReader("resources/mybatis-config.xml");
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static SqlSessionFactory getSqlSessionFactory(){
		return sqlSessionFactory;
	}
}

Employee.java

package in.bushansirgur.entity;

public class Employee {
	
	private Integer id;
	private String fullname;
	private String email;
	private String gender;
	private String hobbies;
	private String country;
	private String address;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getFullname() {
		return fullname;
	}
	public void setFullname(String fullname) {
		this.fullname = fullname;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public String getHobbies() {
		return hobbies;
	}
	public void setHobbies(String hobbies) {
		this.hobbies = hobbies;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getCountry() {
		return country;
	}
	public void setCountry(String country) {
		this.country = country;
	}
	
}

EmployeeMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="in.bushansirgur.dao.EmployeeMapper">
	
	<resultMap type="employee" id="result">
		<id property="id" column="id" />
		<result property="fullname" column="fullname" />
		<result property="email" column="email" />
		<result property="gender" column="gender" />
		<result property="hobbies" column="hobbies" />
		<result property="country" column="country" />
		<result property="address" column="address" />
	</resultMap>
	
	<select id="getAllEmployees" resultType="employee" resultMap="result">
		SELECT * FROM employee
	</select>
	
	<insert id="insertEmployee" parameterType="employee" keyProperty="id" useGeneratedKeys="true">
		INSERT INTO employee(fullname, email, gender, hobbies, country, address)
		VALUES(#{fullname}, #{email}, #{gender}, #{hobbies}, #{country}, #{address})
	</insert>
	
	<update id="updateEmployee" parameterType="employee">
		UPDATE employee SET fullname = #{fullname}, email = #{email}, gender = #{gender}, hobbies = #{hobbies}, country = #{country}, address = #{address} 
		WHERE id = #{id} 
	</update>
	
	<delete id="deleteEmployee" parameterType="int">
		DELETE FROM employee WHERE id = #{employeeId}
	</delete>
	
	<select id="findById" parameterType="int" resultType="employee" resultMap="result">
		SELECT * FROM employee WHERE id = #{employeeId}
	</select> 
</mapper>

EmployeeMapper.java

package in.bushansirgur.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import in.bushansirgur.entity.Employee;
import in.bushansirgur.util.MyBatisUtil;


@Repository
public class EmployeeMapper {
	
	public void saveEmployee(Employee employee){
		SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
		session.insert("insertEmployee", employee);
		session.commit();
		session.close();
	}
	
	public void updateEmployee(Employee employee){
		SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
		session.update("updateEmployee", employee);
		session.commit();
		session.close();
	}
	
	public void deleteEmployee(int employeeId){
		SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
		session.delete("deleteEmployee", employeeId);
		session.commit();
		session.close();
	}
	
	public List<Employee> getAllEmployees(){
		SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
		@SuppressWarnings("unchecked")
		List<Employee> employeesList = session.selectList("getAllEmployees");
		session.commit();
		session.close();
		return employeesList;
	}
	
	public Employee findById(int employeeId){
		SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
		Employee employee = (Employee) session.selectOne("findById", employeeId);
		session.commit();
		session.close();
		return employee;
	}
}

EmployeeController.java

package in.bushansirgur.controller;

import org.springframework.beans.factory.annotation.Autowired;
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.RequestParam;

import in.bushansirgur.dao.EmployeeMapper;
import in.bushansirgur.entity.Employee;


@Controller @RequestMapping("/employee")
public class EmployeeController {

	@Autowired
	EmployeeMapper employeeMapper;
	
	private static final String EMPLOYEE = "Employee";
	private static final String EMPLOYEELIST = "ListEmployees";
	
	@RequestMapping("/listOfEmployee")
	public String showListOfEmployees(Model model){
		model.addAttribute("employeeList", employeeMapper.getAllEmployees());
		return EMPLOYEELIST;
	}
	
	@RequestMapping("/showFormForAdd")
	public String addEmployee(Model model){
		model.addAttribute("employee", new Employee());
		return EMPLOYEE;
	}
	
	@RequestMapping("/saveProcess")
	public String saveEmployee(@ModelAttribute("employee") Employee employee){
		if(employee.getId() == null){
			employeeMapper.saveEmployee(employee);
		}else{
			employeeMapper.updateEmployee(employee);
		}
		
		return "redirect:/employee/listOfEmployee";
	}
	
	@RequestMapping("/displayUpdateForm")
	public String showUpdateForm(@RequestParam("employeeId") int employeeId, Model model){
		model.addAttribute("employee", employeeMapper.findById(employeeId));
		return EMPLOYEE;
	}
	
	@RequestMapping("/displayDeleteForm")
	public String deleteEmployee(@RequestParam("employeeId") int employeeId){
		employeeMapper.deleteEmployee(employeeId);
		return "redirect:/employee/listOfEmployee";
	}
}

index.jsp

<% response.sendRedirect("employee/listOfEmployee.html"); %>

So now let’s run the application, and you will see this landing page,

Love this post?


Help me to buy a cup of coffee/Support us by donating.
All the donations will be going to the website maintenance/improvement.

Pay Now

 

That’s it for this article, I hope this article helped you in one or the other way, do let me know about this article, if you like the content, do share this article with your friends, I will see you in the next article.

About the author

Bushan Sirgur

Well, I am Bushan Sirgur from Banglore, India. Currently, I am working as a Software Developer in a Service Base Company. I am interested in JAVA/J2EE, Angular 2, JavaScript, jQuery, MongoDB.

View all posts

20 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *