Hibernate_使用原生态sql&Dto传输&最佳实践_Demo

这篇博客探讨了在Hibernate中如何使用原生态SQL进行查询,并通过DTO(Data Transfer Object)进行数据传输。作者提供了几个示例,包括从SQL查询到对象转换的不同方法,如直接映射到自定义DTO类和使用Transformers.aliasToBean方法。同时,作者提出了使用Hibernate的最佳实践,建议在大项目中避免双向关联和尽量使用SQL查询而非HQL,以及在需要时自行处理缓存策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package org.com.test.model1;
/**
 * DTO对象没有任何存储的意义,仅仅是用来进行数据的传输的。
 * 特别注意:这样的对象,必须有全部字段的构造方法和不带参数的构造方法。
 * @author asus_n56
 *
 */
public class StudentDto {
	private Classroom classroom;
	private Special special;
	private Student student;
	
	public Classroom getClassroom() {
		return classroom;
	}
	public void setClassroom(Classroom classroom) {
		this.classroom = classroom;
	}
	public Special getSpecial() {
		return special;
	}
	public void setSpecial(Special special) {
		this.special = special;
	}
	public Student getStudent() {
		return student;
	}
	public void setStudent(Student student) {
		this.student = student;
	}
	
	
	public StudentDto(Classroom classroom, Special special, Student student) {
		super();
		this.classroom = classroom;
		this.special = special;
		this.student = student;
	}
	public StudentDto() {
	}
	@Override
	public String toString() {
		return "StudentDto [classroom=" + classroom + ", special=" + special + ", student=" + student + "]";
	}
	
}

package org.com.test.model;
/**
 * DTO对象没有任何存储的意义,仅仅是用来进行数据的传输的。
 * 特别注意:这样的对象,必须有全部字段的构造方法和不带参数的构造方法。
 * @author asus_n56
 *
 */
public class StudentDto {
	private int stuId;
	private String stuName;
	private String sex;
	private String claName;
	private String speName;
	
	
	public int getStuId() {
		return stuId;
	}
	public void setStuId(int stuId) {
		this.stuId = stuId;
	}
	public String getStuName() {
		return stuName;
	}
	public void setStuName(String stuName) {
		this.stuName = stuName;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getClaName() {
		return claName;
	}
	public void setClaName(String claName) {
		this.claName = claName;
	}
	public String getSpeName() {
		return speName;
	}
	public void setSpeName(String speName) {
		this.speName = speName;
	}
	
	
	public StudentDto(int stuId, String stuName, String sex, String claName, String speName) {
		super();
		this.stuId = stuId;
		this.stuName = stuName;
		this.sex = sex;
		this.claName = claName;
		this.speName = speName;
	}
	public StudentDto() {
	}
	@Override
	public String toString() {
		return "StudentDto [stuId=" + stuId + ", stuName=" + stuName + ", sex=" + sex + ", claName=" + claName
				+ ", speName=" + speName + "]";
	}
	
	
}

package org.com.test.test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.com.test.model1.Classroom;
import org.com.test.model1.Special;
import org.com.test.model1.Student;
import org.com.test.model1.StudentDto;
import org.com.test.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.transform.Transformers;
import org.junit.Test;



public class TestSQL {
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Test
	public void testSql(){
		Session session = null;
		try {
			session = HibernateUtil.getSession();
			session.beginTransaction();
			List<Student> stus = session.createSQLQuery("select * from t_student where name like ?")
					.addEntity(Student.class).setParameter(0, "%张%").list();
			Iterator it = stus.iterator();
			while (it.hasNext()) {
				Student stu = (Student) it.next();
				System.out.println(stu.getName());
			}
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtil.closeSession(session);
		}
		
	}
	
	
	/**
	 * 测试的时候由于弄了两个包,所以下面我就弄了完整的类名。
	 * 因为配置的时候出现问题,然后暂时找不到原因,所以将就把完整类名写了。
	 * 配置hibernate.cfg.xml的时候把相应的maping注释起来
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Test
	public void testSql01(){
		Session session = null;
		try {
			session = HibernateUtil.getSession();
			session.beginTransaction();
			/**
			 * {stu.*},{cla.*},{spe.*},必须这么使用,因为name重名。
			 */
			List<Object[]> stus = session.createSQLQuery("select {stu.*},{cla.*},{spe.*} from "
					+ "t_student stu left join t_classroom cla on stu.c_id=cla.id left join"
					+ " t_special spe on spe.id=cla.s_id where stu.name like ?").addEntity("stu", Student.class)
					.addEntity("cla", Classroom.class).addEntity("spe", Special.class).setParameter(0, "%李%")
					.list();
			Iterator it = stus.iterator();
			Student st = null;
			Classroom cla = null;
			Special spe = null;
			StudentDto sdo = null;
			List<StudentDto> dto = new ArrayList<StudentDto>();
			while (it.hasNext()) {
				Object[] stu =(Object[]) it.next();
				st = (Student) stu[0];
				cla = (Classroom) stu[1];
				spe = (Special) stu[2];
				sdo = new StudentDto(cla, spe, st);
				dto.add(sdo);
			}
			for (StudentDto d : dto) {
				System.out.println(d);
			}
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtil.closeSession(session);
		}
		
	}
	
	
	/**
	 * 测试的时候由于弄了两个包,所以下面我就弄了完整的类名。
	 * 因为配置的时候出现问题,然后暂时找不到原因,所以将就把完整类名写了。
	 * 配置hibernate.cfg.xml的时候把相应的maping注释起来
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Test
	public void testSql02(){
		Session session = null;
	
		try {
			session = HibernateUtil.getSession();
			session.beginTransaction();
			List<org.com.test.model.StudentDto> stus = session.createSQLQuery("select stu.id as stuId "
					+ ", stu.name as stuName, stu.sex as sex, cla.name as claName, spe.name as speName from "
					+ "t_student stu left join t_classroom cla on stu.c_id=cla.id left join"
					+ " t_special spe on spe.id=cla.s_id where stu.name like ?")
					.setResultTransformer(Transformers.aliasToBean(org.com.test.model.StudentDto.class))
					.setParameter(0, "%孔%")
					.list();
			Iterator it = stus.iterator();
			while (it.hasNext()) {
				org.com.test.model.StudentDto d = (org.com.test.model.StudentDto) it.next();
				System.out.println(d);
			}
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtil.closeSession(session);
		}
		
	}
}
使用Hibernate的最佳实践
 1、在做关系尽可能使用单向关联,不要使用双向关联
 2、在大项目中(数据量如果超过百万条的项目,使用Hibernate可以酌情考虑以下几个原则)
     2.1、不要使用对象关联,尽可能用冗余字段来替代外键(使用冗余字段所带来的问题就是在修改时必须修改所有的冗余)
     2.2、查询数据不再使用HQL,全部使用SQL查询,如果涉及缓存,自己根据情况加入相应的缓存,而不是用Hibernate的缓存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值