在配置1基础上,为了简化对其他数据表对应的实体类的持久化操作,可以在项目中创建一个BaseDao,将数据的增、删、改、查等操作封装其中。
方法:基于反射机制编写BaseDao<T>.
1、创建BaseDao接口
package cn.hibernate.dao; public interface BaseDao<T> { //接口里只有方法名,没有方法体 //通过Session的get()方法根据OID 加载指定对象 public T get(int id); //通过Session的load()方法根据OID 加载指定对象 public T load(int id); //保存指定的Dept对象 public void save(T entity); //修改指定的Dept对象 public void update(T entity); //删除指定的Dept对象 public void delete(T entity); }
2、创建BaseDao接口实现类BaseDaoImpl
package cn.hibernate.dao; import java.lang.reflect.ParameterizedType; import org.hibernate.Session; /** * @ClassName:BaseDaoImpl * @Description:反射机制模板实现类 * @author: aKuang */ public abstract class BaseDaoImpl<T> implements BaseDao<T> { private Class<T> clazz; public BaseDaoImpl(){ //使用反射技术得到T的真实类型 ParameterizedType pt =(ParameterizedType) this.getClass().getGenericSuperclass(); System.out.println(this.getClass()); System.out.println(this.getClass().getGenericSuperclass()); for (int i = 0; i < pt.getActualTypeArguments().length; i++) { System.out.println(pt.getActualTypeArguments()[i]); } this.clazz=(Class<T>)pt.getActualTypeArguments()[0]; System.out.println("clazz--"+clazz); } public Session currentSession(){ return HibernateUtil.currentSession(); } @Override public T get(int id) { // TODO Auto-generated method stub return (T)HibernateUtil.currentSession().get(clazz, id); } @Override public T load(int id) { // TODO Auto-generated method stub return (T)HibernateUtil.currentSession().load(clazz, id); } @Override public void save(T entity) { // TODO Auto-generated method stub currentSession().save(entity); } @Override public void update(T entity) { // TODO Auto-generated method stub currentSession().update(entity); } @Override public void delete(T entity) { // TODO Auto-generated method stub currentSession().delete(entity); } }
3、编写会话工厂HibernateSessionFactory类
由于SessionFactory是重量级的,也就是说创建SessionFactory需要消耗大量的资源,所以在整个应用程序中最好只存在一个SessionFactory,这就需要把获取SessionFactory的方法单独抽取出来封装成一个工具类HibernateSessionFactory。
会话工厂类HibernateSessionFactory中,首先通过一个静态代码块来启动Hibernate,该代码只在HibernateSessionFactory类被加载时执行一次,用于建立SessionFactory。即SessionFactory是线程安全的,只能被实例化一次。
在Hibernate中,Session负责完成对象持久化操作。HibernateSessionFactory负责创建Session对象,以及关闭Session对象。
步骤:
① 初始化Hibernate配置管理类Configuration。
② 通过Configuration类实例创建Session的工厂类SessionFactory。
③ 通过SessionFactory得到Session实例。
package cn.hibernate.dao; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * @ClassName:HibernateUtil * @Description:获取Session类 * @author: aKuang */ public class HibernateUtil { //static:唯一性,final:不被继承 private static Configuration configuration; private static final SessionFactory sessionFactory; //初始化Configuration和SessionFactory static{ //静态变量的初始化 try { configuration=new Configuration().configure(); //读取的是hibernate.cfg.xml配置文件 sessionFactory=configuration.buildSessionFactory(); } catch (HibernateException ex) { throw new ExceptionInInitializerError(ex); } } public HibernateUtil(){} //获取session对象 public static Session currentSession(){ //静态方法拿到session 把一个私有对象写成一个公有方法 return sessionFactory.getCurrentSession(); } }
注意:由于在上一篇文章配置(1)hibernate.cfg.xml 中,已经配置了如下代码:
<!-- Session由当前执行的线程来跟踪管理 --> <property name="current_session_context_class">thread</property>
配置原因:这样配置是本地jdbc事务配置,你通过getCurrentSession创建的session会绑定到当前线程。即(自己编写的HibernateSessionFactory类里使用了getCurrentSession()方法因此要加上次配置,如果是通过Myeclipse等IDE自动引入依赖时自动创建的HibernateSessionFactory类,可以不加此配置)
4、测试使用
项目结构:
(1)---User实体类---User
public class User implements java.io.Serializable { // Fields private Integer id; private String username; private String password; //省略getter和setter、构造方法 }
(2)---User映射文件---User.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="cn.hibernate.entity.User" table="user" catalog="ssh"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="identity" /> </id> <property name="username" type="java.lang.String"> <column name="username" length="20" /> </property> <property name="password" type="java.lang.String"> <column name="password" length="20" /> </property> </class> </hibernate-mapping>
(3)---UserDao类---UserDao
package cn.hibernate.dao; import cn.hibernate.entity.User; public class UserDao extends BaseDaoImpl<User>{ @Override public User get(int id) { // TODO Auto-generated method stub return super.get(id); } @Override public User load(int id) { // TODO Auto-generated method stub return super.load(id); } @Override public void save(User entity) { // TODO Auto-generated method stub super.save(entity); } @Override public void update(User entity) { // TODO Auto-generated method stub super.update(entity); } @Override public void delete(User entity) { // TODO Auto-generated method stub super.delete(entity); } }
(4)---UserService类---UserService
package cn.hibernate.service; import org.hibernate.HibernateException; import org.hibernate.Transaction; import cn.hibernate.dao.UserDao; import cn.hibernate.entity.User; public class UserService { private UserDao userdao = new UserDao(); public UserDao getUserdao() { return userdao; } public void setUserdao(UserDao userdao) { this.userdao = userdao; } public void addNewUser(User user) { Transaction tx = null; try { //开启事务 tx = userdao.currentSession().beginTransaction(); //执行操作 userdao.save(user); //提交事务 tx.commit(); } catch (HibernateException e) { e.printStackTrace(); if (tx != null) { //事务回滚 tx.rollback(); } } } }
(4)---UserTest测试类---(junit单元测试)
package test; import static org.junit.Assert.*; import org.junit.Test; import cn.hibernate.entity.User; import cn.hibernate.service.UserService; public class UserServiceTest { private UserService userservice = new UserService(); public UserService getUserservice() { return userservice; } public void setUserservice(UserService userservice) { this.userservice = userservice; } @Test public void testAddNewUser() { User user = new User(); user.setUsername("aKuang"); user.setPassword("123456"); userservice.addNewUser(user); } }
结果: