三、通过session操作hibernate(hql语句)

版权声明:本篇文章由IT_CREATE整理 https://blog.csdn.net/IT_CREATE/article/details/87376402

在没有将spring和hibernate整合在一起的时候,要使用hibernate,在持久层需要如下步骤:

一、在还没有对hibernate进行spring的整合的时候,我们需要写一个session工具类来产生sssion操作数据库

SessionUtil.java类:

package com.ge.hibernatexml.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class SessionUtil {
	
	private static Configuration cfg;
	private static ServiceRegistry serviceRegistry;
	private static SessionFactory sessionFactory;
	
	private static ThreadLocal<Session> local = new ThreadLocal<Session>() {
		protected Session initialValue() {
			return sessionFactory.openSession();
		};
	};
	

	static {
		cfg = new Configuration().configure();
		serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
				cfg.getProperties()).build();
		sessionFactory = cfg.buildSessionFactory(serviceRegistry);
	}

	
	public static Session getSession() {
		Session session = local.get();
		if(session == null) {
			session =  sessionFactory.openSession();
			local.set(session);
		}
		return session;
	}
}

二、然后利用切面进行事务的的管理:

TransactionAspect.java类:

package com.ge.hibernatexml.aspect;

import java.lang.reflect.Field;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.stereotype.Component;

import com.gezhi.hibernatexml.util.SessionUtil;

@Component
@Aspect
public class TransactionAspect {

	private Transaction tx;
	
	
	/**
	 * 定义切入点表达式
	 */
	@Pointcut("execution(* com.ge.hibernatexml.*mag.dao.impl.*Impl.*(..))")
	public void pointcut() {}
	
