Simple CRUD with JDBC, Gradle and JUnit Testing

You can view and download the complete source code of this tutorial from my github account.

In this tutorial, we will create a simple CRUD User Management Console Application using Java, MySQL, JDBC. We will generate and build the project using Gradle and perform unit testing using Junit 5.

For this tutorial, we will need the following tools :

1. Eclipse (i use Spring Tool Suite v4.x)

2. XAMPP or MySQL server

3. Gradle (i use version 5.6.2)


First, lets make a new project called “simpleGradleJunit”.

$> mkdir simpleGradleJunit

$> cd simpleGradleJunit

$> gradle init

Starting a Gradle Daemon (subsequent builds will be faster)

Select type of project to generate:2
   1: basic
   2: application
   3: library
   4: Gradle plugin
 Select implementation language:3
   1: C++
   2: Groovy---> 0% EXECUTING [3s]
   3: Java
   4: Kotlin
   5: Swift
 Select build script DSL:1
   1: Groovy
   2: Kotlin---> 50% EXECUTING [1m 20s]
 Select test framework:4
   1: JUnit 4
   2: TestNG---> 50% EXECUTING [1m 27s]
   3: Spock
   4: JUnit Jupiter
 Project name (default: simpleGradleJunit):
 Source package (default: simpleGradleJunit): id.danielniko.simpleGradleJunit

> Task :init
 Get more help with your project: https://docs.gradle.org/5.6.2/userguide/tutorial_java_projects.html

BUILD SUCCESSFUL in 2m 28s
 2 actionable tasks: 2 executed

Import the resulted directory to your Eclipse workspace using Import –> Existing Gradle Project.

The resulted directory is as follows:

Lets make sure the Gradle generated class file, App and AppTest works well. Right click on the App.java file and select Run As –> Java Application. You will get “Hello World.” in the console window.

Now, run AppTest.java. Right click and select Run As –> JUnit Test. You will encounter the following error :

java.lang.NoClassDefFoundError: org/junit/platform/commons/PreconditionViolationException

If that is the case, edit build.gradle to the following

apply plugin: 'application'

mainClassName = 'id.danielniko.simpleGradleJunit.App'

repositories {
    jcenter()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}

test {
    // Use junit platform for unit tests
    useJUnitPlatform()
}

Now run the AppTest again as JUnit Test. It will show green bar and no Failures.

This means our settings are complete. Now, its time to finally make our application.


Create our database “budget” and table “users” with the following sql. We also insert 1 row to test when our program can connect successfully.

drop database budget;
create database budget;
use budget;

