【Hibernate】Hibernate常用增删改查方法

1.简单CURD

1.1 session.get(实体类名.class,主键值)
  • 根据主键值查询单条数据
  • 先从缓存中查找拥有该主键值的对象,如果没有查找到则发送sql从数据库查询
1.2 session.load(实体类名.class,主键值)
  • 根据主键值查询单条数据(一般配合lazyload=true[默认]使用)
  • 先从缓存中查找拥有该主键值的对象,如果没有查找到则只会返回只有主键值的代理对象,当在session范围内调用该代理对象除了主键值其他之外的属性,则会发送sql语句到数据库进行查询并返回完整的对象;如果再session范围外调用代理对象,则会直接报错no session
1.3 session.save(对象)
  • 插入一条数据到数据库
			//新建实体类对象
			Subject subject = new Subject();
			//设置属性值
			subject.setName("科目十");
			//插入到数据库
			session.save(subject);
			
			//插入后可以查看主键值
			System.out.println(subject.getId());
1.4 session.update(对象)
  • 更新一条数据到数据库
  • 要先查询整条数据,再修改部分数据,最后再更新到数据库
  • 如果直接新建对象修改部分属性,更新到数据库后其他列会有空值(默认更新所有列)
//先查询
Student student=session.get(Student.class, 1);
//修改数据
student.setName("李九");
//更新数据库
session.update(student);
1.5 session.saveOrUpdate(对象)
  • 当对象有主键标识属性值时,执行update()方法
  • 当对象没有主键标属性值时,执行save()方法
1.6 session.delete(对象)
  • 根据主键值删除一条数据
  • 要先查询再删除,能避免各种属性非空报错,能方便级联删除(要改配置)
//1.先查询
Student student=session.get(Student.class, 2);

//2.删除数据
session.delete(student);

2.HQL查询

2.1 Query常用方法
  • List list()

    • 一次性查询返回多列数据
  • Iterator iterate()

    • 查询符合条件的每条记录的主键值,其他列不会查询,当后面需要用到其他属性时,会根据主键值查询该条记录
  • Object uniqueResult()

    • 查询返回单个值
  • Query setParameter(参数名称或下标,参数值)

    • 设置hql查询单个条件值
    • Query参数下标是从0开始的,jdbc设置参数下标是从1开始的,注意区分
  • Query setProperties(自定义条件类对象)

    • 如果条件对象的属性与hql的参数名相同,则自动把对应的属性值赋值到hql中
  • Query setMaxResults(page_size)

    • 设置分页查询的每页显示的数量
  • Query setFirstResult(startIndex)

    • 设置分页查询的起始下标(不包含startIndex),也可以理解为跳过startIndex条数据后开始读取
    • startIndex=(当前页码-1)*每页显示的数量
2.1 hql简单查询
  • hql语法跟sql基本一样的
    • 查询所有列时可以省略select *
    • 表名要大写
    • 用到外键表的列时要先给主键表起别名,再根据java调用对象属性方式调用
// hql语句
	String hql = "from Student s where sex=:sex and s.grade.id=:grade_id order by id desc";
	// 创建hql查询
	Query query = session.createQuery(hql);
	// 设置hql参数
	query.setParameter("sex", 1);
	query.setParameter("grade_id", 1);
	// 查询返回实体对象集合
	List<Student> list = query.list();
	for (Student student : list) {
		System.out.println(student.getName() + "、" + student.getSex());
	}

2.2 hql分组统计查询
String hql = "select count(*) from Student s group by s.grade.id";
Query query = session.createQuery(hql);

//count()返回的是Long值
List<Long> list=  query.list();
for (Long count : list) {
	System.out.println(count);
}

2.3 hql分页查询
	String hql = "from Student";
	
	Query query = session.createQuery(hql);
	
	int page_size=3;  //页大小
	int page_index=2; //当前页码
	
	//开始下标=(当前页码-1)*页大小
	int startIndex=(page_index-1)*page_size;
	
	//设置分页查询的开始下标(不包含),即跳过startIndex条记录后再查询
	query.setFirstResult(startIndex);
	//设置每页显示的记录数
	query.setMaxResults(page_size);
	
	// 查询返回实体对象集合
	List<Student> list = query.list();
2.4 投影查询
//查询部分列并通过构造方法创建对象,返回该对象的集合
//Student类中需要对应的构造方法public Student(String name,Grade grade)
String hql = "select new Student(name,grade) from Student s";
Query query = session.createQuery(hql);	
List<Student> list = query.list();
for (Student student : list) {			
	System.out.println(student.getName() + "、"+student.getGrade().getId() );
}
2.5 迫切连接
  • 语法from Entity [left|right] join [fetch] Entity.property
  • 了解即可,一般直接调用实体类的外键类属性和set子表集合即可获取所有关联信息(懒加载,自动查询)
	//迫切外连接:把主表和子表的数据都一次性查询出来
	//因为主表Grade对应着子表的多条记录,所以这里需要distinct去掉重复项
	String hql = "select distinct g from Grade g left join fetch g.students";
	Query query = session.createQuery(hql);	
	
	//把子表所有数据封装到主表的students属性中
	List<Grade> list = query.list();
	
	for (Grade grade : list) {			
		System.out.println(grade.getName());
		 Set<Student> students = grade.getStudents();
		for (Student student : students) {
			System.out.println(student.getName());
		}	
	}
2.6 子查询
  • all
    • 如果当前筛选all子查询内返回0条记录,任何判断符号,该判断都为true
    • 如果当前筛选all子查询内返回1条或以上记录,则返回的所有记录都符合条件才为true
//查询所有成绩都及格的学生(没有成绩的学生也不查询)
//如果不加s.results.size>0这个额外条件,没有成绩的学生也会被查询到
//因为没有成绩的学生all()没有返回记录,所以无论60>还是60<都是为true
from Student s where 60<all(select r.score from s.results r) 
and s.results.size>0
  • any
    • 如果当前筛选any子查询内返回0条记录,该判断为false
    • 如果当前筛选all子查询内返回1条或以上记录,则返回的所有记录只要有一条记录符合条件即为true,全部记录都不符合才为false
    • some跟any作用一样
    • in跟=any一样
//查询有一次或以上成绩及格的学生
from Student s where 60<any(select r.score from s.results r)
  • exists
    • 返回一条或以上记录则为true,返回0条记录则为false

3.原生SQL查询

//SQL语句、{s.*}标识一个对象的所有属性、可以使用占位符
String sql="select {s.*},{g.*} from Student s join Grade g on g.id=s.grade_id";

//使用createSQLQuery()调用SQL查询语句,返回SQLQuery类型,继承Query接口
SQLQuery query=session.createSQLQuery(sql);

//addEntity()可以把返回结果封装成对象,第一个参数是SQL查询语句中Student的别名s,第二个参数是需要封装成的类Student.class
      //addJoin()可以连接查询的对象封装成对象,第一个参数是SQL查询语句中被连接的表的别名g,第二个参数是Student类的grade属性,是个字符串
query.addEntity("s",Student.class).addJoin("g", "s.grade");

//返回值是一个Object数组集合,数组的第一个元素是Student对象,数组第二个元素是Grade对象
List<Object[]> list = query.list();
for (Object[] objects : list) {
	Student student=(Student) objects[0];
	Grade grade=(Grade)objects[1];
	System.out.println(student.getName()+","+grade.getName());
}		
}
  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值