	/**
	 * 定义前置通知
	 * @param join
	 */
	@Before("pointcut()")
	public void beforeAdvice(JoinPoint join) {
		
		Session session = SessionUtil.getSession();
		
		Object obj = join.getTarget();//得到目标对象
		Class<?> cls = obj.getClass();
		try {
			Field field = cls.getDeclaredField("session");
			field.setAccessible(true);
			field.set(obj, session);
			
			//开启该session对应的事务操作能力
			tx = session.beginTransaction();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
	
	@AfterReturning(pointcut="pointcut()",returning="rev")
	public void afterReturningAdvice(JoinPoint join,Object rev) {
		tx.commit();
	}
	
	@AfterThrowing(pointcut="pointcut()",throwing="e")
	public void afterThrowingAdvice(JoinPoint join,Exception e) {
		tx.rollback();
	}
	
}

三、在spring的配置文件applicationContext.xml中要开启切面支持:

<!-- 开启切面的动态代理支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

下面就可以进行数据库的操作了。

一、对于增删改,可以直接调用hibernate内置的方法进行调用,操作底层数据库:

@Repository
public class UserDaoImpl implements IUserDao {

	private Session session;

	@Override
	public void saveUserBean(UserBean user) {
		// TODO Auto-generated method stub
		session.save(user);
	}

	@Override
	public void updateUserBean(UserBean user) {
		// TODO Auto-generated method stub
		session.update(user);
	}

	@Override
	public void deleteUserBean(UserBean user) {
		// TODO Auto-generated method stub
		session.delete(user);
	}
}

二、对于查询而言,他有两个方法(get和load)是根据id进行数据查询

@Repository
public class UserDaoImpl implements IUserDao {

	private Session session;


	@Override
	public UserBean getUserBeanById(int id) {
		// TODO Auto-generated method stub
		return (UserBean) session.get(UserBean.class, id);
	}

	/**
	 * 
	 */
	@Override
	public UserBean loadUserBeanById(int id) {
		// TODO Auto-generated method stub
		/*
		 * get()和load()的区别: get()在查询对象时,采用的是即时查询方法,它从一级缓存开始,进行二级缓存,到达数据库,它一定会得到一个最终的结果。
		 * load()在查询对象时,采用的是延迟查询方法,它从一级缓存开始,进行二级缓存,如果二级缓存中没有对应的数据,它将默认数据库中一定存在那条数据,
		 * 并返回该对象的代理对象, 直到程序发生调用时,才去查询,找到了就正常返回,找不到,抛异常:ObjectNotFoundException
		 */

		// 延迟加载对象,一定不能关闭Session
		return (UserBean) session.load(UserBean.class, id);
	}
}

三、自定义查询语句

  • 通过查询id返回一个Map数据(用?进行预编译的形式)
@Override
public Map<String, Object> queryUserBeanById(Integer id) {
	// TODO Auto-generated method stub
	String hql = "select new map(u.userName as userName,u.loginName as loginName,u.password as password) From UserBean as u where id = ?";
	Query query = session.createQuery(hql);
	query.setInteger(0, id);
	List<?> datas = query.list();
	if (datas != null)
		return (Map<String, Object>) datas.get(0);
	return null;
}

在hibernate中,我们可以使用两种方式来进行自定义语句的编写,第一种,利用hql语句。

从上面可以看到,hql语句和sql语句有一些区别,因为是面对对象编程了,所以UserBean对应了t_user;

通过map来接收指定的一些数据,那么就会以hql语句中map中的别名作为键,具体查出来的值为具体的值进行返回;

createQuery(hql)是执行hql的语句的预编译,返回一个Query类型的查询接口,同过这个接口对预编译的语句进行赋值,默认第一个?的位置是0。

query.list()是执行查询结果,返回一个list集合的结果集,因为这里通过id只能查询出一条结果,所以,用list的get方法,get(0)就可以获得这条数据。

  • 通过查询对象返回一个Map类型的list集合(通过取别名“:参数名”的形式进行预编译)
@Override
public List<Map<String, Object>> findUserBeanMapByObject(UserBean user) {
	// TODO Auto-generated method stub
	String hql = "select new map(u.loginName,u.userName,u.age) From UserBean as u where u.userName like concat(:userName,'%') and u.gender = :gender";
	Query query = session.createQuery(hql);// 产生一个Query接口的实例,并针对HQL进行预编译
	query.setProperties(user);
	return query.list();
}

通过取别名的方式来代替?,从hql语句中我们可以看到,我们传进来是一个对象,那么只要我们的对象属性的名称和hql语句中需要赋值的字段的名字保持一致就可以了,用“ :参数名”来替代上面预编译的问号,就是“:”后面的参数名与对象属性一致,这样我们就可以直接用query.setProperties(对象) 的形式进行赋值了

如果我们用的“ :参数名”没有和对象的属性的名称对应,那么就需要如下这种方式了进行赋值(别名赋值):

@Override
	public UserBean findUserBeanByLoginNameAndPwd(String loginName, String pwd) {
		// TODO Auto-generated method stub
		/*
		 * 按照参数别名进行设值
		 */
		String hql = "From UserBean as u where u.loginName = :ln and u.password = :pwd";
		Query query = session.createQuery(hql);// 产生一个Query接口的实例,并针对HQL进行预编译
		query.setString("ln", loginName);
		query.setString("pwd", pwd);
		List<?> datas = query.list();
		if (datas != null)
			return (UserBean) datas.get(0);
		return null;
	}

hql语句省略了前面的select部分,默认返回的是表关联对象的集合,这里就是UserBean的集合。

如果用?来进行预编译,就用下标形式赋值:

​
// select * from t_user as u where u.login_name = ? and u.user_pwd = ?
		
// 按照位置进行设值 
String hql = "From UserBean as u where u.loginName = ? and u.password = ?"; 
Query query = session.createQuery(hql);//产生一个Query接口的实例,并针对HQL进行预编译 
query.setString(0, loginName);//在JDBC中,第1个?下标是1,在Hibernate中,下标是0 
query.setString(1, pwd);
List<?> datas = query.list();


​

猜你喜欢

转载自blog.csdn.net/IT_CREATE/article/details/87376402