CREATE TABLE `users` (
  `username` varchar(30) NOT NULL,
  `password` varchar(40) NOT NULL,
  `full_name` varchar(45) NOT NULL,
  `email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`username`)
) 

Next, we will add MySQL connector to build.gradle. Dont forget to right click your project, go to Gradle –> Refresh Gradle Project when you edit build.gradle. This will trigger gradle to download the dependencies.

dependencies {
    implementation 'mysql:mysql-connector-java:8.0.21'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}

Create a new class in id.danielniko.util package and name it DbUtil.java. This class handles the database connection to our MySQL server. In this class, we read a .properties file which contains the information necessary for the connection.

package id.danielniko.util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class DbUtil {
	
	private static Connection connection = null;
    private static Properties prop = null;

	public static String getProperty(String key) {
		if (prop != null) {
			return prop.getProperty(key);
			
		} else {
			Properties prop = new Properties();
            InputStream inputStream = DbUtil.class.getClassLoader().getResourceAsStream("database.properties");
            try {
				prop.load(inputStream);
				return prop.getProperty(key);
			} catch (IOException e) {
				e.printStackTrace();
				return null;
			}
		}
	}
	
    public static Connection getConnection() {
        if (connection != null)
            return connection;
        else {
            try {
                String driver = getProperty("driver");
                String url = getProperty("url");
                String user = getProperty("user");
                String password = getProperty("password");
                Class.forName(driver);
                connection = DriverManager.getConnection(url, user, password);
                connection.setAutoCommit(false);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } 
            return connection;
        }

    }

}

Create the properties file directly under the src/main/resources folder. Create a new file, name it database.properties. Put the following information inside.

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/budget
user=root
password=your_password

Now, lets test the .properties file read method and database connection class.

Create new class “DbUtilTest.java” under src/test/java with the same package as class to be tested, id.danielniko.util. In this unit test, we check whether .properties file can be read properly and database connection has been properly configured.

package id.danielniko.util;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.sql.Connection;

import org.junit.jupiter.api.Test;

class DbUtilTest {
	
	@Test 
    void getPropertyTest() {
    	String driver = DbUtil.getProperty("driver");
    	assertEquals("com.mysql.cj.jdbc.Driver", driver, "Db driver should match");
    }

    @Test 
    void getConnectionTest() {
    	Connection dbConnection = DbUtil.getConnection();
        assertNotNull(dbConnection, "connection should be successfull.");

    }
}

Right click on the class and Run as JUnit test. Make sure that the test runs successfully.


Now we can concentrate on the business process itself.

Create new POJO (Plain Old Java Object) class named User.java under id.danielniko.model

package id.danielniko.model;

public class User {

	private String username;
	private String password;
	private String fullName;
	private String email;
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	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;
	}
	@Override
	public String toString() {
		return "User [username=" + username + ", password=" + password + ", fullName=" + fullName + ", email=" + email
				+ "]";
	}
	
}

Next, we can create DAO (Data Access Object) and name it UserDao.java inside package id.danielniko.dao

package id.danielniko.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import id.danielniko.model.User;
import id.danielniko.util.DbUtil;

public class UserDao {

    private Connection connection;

    public UserDao() {
        connection = DbUtil.getConnection();
    }
    
    public UserDao(Connection conn) {
        connection = conn;
    }

    public void addUser(User user) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("insert into users(username,password,full_name,email) values (?, ?, ?, ? )");
            // Parameters start with 1
            preparedStatement.setString(1, user.getUsername());
            preparedStatement.setString(2, user.getPassword());
            preparedStatement.setString(3, user.getFullName());
            preparedStatement.setString(4, user.getEmail());
            preparedStatement.executeUpdate();
            preparedStatement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } 
    }

    public void deleteUser(String username) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("delete from users where username=?");
            // Parameters start with 1
            preparedStatement.setString(1, username);
            preparedStatement.executeUpdate();
            preparedStatement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void updateUser(User user) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("update users set password=?, full_name=?, email=?" +
                            "where username=?");
            // Parameters start with 1
            preparedStatement.setString(1, user.getPassword());
            preparedStatement.setString(2, user.getFullName());
            preparedStatement.setString(3, user.getEmail());
            preparedStatement.setString(4, user.getUsername());
            preparedStatement.executeUpdate();
            preparedStatement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public List<User> getAllUsers() {
        List<User> users = new ArrayList<User>();
        try {
            Statement statement = connection.createStatement();
            ResultSet rs = statement.executeQuery("select * from users");
            while (rs.next()) {
                User user = new User();
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setFullName(rs.getString("full_name"));
                user.setEmail(rs.getString("email"));
                users.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return users;
    }

    public User getUserByUsername(String username) {
        User user = new User();
        try {
            PreparedStatement preparedStatement = connection.
                    prepareStatement("select * from users where username=?");
            preparedStatement.setString(1, username);
            ResultSet rs = preparedStatement.executeQuery();

            if (rs.next()) {
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setFullName(rs.getString("full_name"));
                user.setEmail(rs.getString("email"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return user;
    }
}

As with previous classes, lets make unit test for this DAO class. We create UserDaoTest.java inside the id.danielniko.dao inside src/test/java. In this class, we use @BeforeAll to initialize before testing that the operation to DB is not auto committed because by default, whenever we call executeUpdate() it will be committed to the DB. We dont want that to happen on our testing.

In this case, the DB operation in test scenario will run in the actual DB but not committed so any changes will be discarded after the test finishes.

package id.danielniko.dao;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import java.sql.Connection;
import java.sql.SQLException;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import id.danielniko.model.User;
import id.danielniko.util.DbUtil;

class UserDaoTest {
	
	private static UserDao dao;
	
	@BeforeAll
	static void init() {
		Connection conn = DbUtil.getConnection();
		try {
			// set auto commit false so any operation in this test will be discarded.
			conn.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		dao = new UserDao(conn);
	}
	
	@AfterAll
	static void teardown() {
		Connection conn = DbUtil.getConnection();
		try {
			conn.setAutoCommit(true);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	void addUserTest() {
		User user = new User();
		user.setUsername("steven");
		user.setPassword("mypass");
		user.setFullName("Steven Gerrard");
		user.setEmail("steven@example.com");
		dao.addUser(user);
		User userFromDb = dao.getUserByUsername("steven");
		assertEquals("mypass", userFromDb.getPassword(), "Password must be equals");
	}
	
	@Test
	void deleteUserTest() {
		dao.deleteUser("danielniko");
		User userFromDb = dao.getUserByUsername("danielniko");
		assertNull(userFromDb.getUsername(), "Username should be null");
	}
	
	@Test
	void updateUserTest() {
		User user = new User();
		user.setUsername("danielniko");
		user.setPassword("secret");
		user.setFullName("Daniel Niko");
		user.setEmail("danielniko@example.com");
		dao.addUser(user);
		user.setPassword("verysecret");
		dao.updateUser(user);
		User userFromDb = dao.getUserByUsername("danielniko");
		assertEquals("verysecret", userFromDb.getPassword(), "Updated password must be equal.");
	}

}

Once again, right click on the test class and run as JUnit. After all green then we can move on to App.class inside id.danielniko.simpleGradleJunit

package id.danielniko.simpleGradleJunit;

import id.danielniko.dao.UserDao;
import id.danielniko.model.User;

public class App {

    public static void main(String[] args) {
    	UserDao dao = new UserDao();
    	// Add new user
    	User user = new User();
    	user.setUsername("luiz");
    	user.setPassword("secret");
    	user.setFullName("Luiz Suarez");
    	user.setEmail("luiz@example.com");
    	// Update user
    	dao.addUser(user);
    	user.setPassword("verysecret");
    	dao.updateUser(user);
    	System.out.println(dao.getAllUsers());
    	
    }
    
}

Actually, not much is happening in this class since this is only use to show how to connect Java with MySQL with unit testing.

Now, we need to build our program using the following command. Go to project root directory and execute the following.

gradlew build

You will see that it will trigger all of our unit tests to be run also. If you successfully run unit test previously, then it should not be a problem.

Now, if you want to distribute our program as executables, you can run below command.

gradlew distZip

This command will trigger building a simpleGradleJunit.zip file inside the build\distribution folder. Unzip it and run the .bat file inside bin folder using double click or from command prompt. You will get the following :

[User [username=luiz, password=verysecret, fullName=Luiz Suarez, email=luiz@example.com], User [username=steven, password=mypass, fullName=Steven Gerrard, email=steven@example.com]]

Advertisement

Penggunaan Serializable di Java

Kegunaan Serializable

Jika anda menggunakan Java untuk membuat proyek web application, pasti anda akan menjumpai interface Serializable. Serializable digunakan agar object yang dibuat dari class yang implement interface tersebut dapat diubah menjadi byte stream. Tujuan utamanya adalah agar object tersebut dapat disimpan menjadi file atau dikirim melalui network.

Object pada java disimpan dalam heap dalam memory. Jika aplikasinya mati, maka OS akan mengalokasikan ulang memory dan konsekuensinya object akan hilang. Agar object dapat diambil dari heap untuk disimpan ke dalam harddisk atau dikirim melalui network, maka object tersebut harus diubah menjadi byte stream dulu melalui proses Serialization.

Contohnya pada penggunaan HTTP request berikut:

public static void main(String[] args) {

    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(“https://www.example.com&#8221;);

    try {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
        nameValuePairs.add(new BasicNameValuePair(“Email”, “youremail”));
        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = client.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent()));
        String line = "";
        while ((line = rd.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Pada code snippet di atas, agar object nameValuePair dapat diambil dari heap space dan bisa dikirim sebagai byte melalui internet, maka harus implement Serializable. Jika merujuk pada javadoc, maka benar saja, class tersebut implements Serializable.

serialVersionUID

Jika class anda implement Serializable, maka anda harus menetapkan serialVersionUID pada class tersebut. Biasanya oleh IDE, misalnya Eclipse anda punya pilihan untuk generate default (1L) atau generated berdasarkan variable dalam class anda.

Kegunaan serialVersionUID ini adalah menentukan apakah byte stream atau file hasil yang berhasil di-serialize dapat di-deserialize atau diubah kembali menjadi object dengan serialVersionUID yang sama.

Jadi, misalnya hari ini dengan serialVersionUID = 1L, kemudian melakukan serialisasi object menjadi satu file.

class Employee {
    private static final long serialVersionUID = 1L;
    String name;
    String email;
}

Besoknya, kita menambahkan class variable yang baru, yaitu mobileNo, maka jika kita tidak mengubah serialVersionUID, file tersebut dapat diubah ulang menjadi object. Walaupun mobileNo tetap null. Wajar, karena memang di awal variable tersebut tidak ada.

class Employee {
    private static final long serialVersionUID = 1L;
    String name;
    String email;
    String mobileNo;
}

Namun, ada kalanya kita tidak mau jika file lama bisa diubah menjadi object lagi. Mungkin dengan adanya penambahan variable baru bisa mengakibatkan business logic yang berbeda. Maka kita tinggal mengubah serialVersionUID, misalnya menjadi serialVersionUID = 2L.

Dengan mengubah serialVersionUID, maka jika program mencoba untuk mengubah file menjadi object (deserialisasi), maka program akan melempar exception, yaitu : InvalidClassException.

Demikian penggunaan Serializable di Java. Jika ada pertanyaan, bisa disampaikan melalui comments.

Simple CRUD Using Java, Hibernate and MySQL

You can view and download the complete source code of this tutorial from my github account.

In this tutorial, we will create a simple CRUD (Create Read Update Delete) User Management Console Application using Java, Hibernate and MySQL.

For this tutorial, we will need the following tools: (The older or newer version should also works).

1. Eclipse IDE for Java EE Developers (Indigo – ver. 3.7)

2. MySQL Community Server and MySQL Workbench (GUI Tool)

3. MySQL Connector for Java

4. Hibernate ORM


First, lets create the database and table for User using the following SQL scripts. Copy and run this script in the MySQL Workbench (GUI Tool) –> SQL Editor:

create database UserDB;
use UserDB;
grant all on UserDB.* to 'admin'@'localhost' identified by 'test'; 

CREATE TABLE UserDB.`users` (
  `userid` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(45) DEFAULT NULL,
  `lastname` varchar(45) DEFAULT NULL,
  `dob` date DEFAULT NULL,
  `email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8

Go to eclipse and create a new project. Select File—>New—>Java Project. Enter “SimpleJava Hibernate” as the project name. Accept all the default value. Click Finish.

Please refer to this project directory in case you miss something along the way

structure

After creating the project, we need to add MySQL connector .jar file to our project build path. To do so, right click our newly created project “SimpleJavaHibernate” and choose Properties to open Properties window.

Select Java Build Path in the left side tree view to open right side detail view. Click Add External JARs.. button to open File browser dialog and point it to the MySQL connector .jar file which you have downloaded earlier.

Furthermore, we need to add Hibernate library to our project. Right click again the project and select Properties –>Java Build Path. This time, click Add Library. Select User Library from the list of selection. Click User Library. Next, click New. Enter “Hibernate” as the library name. Ok. Click our newly created User Library and click Add Jar. Select all the .jar file in both provided and required folder which located inside this directory structure [your hibernate download folder]—>hibernate-search-4.1.0.CR3-dist—>hibernate-search-4.1.0.CR3—>dist—>lib

Verify your build path to match configuration in picture below:

build path

This is all the configuration that we need to do and now let us get to the code.

Create four packages in the src folder.

  • com.daniel: contains the main method as the entry point for our console application
  • com.daniel.dao: contains the logic for database operation
  • com.daniel.model: contains the POJO (Plain Old Java Object). Each class in this package represents the database table. For this tutorial, however, we only have one table.
  • com.daniel.util : contains the class for initiating database connection

Next, create a new Java class. in com.daniel.model folder. Name it “User.java” and insert these following codes. Each of the variables in this class represents the field in USERS table in our database.

package com.daniel.model;

import java.util.Date;

public class User {

    private int userid;
    private String firstName;
    private String lastName;
    private Date dob;
    private String email;
    public int getUserid() {
        return userid;
    }
    public void setUserid(int userid) {
        this.userid = userid;
    }
    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 Date getDob() {
        return dob;
    }
    public void setDob(Date dob) {
        this.dob = dob;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "User [userid=" + userid + ", firstName=" + firstName
                + ", lastName=" + lastName + ", dob=" + dob + ", email="
                + email + "]";
    }    
}

Create a new class in com.daniel.util package and name it HibernateUtil.java. This class will read the configuration in our hibernate.cfg.xml file which handles the database connection to our MySQL server.

package com.daniel.util;

import org.hibernate.SessionFactory;
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
            return new Configuration().configure().buildSessionFactory();
        } 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;
    }
}

