[JAVA] Let's create a parameter polymorphic mechanism with Generic Dao and Hibernate

I checked it once, but since it is in storage, I will publish it to Qiita

Motivation

Materials about Generic Dao

It's a fairly old article, so I'm not sure if it's practical.

Comparison of non-use / use of GenericDao

It is a prediction because I have never put it in the actual battle

GenericDao? use do not use
Boilerplate code(Standard code that cannot be omitted due to language specifications) Can be reduced Do your best to write
SQL tuning it can it can
debug Troublesome Troublesome

Samples and coding

GenericDao(interface)

Define interface as a model, and perform basic CRUD processing from the application to the database.

import java.io.Serializable;
import java.util.List;

/**
 * This is the article 10 years ago, we should follow this
 * @see https://www.ibm.com/developerworks/jp/java/library/j-genericdao/
 */
public interface GenericDao<T, PK extends Serializable> {

	/** Persist the newInstance object into database */
	PK create(T newInstance);

	/**
	 * Retrieve an object that was previously persisted to the database using
	 * the indicated id as primary key
	 */
	T read(PK id);
	List<T> read();

	/** Save changes made to a persistent object. */
	void update(T transientObject);

	/** Remove an object from persistent storage in the database */
	void delete(PK id) throws Exception;
	void delete(T persistentObject) throws Exception;
}

GenericDaoHibernateImpl(class)

GenericDaoHibernateImpl.java


import java.io.Serializable;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class GenericDaoHibernateImpl<T, PK extends Serializable> implements GenericDao<T, PK> {

	private Class<T> type;

	@Autowired
	private SessionFactory sessionFactory;

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public GenericDaoHibernateImpl(Class<T> type) {
		this.type = type;
	}

	// Not showing implementations of getSession() and setSessionFactory()
	private Session getSession() {
		Session session = sessionFactory.getCurrentSession();
		return session;
	}

	@Transactional(readOnly = false, rollbackFor = RuntimeException.class)
	public PK create(T o) {
		return (PK) getSession().save(o);
	}

	@Transactional(readOnly = false, rollbackFor = RuntimeException.class)
	public void update(T o) {
		getSession().update(o);
	}

	@Transactional(readOnly = true)
	public T read(PK id) {
		return (T) getSession().get(type, id);
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<T> read() {
		return (List<T>) getSession().createCriteria(type).list();
	}

	@Transactional(readOnly = false, rollbackFor = RuntimeException.class)
	public void delete(PK id) {
		T o = getSession().load(type, id);
		getSession().delete(o);
	}

	@Transactional(readOnly = false, rollbackFor = RuntimeException.class)
	public void delete(T o) {
		getSession().delete(o);
	}
}

EmployeesDao --Model layer sample

Let's write Dao (Data Access Object) to actually link with the model

SQL

CREATE TABLE employees (
    emp_no      INT             NOT NULL,  -- UNSIGNED AUTO_INCREMENT??
    birth_date  DATE            NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    gender      ENUM ('M','F')  NOT NULL,  -- Enumeration of either 'M' or 'F'  
    hire_date   DATE            NOT NULL,
    PRIMARY KEY (emp_no)                   -- Index built automatically on primary-key column
                                           -- INDEX (first_name)
                                           -- INDEX (last_name)
);

Model layer

Let's write a class for O / R Map. Stop writing Getter / Setter and generate it with lombok.

point

Employees.java


import java.io.Serializable;
import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@NoArgsConstructor
@Table(name = "employees")
public class Employees implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@Column(name = "emp_no", unique = true)
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer empNo;

	@Column(name = "birth_date")
	private Date birthDate;
	
	@Column(name = "first_name")
	private String firstName;
	
	@Column(name = "last_name")
	private String lastName;
	
	@Column(name = "gender")
	@Enumerated(EnumType.STRING)
	private Gender gender;
	
	@Column(name = "hire_date")
	private Date hireDate;
}

Dao

EmployeesDao.java


public interface EmployeesDao extends GenericDao<Employees, Integer> {
}

Dao Spring settings

applicationContext.xml


	<!--DataSource settings-->
	<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>

	<!-- sessionFactory -->
	<bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<!--DataSource set above-->
		<property name="dataSource" ref="myDataSource" />

		<!--Specify the namespace where the model class is-->
		<property name="packagesToScan" value="package.to.your.models" />

		<!--Hibernate connection settings-->
		<property name="hibernateProperties">
			<props>
				<prop key="dialect">org.hibernate.dialect.MySQLDialect</prop>
				<!--It seems that you can not debug here unless you set it to true in both production and test-->
				<prop key="show_sql">true</prop>
				<prop key="format_sql">true</prop>
				<prop key="connection.CharSet">utf8</prop>
				<prop key="connection.characterEncoding">utf8</prop>
				<prop key="connection.useUnicode">true</prop>
			</props>
		</property>
	</bean>

	<!--Use transactionManager-->
	<tx:annotation-driven />
	<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="mySessionFactory" />
	</bean>

	<!--Inject the sessionFactory created above into GenericDaoHibernateImpl-->
	<bean id="abstractDaoTarget" class="jp.gr.java_conf.hangedman.dao.GenericDaoHibernateImpl" abstract="true">
		<property name="sessionFactory">
			<ref bean="mySessionFactory" />
		</property>
	</bean>

	<!--Ready to inject implementation using Spring AOP-->
	<bean id="abstractDao" class="org.springframework.aop.framework.ProxyFactoryBean"
		abstract="true">
	</bean>

	<!-- Dao,Set the Model and finally finish. From here down<bean>Do you need a tag for each Dao?-->
	<bean id="employeesDao" parent="abstractDao">
		<!-- You need to configure the interface for Dao -->
		<property name="proxyInterfaces">
			<value>jp.gr.java_conf.hangedman.dao.EmployeesDao</value>
		</property>
		<property name="target">
			<bean parent="abstractDaoTarget">
				<constructor-arg>
					<value>jp.gr.java_conf.hangedman.models.Employees</value>
				</constructor-arg>
			</bean>
		</property>
	</bean>

sample

Recommended Posts

Let's create a parameter polymorphic mechanism with Generic Dao and Hibernate
Let's create a timed process with Java Timer! !!
Create a blog with Jekyll and GitHub Pages @ Theme setting
Create a blog with Jekyll and GitHub Pages @ Initial Settings
Create a JVM for app distribution with JDK9 modules and jlink
[Swift] Create a project with Xcode (ver 12.1) and display "Hello, World!"
Create a flyway jar with maven and docker build (migrate) with docker-maven-plugin
[Java] Let's create a mod for Minecraft 1.16.1 [Add and generate trees]
[Java] Let's create a mod for Minecraft 1.14.4 [8. Add and generate ore]
Let's create Ubuntu environment with vmware
Create exceptions with a fluid interface
Create a Maven project with a command
Let's install Docker on Windows 10 and create a verification environment for CentOS 8!
Create a simple CRUD with SpringBoot + JPA + Thymeleaf ② ~ Screen and function creation ~
[Java] Create a jar file with both compressed and uncompressed with the jar command
Create a program to post to Slack with GO and make it a container
How to create a server executable JAR and WAR with Spring gradle
Let's go with Watson Assistant (formerly Conversation) ⑤ Create a chatbot with Watson + Java + Slack
How to make an app with a plugin mechanism [C # and Java]
Let's create a TODO application in Java 2 I want to create a template with Spring Initializr and make a Hello world