1.BaseDao接口:
package com.dear.simpler.dao;
import java.io.Serializable;
import java.util.List;
import com.dear.simpler.db.utils.SPLDBException;
/**
*
* @author lixiang
*
* 定义所有表的公共的方法接口
*/
public interface BaseDao<T,PK extends Serializable>{
void save(T t) throws SPLDBException;
void delete(PK id) throws SPLDBException;
void update(T t) throws SPLDBException;
void saveOrUpdate(T t) throws SPLDBException;
//仅仅查询当前对象,不支持级联查询
List<T> query() throws SPLDBException;
T get(PK id) throws SPLDBException;
T load(PK id) throws SPLDBException;
}
2.BaseDaoImpl
package com.dear.simpler.dao.impl;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.Session;
import com.dear.simpler.dao.BaseDao;
import com.dear.simpler.db.utils.HibernateUtil;
import com.dear.simpler.db.utils.SPLDBException;
/**
*
* @author lixiang
*
* 完成了公共业务逻辑的实现,子类只需继承即可
*/
public class BaseDaoImpl<T,PK extends Serializable> implements BaseDao<T, PK> {
private Class<?> clazz; //clazz中存储当前操作实体类型
public BaseDaoImpl() {
//this代表子类对象,获取父类信息
ParameterizedType type = (ParameterizedType) this.getClass()
.getGenericSuperclass();
clazz = (Class<?>) type.getActualTypeArguments()[0]; //获取具体实体类型
}
public Session getSession() throws SPLDBException{
return HibernateUtil.getThreadSession();
}
@Override
public void save(T t) throws SPLDBException{
try{
Session session = getSession();
session.save(t);
}catch(Exception e){
throw new SPLDBException(e.getMessage());
}
}
@Override
public void delete(PK id) throws SPLDBException {
try{
Session session = getSession();
String hql = "DELETE FROM " + clazz.getSimpleName() + " c WHERE c.id=:id";
session.createQuery(hql).setSerializable("id", id).executeUpdate();
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void update(T t) throws SPLDBException {
try{
Session session = getSession();
session.update(t);
}catch(Exception e){
throw new SPLDBException(e.getMessage());
}
}
@Override
public void saveOrUpdate(T t) throws SPLDBException {
try{
Session session = getSession();
session.saveOrUpdate(t);
}catch(Exception e){
throw new SPLDBException(e.getMessage());
}
}
//仅仅支持当前对象,不支持级联查询
@SuppressWarnings("unchecked")
@Override
public List<T> query() throws SPLDBException {
List<T> lists = null;
try{
Session session = getSession();
String hql = "FROM " + clazz.getSimpleName();
lists = session.createQuery(hql).list();
}catch(Exception e){
throw new SPLDBException(e.getMessage());
}
return lists;
}
@SuppressWarnings("unchecked")
@Override
public T get(PK id) throws SPLDBException {
T t = null;
try{
Session session =getSession();
t = (T)session.get(clazz, id);
}catch(Exception e){
throw new SPLDBException(e.getMessage());
}
return t;
}
@SuppressWarnings("unchecked")
@Override
public T load(PK id) throws SPLDBException {
T t = null;
try{
Session session =getSession();
t = (T)session.load(clazz, id);
}catch(Exception e){
throw new SPLDBException(e.getMessage());
}
return t;
}
}
3.HibernateUtil
package com.dear.simpler.db.utils;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
/**
*
* @author lixiang
* 封装的hibernate工具类
*/
public class HibernateUtil {
private static final Logger LOG = Logger.getLogger(HibernateUtil.class);
private static ThreadLocal<Session> sessionHolder = new ThreadLocal<Session>();
private static SessionFactory sessionFactory;
private HibernateUtil() {}
static{
init();
}
private static void init(){
try{
Configuration cfg = new Configuration().configure("/hibernate.cfg.xml");
StandardServiceRegistryBuilder ssrbuilder = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties());
ServiceRegistry service = ssrbuilder.build();
sessionFactory=cfg.buildSessionFactory(service);
LOG.info("init hibernate success");
}catch(Exception e){
LOG.error("init hibernate failed : " + e.getMessage());
}
}
public static Session getThreadSession() throws SPLDBException{
Session session = sessionHolder.get();
if(session == null){
session = getNewSession();
sessionHolder.set(session);
}
return session;
}
public static Session getCurrentSession()
throws SPLDBException{
Session session = null;
try {
session = sessionFactory.getCurrentSession();
} catch (Exception e) {
throw new SPLDBException(e.getMessage());
}
return session;
}
public static Session getNewSession()
throws SPLDBException{
Session session = null;
try {
session = sessionFactory.openSession();
} catch (Exception e) {
throw new SPLDBException(e.getMessage());
}
return session;
}
public static void closeSession(Session session)
throws SPLDBException{
if(session!=null&&session.isOpen()){
try {
session.close();
} catch (Exception e) {
throw new SPLDBException(e.getMessage());
}
}
}
public static void closeThreadSession() {
Session session = sessionHolder.get();
if(session != null){
session.close();
//从ThreadLocal中清除session
sessionHolder.remove();
}
}
public static Transaction openTransaction()
throws SPLDBException{
Transaction transaction = null;
try {
Session session = getThreadSession();
transaction = session.beginTransaction();
} catch (Exception e) {
throw new SPLDBException(e.getMessage());
}
return transaction;
}
}
4.SPLDBException
package com.dear.simpler.db.utils;
/**
*
* @author lixiang
* 封装的数据库异常类
*/
public class SPLDBException extends Exception{
private static final long serialVersionUID = 1L;
public SPLDBException(String msg) {
super(msg);
}
}
接下来来使用上述定义的泛化接口及类,
具体的dao接口:继承BaseDao接口,通过泛型传入具体的对象类型及主键类型、
package com.dear.simpler.dao;
import com.dear.simpler.entity.Operation;
/**
*
* @author lixiang
*
*/
public interface OperationDao extends BaseDao<Operation,Integer>{
}
具体的dao实现类,继承BaseDaoImpl,并且实现上面的具体dao接口(该类使用了双重校验锁的单例模式)
package com.dear.simpler.dao.impl;
import com.dear.simpler.dao.OperationDao;
import com.dear.simpler.entity.Operation;
/**
*
* @author lixiang
*
*/
public class OperationDaoImpl extends BaseDaoImpl<Operation,Integer>
implements OperationDao{
private static volatile OperationDaoImpl operationDaoImpl;
private OperationDaoImpl(){}
public static OperationDaoImpl getInstance(){
if(operationDaoImpl == null){
synchronized (OperationDaoImpl.class) {
if(operationDaoImpl == null){
operationDaoImpl = new OperationDaoImpl();
}
}
}
return operationDaoImpl;
}
}
通过以上的方式,增删改查等公有操作就可以全部由BaseDaoImpl来实现,当具体的dao类很多的时候,就可以减少大量的冗余代码,使得代码更易维护,每个dao类只要关注自己个性化的方法即可。