Create the aforementioned hibernate.cfg.xml configuration file directly under SimpleJavaHibernate folder. Put the following information inside.

<?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>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/UserDB</property>
        <property name="connection.username">admin</property>
        <property name="connection.password">test</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</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>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

        <!-- Mapping files -->
        <mapping resource="user.hbm.xml" />

    </session-factory>
</hibernate-configuration>

Notice that inside the file, there is an information about mapping resource which point to user.hbm.xml file. So, create an .xml file directly under SimpleJavaHibernate folder to map our Plain Old Java Object (POJO) variables with fields in database. Name it user.hbm.xml and write the following code inside

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

<hibernate-mapping>
    <class name="com.daniel.model.User" table="users">
        <id name="userid" type="int" column="userid">
            <generator class="increment" />
        </id>
        <property name="firstName">
            <column name="firstname" />
        </property>
        <property name="lastName">
            <column name="lastname" />
        </property>
        <property name="dob">
            <column name="dob" />
        </property>
        <property name="email">
            <column name="email" />
        </property>
    </class>
</hibernate-mapping>

Next, create a new class in com.daniel.dao package, name it UserDao.java. Dao stands for Data Access Object. It contains the logic for database operation.

package com.daniel.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.daniel.model.User;
import com.daniel.util.HibernateUtil;

