I checked it once, but since it is in storage, I will publish it to Qiita
It's a fairly old article, so I'm not sure if it's practical.
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 | 
GenericDao(interface)
Define interface as a model, and perform basic CRUD processing from the application to the database.
A brief explanation (although there are obvious points, I will not write in detail because it is troublesome).
** CREATE **: Receive an instance of the model and insert it into the database
** READ **: SELECT with the primary key if there is one, SELECT all if not
** UPDATE **: Receive an instance of the model and UPDATE it to the database
** DELETE **: Receive primary key and DELETE from database
T ← This is the class of the object mapped to the database table, which you can see at the time of declaration
PK ← This is a class of what is the primary key, and in most cases it will be declared as String, Integer, Long.
What do you do when you want to use multiple keys?
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)
SessionFactory entered in DIsessionFactory.getCurrentSession (), you can use the acquired session from the middle.private Class <T> type; and receive the entity of that class in the constructorGenericDaoHibernateImpl.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);
	}
}
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)
);
Let's write a class for O / R Map. Stop writing Getter / Setter and generate it with lombok.
point
@Data used in lombokGender, ENUM is used in SQL, so it is necessary to separate it into another class.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> {
}
<bean id =" employeesDao "parent =" abstractDao "> partapplicationContext.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>