public class UserDao {

    public void addUser(User user) {
        Transaction trns = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        try {
            trns = session.beginTransaction();
            session.save(user);
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            if (trns != null) {
                trns.rollback();
            }
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
    }

    public void deleteUser(int userid) {
        Transaction trns = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        try {
            trns = session.beginTransaction();
            User user = (User) session.load(User.class, new Integer(userid));
            session.delete(user);
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            if (trns != null) {
                trns.rollback();
            }
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
    }

    public void updateUser(User user) {
        Transaction trns = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        try {
            trns = session.beginTransaction();
            session.update(user);
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            if (trns != null) {
                trns.rollback();
            }
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
    }

    public List<User> getAllUsers() {
        List<User> users = new ArrayList<User>();
        Transaction trns = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        try {
            trns = session.beginTransaction();
            users = session.createQuery("from User").list();
        } catch (RuntimeException e) {
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
        return users;
    }

    public User getUserById(int userid) {
        User user = null;
        Transaction trns = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        try {
            trns = session.beginTransaction();
            String queryString = "from User where id = :id";
            Query query = session.createQuery(queryString);
            query.setInteger("id", userid);
            user = (User) query.uniqueResult();
        } catch (RuntimeException e) {
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
        return user;
    }
}

Finally, create our main application class inside the com.daniel package and name it App.java

package com.daniel;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.daniel.dao.UserDao;
import com.daniel.model.User;
import com.daniel.util.DbUtil;

public class App {

    public static void main(String[] args) {
        UserDao dao = new UserDao();

        // Add new user
        User user = new User();
        user.setFirstName("Daniel");
        user.setLastName("NikoJdbc");
        try {
            Date dob = new SimpleDateFormat("yyyy-MM-dd").parse("1986-01-02");
            user.setDob(dob);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        user.setEmail("daniel@example.com");
        dao.addUser(user);
//
//        // Update user
        user.setEmail("daniel@updatedJdbc.com");
        user.setUserid(1);
        dao.updateUser(user);

        // Delete user
        //dao.deleteUser(2);

        // Get all users
        for (User iter : dao.getAllUsers()) {
            System.out.println(iter);
        }

        // Get user by id
        System.out.println(dao.getUserById(8));

        try {
            DbUtil.getConnection().close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}

That is it. Run the project from eclipse and see the output from Console window

Simple CRUD Using Jsp, Servlet and MySQL

You can view and download the complete source code of this tutorial from my github account.

In this tutorial, we will create a simple CRUD (Create Read Update Delete) User Management Web Application using Jsp, Servlet and MySQL.

For this tutorial, we will need the following tools: (The older or newer version should also works). Moreover, basic Java knowledge is assumed.

1. Eclipse IDE for Java EE Developers (Indigo – ver. 3.7)

2. Apache Tomcat ver 7.0

3. MySQL Community Server and MySQL Workbench (GUI Tool)

4. MySQL Connector for Java

5. jstl.jar and standard.jar. You can get these jars from your Tomcat. Check in this directory : (your tomcat directory)—>apache-tomcat-7.0.26-windows-x86—>apache-tomcat-7.0.26—>webapps—>examples—>WEB-INF—>lib

I will tell you where you should put these jars later.

6. jQuery for javascript capability. In this case, we only use it for the datepicker component


First, lets create the database and table for User using the following SQL scripts:

create database UserDB;
use UserDB;
grant all on UserDB.* to 'admin'@'localhost' identified by 'test'; 

CREATE TABLE UserDB.`users` (
  `userid` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(45) DEFAULT NULL,
  `lastname` varchar(45) DEFAULT NULL,
  `dob` date DEFAULT NULL,
  `email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8

Go to eclipse. Before we create a new project for our application, we need to setup the server. Select File—>New—>Other. From the tree, Select Server.

Choose Apache—>Tomcat v7.0 Server and set the runtime environment.

Next, create a new project. Select File—>New—>Dynamic Web Project.

Enter “SimpleJspServletDB” as the project name. Select target runtime to Apache Tomcat v7.0 which we already setup before. Click Finish.

Please refer to this project directory in case you miss something along the way

directory

Copy the standard.jar, mysql-connector jar and jstl jar to WEB-INF—>lib folder.

Create four packages in the src folder.

  • com.daniel.controller: contains the servlets
  • com.daniel.dao: contains the logic for database operation
  • com.daniel.model: contains the POJO (Plain Old Java Object). Each class in this package represents the database table. For this tutorial, however, we only have one table.
  • com.daniel.util : contains the class for initiating database connection

Next, create a new Java class. in com.daniel.model folder. Name it “User.java” and insert these following codes. Each of the variables in this class represents the field in USERS table in our database.

package com.daniel.model;

import java.util.Date;

public class User {

    private int userid;
    private String firstName;
    private String lastName;
    private Date dob;
    private String email;
    public int getUserid() {
        return userid;
    }
    public void setUserid(int userid) {
        this.userid = userid;
    }
    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 Date getDob() {
        return dob;
    }
    public void setDob(Date dob) {
        this.dob = dob;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "User [userid=" + userid + ", firstName=" + firstName
                + ", lastName=" + lastName + ", dob=" + dob + ", email="
                + email + "]";
    }    
}

Create a new class in com.daniel.util package and name it DbUtil.java. This class handles the database connection to our MySQL server. In this class, we read a .properties file which contains the information necessary for the connection.

package com.daniel.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class DbUtil {

    private static Connection connection = null;

    public static Connection getConnection() {
        if (connection != null)
            return connection;
        else {
            try {
                Properties prop = new Properties();
                InputStream inputStream = DbUtil.class.getClassLoader().getResourceAsStream("/db.properties");
                prop.load(inputStream);
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String user = prop.getProperty("user");
                String password = prop.getProperty("password");
                Class.forName(driver);
                connection = DriverManager.getConnection(url, user, password);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return connection;
        }

    }
}

Create the properties file directly under the src folder. Create a new file, name it db.properties. Put the following information inside.

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/UserDB
user=admin
password=test

Next, create a new class in com.daniel.dao package, name it UserDao.java. Dao stands for Data Access Object. It contains the logic for  database operation.

package com.daniel.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.daniel.model.User;
import com.daniel.util.DbUtil;

public class UserDao {

    private Connection connection;

    public UserDao() {
        connection = DbUtil.getConnection();
    }

    public void addUser(User user) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("insert into users(firstname,lastname,dob,email) values (?, ?, ?, ? )");
            // Parameters start with 1
            preparedStatement.setString(1, user.getFirstName());
            preparedStatement.setString(2, user.getLastName());
            preparedStatement.setDate(3, new java.sql.Date(user.getDob().getTime()));
            preparedStatement.setString(4, user.getEmail());
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void deleteUser(int userId) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("delete from users where userid=?");
            // Parameters start with 1
            preparedStatement.setInt(1, userId);
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void updateUser(User user) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("update users set firstname=?, lastname=?, dob=?, email=?" +
                            "where userid=?");
            // Parameters start with 1
            preparedStatement.setString(1, user.getFirstName());
            preparedStatement.setString(2, user.getLastName());
            preparedStatement.setDate(3, new java.sql.Date(user.getDob().getTime()));
            preparedStatement.setString(4, user.getEmail());
            preparedStatement.setInt(5, user.getUserid());
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public List<User> getAllUsers() {
        List<User> users = new ArrayList<User>();
        try {
            Statement statement = connection.createStatement();
            ResultSet rs = statement.executeQuery("select * from users");
            while (rs.next()) {
                User user = new User();
                user.setUserid(rs.getInt("userid"));
                user.setFirstName(rs.getString("firstname"));
                user.setLastName(rs.getString("lastname"));
                user.setDob(rs.getDate("dob"));
                user.setEmail(rs.getString("email"));
                users.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return users;
    }

    public User getUserById(int userId) {
        User user = new User();
        try {
            PreparedStatement preparedStatement = connection.
                    prepareStatement("select * from users where userid=?");
            preparedStatement.setInt(1, userId);
            ResultSet rs = preparedStatement.executeQuery();

            if (rs.next()) {
                user.setUserid(rs.getInt("userid"));
                user.setFirstName(rs.getString("firstname"));
                user.setLastName(rs.getString("lastname"));
                user.setDob(rs.getDate("dob"));
                user.setEmail(rs.getString("email"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return user;
    }
}

Finally, create a new Servlet inside the com.daniel.controller package and name it UserController.java

package com.daniel.controller;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.daniel.dao.UserDao;
import com.daniel.model.User;

public class UserController extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static String INSERT_OR_EDIT = "/user.jsp";
    private static String LIST_USER = "/listUser.jsp";
    private UserDao dao;

    public UserController() {
        super();
        dao = new UserDao();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String forward="";
        String action = request.getParameter("action");

        if (action.equalsIgnoreCase("delete")){
            int userId = Integer.parseInt(request.getParameter("userId"));
            dao.deleteUser(userId);
            forward = LIST_USER;
            request.setAttribute("users", dao.getAllUsers());    
        } else if (action.equalsIgnoreCase("edit")){
            forward = INSERT_OR_EDIT;
            int userId = Integer.parseInt(request.getParameter("userId"));
            User user = dao.getUserById(userId);
            request.setAttribute("user", user);
        } else if (action.equalsIgnoreCase("listUser")){
            forward = LIST_USER;
            request.setAttribute("users", dao.getAllUsers());
        } else {
            forward = INSERT_OR_EDIT;
        }

        RequestDispatcher view = request.getRequestDispatcher(forward);
        view.forward(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User user = new User();
        user.setFirstName(request.getParameter("firstName"));
        user.setLastName(request.getParameter("lastName"));
        try {
            Date dob = new SimpleDateFormat("MM/dd/yyyy").parse(request.getParameter("dob"));
            user.setDob(dob);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        user.setEmail(request.getParameter("email"));
        String userid = request.getParameter("userid");
        if(userid == null || userid.isEmpty())
        {
            dao.addUser(user);
        }
        else
        {
            user.setUserid(Integer.parseInt(userid));
            dao.updateUser(user);
        }
        RequestDispatcher view = request.getRequestDispatcher(LIST_USER);
        request.setAttribute("users", dao.getAllUsers());
        view.forward(request, response);
    }
}

Now, it’s time for us to create the jsp, the view for our application. Under the WebContent folder, create a jsp file, name it index.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<!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=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<jsp:forward page="/UserController?action=listUser" />
</body>
</html>

This jsp serves as the entry point for our application. In this case, it will redirect the request to our servlet to list all the users in the database.

Next, create the jsp to list all the users in the WebContent folder. Name it listUser.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!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=EUC-KR">
<title>Show All Users</title>
</head>
<body>
    <table border=1>
        <thead>
            <tr>
                <th>User Id</th>
                <th>First Name</th>
                <th>Last Name</th>
                <th>DOB</th>
                <th>Email</th>
                <th colspan=2>Action</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach items="${users}" var="user">
                <tr>
                    <td><c:out value="${user.userid}" /></td>
                    <td><c:out value="${user.firstName}" /></td>
                    <td><c:out value="${user.lastName}" /></td>
                    <td><fmt:formatDate pattern="yyyy-MMM-dd" value="${user.dob}" /></td>
                    <td><c:out value="${user.email}" /></td>
                    <td><a href="UserController?action=edit&userId=<c:out value="${user.userid}"/>">Update</a></td>
                    <td><a href="UserController?action=delete&userId=<c:out value="${user.userid}"/>">Delete</a></td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
    <p><a href="UserController?action=insert">Add User</a></p>
</body>
</html>

In this jsp, we use JSTL to connect between the jsp and the servlet. We should refrain from using scriplet inside the jsp because it will make the jsp more difficult to maintain. Not to mention it will make the jsp looks ugly.

Next, create a new jsp in WebContent folder and name it user.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!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=EUC-KR">
<link type="text/css"
    href="css/ui-lightness/jquery-ui-1.8.18.custom.css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.18.custom.min.js"></script>
<title>Add new user</title>
</head>
<body>
    <script>
        $(function() {
            $('input[name=dob]').datepicker();
        });
    </script>

    <form method="POST" action='UserController' name="frmAddUser">
        User ID : <input type="text" readonly="readonly" name="userid"
            value="<c:out value="${user.userid}" />" /> <br /> 
        First Name : <input
            type="text" name="firstName"
            value="<c:out value="${user.firstName}" />" /> <br /> 
        Last Name : <input
            type="text" name="lastName"
            value="<c:out value="${user.lastName}" />" /> <br /> 
        DOB : <input
            type="text" name="dob"
            value="<fmt:formatDate pattern="MM/dd/yyyy" value="${user.dob}" />" /> <br /> 
        Email : <input type="text" name="email"
            value="<c:out value="${user.email}" />" /> <br /> <input
            type="submit" value="Submit" />
    </form>
</body>
</html>

Lastly, check the web.xml file located in WebContent—>WEB-INF folder in your project structure. Make sure it looks like this

<?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/web-app_2_5.xsd" 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">
  <display-name>SimpleJspServletDB</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>UserController</display-name>
    <servlet-name>UserController</servlet-name>
    <servlet-class>com.daniel.controller.UserController</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UserController</servlet-name>
    <url-pattern>/UserController</url-pattern>
  </servlet-mapping>
</web-app>

That is it. Right click the project name and run it using Run As–>Run on server option.

usermgt