03-Hibernater

Hibernate级联与懒加载
本文详细介绍了Hibernate中级联保存、级联删除的概念及应用,并深入探讨了懒加载的不同配置选项及其对性能的影响。

级联添加

User.hbm.xml设置级联删除,但是没有反转

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- package:实体类的包名 -->
<hibernate-mapping package="com.tamakiakoo.entity">

	<!-- 
		name:类名
		table:实体类对应的表明
	 -->
	<class name="User" table="t_user" lazy="false">
		<!-- 主键要用<id>标签来修饰 -->
		<!-- 
			name:对象中的主键名称
			column:表中的主键名称(如果表中的字段和对象中的属性一直,column可以不写)
		 -->
		<id name="id" column="id">
			<generator class="native" />
		</id>
		<property name="username" />
		<property name="password" />
		<property name="email" />
		<property name="sex" />
		<!-- 
			cascade:级联属性
				1:save-update:保存一的一方多的一方可以自动保存
				2:delete:删除以的一方多的一方可以自动删除
				3:all=save-update+delete
		 -->
		<!--  inverse="true"  cascade="all -->
		<set name="addSet"">
			<key column="user_id" ></key>
			<one-to-many class="Address" />
		</set>
		
	</class>

</hibernate-mapping>

Address.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">
<hibernate-mapping package="com.tamakiakoo.entity">

	<class name="Address" table="t_address" >
		
		<id name="id">
			<generator class="native" />
		</id>
		<property name="address"/>
		<property name="phone" />
		
		<many-to-one name="user">
			<column name="user_id"></column>
		</many-to-one>
		
	</class>
</hibernate-mapping>

测试一:

User设置级联,user维护关系,进行级联操作

修改user.hbm.xml

<set name="addSet" cascade="all">
			<key column="user_id" ></key>
			<one-to-many class="Address" />
		</set>
代码
@Test
	public void testAdd1() {
		// a.创建一个用户
		User user = new User("admin", "admin");

		// b.创建两个地址
		Address a1 = new Address("深圳", "123");
		Address a2 = new Address("北京", "456");

		// 2.维护关系【给以的一方维护关系】目的:就保存一的时候多可以自动保存
		user.getAddSet().add(a1);
		user.getAddSet().add(a2);


		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();

		session.save(user);

		transaction.commit();
	}
控制台
Hibernate: insert into t_user (username, password, email, sex) values (?, ?, ?, ?)
Hibernate: insert into t_address (address, phone, user_id) values (?, ?, ?)
Hibernate: insert into t_address (address, phone, user_id) values (?, ?, ?)
Hibernate: update t_address set user_id=? where id=?
Hibernate: update t_address set user_id=? where id=?

数据都正常,address表外键也加进去了

继续测试配置不变

注释掉保存的User,但是因为address没有设置级联而报错

@Test
	public void testAdd2() {
		// a.创建一个用户
		User user = new User("admin", "admin");
		
		// b.创建两个地址
		Address a1 = new Address("深圳", "123");
		Address a2 = new Address("北京", "456");
		
		a1.setUser(user);
		a2.setUser(user);
		
		// 3.入库
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		//session.save(user);
		session.save(a1);
		session.save(a2);
		
		transaction.commit();
	}

控制台

    报错:
    org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.tamakiakoo.entity.User

这是因为你的对象引用了一个未保存的瞬态实例,换句话讲就是:因为主表的记录不曾插入,所以参照该记录的从表记录也就无法插入
通过cascade=CascadeType.All将Hibernate的所有持久化操作都级联到关联实体

解决办法一:

修改代码如下:
主要是设置了他的id为1(数据库中存在)

	@Test
	public void testAdd2() {
		// a.创建一个用户
		User user = new User("admin", "admin");//
		user.setId(1);
		
		// b.创建两个地址
		Address a1 = new Address("深圳", "123");
		Address a2 = new Address("北京", "456");
		
		a1.setUser(user);
		a2.setUser(user);
		
		// 3.入库
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		//session.save(user);
		session.save(a1);
		session.save(a2);
		
		transaction.commit();
	}

}

执行代码之后:数据正常,而且尽管user对象的usernaem和password和数据库不一致也没有修改

解决办法二

在保存地址之前先保存User对象

	@Test
	public void testAdd2() {
		// a.创建一个用户
		User user = new User("admin", "admin");
		//user.setId(2);
		
		// b.创建两个地址
		Address a1 = new Address("深圳", "123");
		Address a2 = new Address("北京", "456");
		
		a1.setUser(user);
		a2.setUser(user);
		
		// 3.入库
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		session.save(user);
		session.save(a1);
		session.save(a2);
		
		
		transaction.commit();
	}

数据正常

解决办法三

设置级联操作

修改address.hbm.xlm

<many-to-one name="user" cascade="all">
			<column name="user_id"></column>
		</many-to-one>

执行代码

@Test
	public void testAdd3() {
		// a.创建一个用户
		User user = new User("admin1", "admin1");
		
		// b.创建两个地址
		Address a1 = new Address("深圳", "123");
		Address a2 = new Address("北京", "456");
		
		a1.setUser(user);
		a2.setUser(user);
		
		// 3.入库
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		//session.save(user);
		session.save(a1);
		session.save(a2);
		
		
		transaction.commit();
	}

控制台

Hibernate: insert into t_user (username, password, email, sex) values (?, ?, ?, ?)
Hibernate: insert into t_address (address, phone, user_id) values (?, ?, ?)
Hibernate: insert into t_address (address, phone, user_id) values (?, ?, ?)

数据正常

问题:

级联保存user的时候会多出sql
级联保存address的时候要保存多个地址

所以有没有办法保存user的时候不多出sql,并且级联保存address对象呢

如下:

user.hbm.xml 设置反转

<set name="addSet" cascade="all" inverse="true">
			<key column="user_id" ></key>
			<one-to-many class="Address" />
		</set>

address.hbm.xml

<many-to-one name="user">
			<column name="user_id"></column>
		</many-to-one>

执行代码(user维护关系)

@Test
	public void testAdd1() {
		// a.创建一个用户
		User user = new User("admin", "admin");

		// b.创建两个地址
		Address a1 = new Address("深圳", "123");
		Address a2 = new Address("北京", "456");

		// 2.维护关系【给以的一方维护关系】目的:就保存一的时候多可以自动保存
		user.getAddSet().add(a1);
		user.getAddSet().add(a2);

		// 3.入库
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();

		session.save(user);

		transaction.commit();
	}

控制台

Hibernate: insert into t_user (username, password, email, sex) values (?, ?, ?, ?)
Hibernate: insert into t_address (address, phone, user_id) values (?, ?, ?)
Hibernate: insert into t_address (address, phone, user_id) values (?, ?, ?)

数据不正常,address表的userid是null

说明user维护了关系是可以级联添加的,只是inverse了address表的userid当然是null,所以需要在级联保存之前 address维护关系

如下:
user.hbm.xml 设置反转

<set name="addSet" cascade="all" inverse="true">
			<key column="user_id" ></key>
			<one-to-many class="Address" />
		</set>

address.hbm.xml

<many-to-one name="user">
			<column name="user_id"></column>
		</many-to-one>

执行代码(address维护关系)

@Test
	public void testAdd1() {
		// a.创建一个用户
		User user = new User("admin", "admin");

		// b.创建两个地址
		Address a1 = new Address("深圳", "123");
		Address a2 = new Address("北京", "456");

		// 维护关系【给多的一方维护关闭】目的:关联字段的维护权在多的一方
		a1.setUser(user);
		a2.setUser(user);

		// 3.入库
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();

		session.save(user);
		
		transaction.commit();
	}

控制台

Hibernate: insert into t_user (username, password, email, sex) values (?, ?, ?, ?)

只保存了user对象,并没有级联到

说明:只有维护了关系才会级联

解决办法
/**
	 * 保存一的一方多的一方可以自动保存
	 */
	@Test
	public void testAdd1() {

		// 1.造数据

		// a.创建一个用户
		User user = new User("admin", "admin");

		// b.创建两个地址
		Address a1 = new Address("深圳", "123");
		Address a2 = new Address("北京", "456");

		// 2.维护关系【给以的一方维护关系】目的:就保存一的时候多可以自动保存
		user.getAddresses().add(a1);
		user.getAddresses().add(a2);

		// 维护关系【给多的一方维护关闭】目的:关联字段的维护权在多的一方
		a1.setUser(user);
		a2.setUser(user);

		// 3.入库
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();

		session.save(user);
		// session.save(a1);
		// session.save(a2);

		transaction.commit();
	}

这样就可以数据正常 而且不会产生对于的SQL语句

级联删除
@Test
	public void testAdd4() {

		// 3.入库
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		session.delete(session.get(User.class, 182));
		
		transaction.commit();
	}

控制台

Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.email as email0_0_, user0_.sex as sex0_0_ from t_user user0_ where user0_.id=?
Hibernate: select addset0_.user_id as user4_0_1_, addset0_.id as id1_, addset0_.id as id1_0_, addset0_.address as address1_0_, addset0_.phone as phone1_0_, addset0_.user_id as user4_1_0_ from t_address addset0_ where addset0_.user_id=?
Hibernate: delete from t_address where id=?
Hibernate: delete from t_address where id=?
Hibernate: delete from t_user where id=?

多对多

老师和班级是多对多的关系

多对多的关系产生一张中间表,使用组合外键确定外键

创建表和实体类

package com.tamakiakoo.entity;

import java.util.HashSet;
import java.util.Set;

public class Teacher {
	private Integer id;
	private String tname;
	
	
	private Set<Classes> classes = new HashSet<>();
	
	public Teacher(){}
	
	public Teacher(String tname) {
		this.tname=tname;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getTname() {
		return tname;
	}

	public void setTname(String tname) {
		this.tname = tname;
	}

	public Set<Classes> getClasses() {
		return classes;
	}

	public void setClasses(Set<Classes> classes) {
		this.classes = classes;
	}

}

package com.tamakiakoo.entity;

import java.util.HashSet;
import java.util.Set;

public class Classes {

	private Integer id;
	private String cname;
	
	private Set<Teacher> teachers = new HashSet<>();
	
	public Classes(){}
	
	
	public Classes(String cname) {
		super();
		this.cname = cname;
	}





	public Set<Teacher> getTeachers() {
		return teachers;
	}
	public void setTeachers(Set<Teacher> teachers) {
		this.teachers = teachers;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}
	
}

映射文件

Theacher.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- package:实体类的包名 -->
<hibernate-mapping package="com.tamakiakoo.entity">
	
	<class name="Teacher"  table="t_teacher">
		<id name="id" column="id">
			<generator class="native"/>
		</id>
		<property name="tname" />
		
		<set name="classes" table="t_classesteacher">
			<key column="tid"></key>
			<many-to-many class="Classes" column="cid" />
		</set>
		
	</class>

</hibernate-mapping>
Classes.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- package:实体类的包名 -->
<hibernate-mapping package="com.tamakiakoo.entity">
	
	<class name="Classes"  table="t_classes">
		<id name="id" column="id">
			<generator class="native"/>
		</id>
		<property name="cname" />
		
		<set name="teachers" table="t_classteacher">
			<key column="cid" />
			<many-to-many class="Teacher" column="tid"></many-to-many>
		</set>
		
	</class>

</hibernate-mapping>
环境测试
@Test
	public void testAdd() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();

		Teacher teacher = new Teacher("达老师");
		Classes c1 = new Classes("Java_1901");

		session.save(teacher);
		session.save(c1);
		transaction.commit();
	}

遇到如下错误

原因:一般都是配置文件错误,修改配置文件就好了

插入
@Test
	public void testAdd2() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		// 1.0 创建两个老师
		Teacher t1 = new Teacher("达老师");
		Teacher t2 = new Teacher("孙老师");

		// 1.1 创建两个班级
		Classes c1 = new Classes("Java_1901");
		Classes c2 = new Classes("Java_1902");
		
		t1.getClasses().add(c1);
		t1.getClasses().add(c2);
		t2.getClasses().add(c1);
		t2.getClasses().add(c2);
		
		session.save(t1);
		session.save(t2);
		session.save(c1);
		session.save(c2);
		
		transaction.commit();
	}

控制台

Hibernate: insert into t_teacher (tname) values (?)
Hibernate: insert into t_teacher (tname) values (?)
Hibernate: insert into t_classes (cname) values (?)
Hibernate: insert into t_classes (cname) values (?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)

数据都正常

如果只保存 session.save(t1); 和 session.save(t2); 就会会出异常


Hibernate: insert into t_teacher (tname) values (?)
Hibernate: insert into t_teacher (tname) values (?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)

error:"object references an unsaved transient instance - save the transient instance before flushing: com.tamakiakoo.entity.Classes"

级联保存

修改Teacher.hbm.xml配置文件

<set name="classes" table="t_classesteacher"   cascade="all">
			<key column="tid"></key>
			<many-to-many class="Classes" column="cid" />
		</set>
/**
	 * 级联保存
	 */
	@Test
	public void testAdd3() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();

		// 1.造数据
		
		// 1.0 创建两个老师
		Teacher t1 = new Teacher("达老师");
		Teacher t2 = new Teacher("孙老师");
		
		// 1.1 创建两个班级
		Classes c1 = new Classes("Java_1901");
		Classes c2 = new Classes("Java_1902");

		
		// 2.维护关系
		t1.getClasses().add(c1);
		t1.getClasses().add(c2);
		t2.getClasses().add(c1);
		t2.getClasses().add(c2);
		/*
		c1.getTeacheres().add(t1);
		c1.getTeacheres().add(t2);
		c2.getTeacheres().add(t1);
		c2.getTeacheres().add(t2);
		*/
		
		// 3.保存
		session.save(t1);
		session.save(t2);
		
//		session.save(c1);
//		session.save(c2);
		transaction.commit();
	}

控制台

Hibernate: insert into t_teacher (tname) values (?)
Hibernate: insert into t_classes (cname) values (?)
Hibernate: insert into t_classes (cname) values (?)
Hibernate: insert into t_teacher (tname) values (?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)
Hibernate: insert into t_classesteacher (tid, cid) values (?, ?)

数据正常

Fetch与lazy的配合使用

测试代码

@Test
	public void testLoad1() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();

		User user = (User) session.load(User.class, 179);
		System.out.println(user.getUsername());
		System.out.println("===============");
		System.out.println(user.getAddSet().size());
		transaction.commit();
	}
测试一:
<set name="addresses" fetch="subselect" lazy="extra">
    <!-- 关联外键 -->
    <key column="user_id"></key>
    <one-to-many class="Address"/>
</set>
Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.email as email0_0_, user0_.sex as sex0_0_ from t_user user0_ where user0_.id=?
admin
===============
Hibernate: select count(id) from t_address where user_id =?
2

极其懒惰的情况下:在使用的时候只查询使用的那一部分

测试二:
<set name="addSet" cascade="all"  fetch="select" lazy="true">
			<key column="user_id" ></key>
			<one-to-many class="Address" />
		</set>
Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.email as email0_0_, user0_.sex as sex0_0_ from t_user user0_ where user0_.id=?
admin
===============
Hibernate: select addset0_.user_id as user4_0_1_, addset0_.id as id1_, addset0_.id as id1_0_, addset0_.address as address1_0_, addset0_.phone as phone1_0_, addset0_.user_id as user4_1_0_ from t_address addset0_ where addset0_.user_id=?
2

懒惰的情况下:在使用的时候才查询

测试三:
<set name="addSet" cascade="all"  fetch="select" lazy="false">
			<key column="user_id" ></key>
			<one-to-many class="Address" />
		</set>
Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.email as email0_0_, user0_.sex as sex0_0_ from t_user user0_ where user0_.id=?
Hibernate: select addset0_.user_id as user4_0_1_, addset0_.id as id1_, addset0_.id as id1_0_, addset0_.address as address1_0_, addset0_.phone as phone1_0_, addset0_.user_id as user4_1_0_ from t_address addset0_ where addset0_.user_id=?
admin
===============
2

不懒惰 还没有查询的时候就已经查询好了

总结

  • fetch:select
    • lazy:true:地址使用到的时候才会发送sql语句查询
    • lazy:false,地址不适用也会查询
    • lazy:extra,:地址使用到的时候才会发送sql语句查询,统计数量的时候用count查询
  • fetch:join
    • 由于join语法本身的原因,lazy属性设置无效
  • subselect
    • 用get和load查询结果和select的一样
    • 在一定的场景下才可以看出select和subselect的区别,用hql查询

batch-size

<!--  一次查询2个用户的地址 -->
		<set name="addresses" batch-size="2">
			<key column="user_id"></key>
			<one-to-many class="Address" />
		</set>

测试代码

    @Test
	public void testGetUserList() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();

		Query query = session.createQuery("from User"); // hql
		
		List<User> userList= query.list();
		for (User user : userList) {
			System.out.println(user.getUsername()+":"+user.getAddSet().size());
		}
 		
		transaction.commit();
	}
Hibernate: select user0_.id as id0_, user0_.username as username0_, user0_.password as password0_, user0_.email as email0_, user0_.sex as sex0_ from t_user user0_
上面是查询所有用户的

Hibernate: select addset0_.user_id as user4_0_1_, addset0_.id as id1_, addset0_.id as id1_0_, addset0_.address as address1_0_, addset0_.phone as phone1_0_, addset0_.user_id as user4_1_0_ from t_address addset0_ where addset0_.user_id in (?, ?)
admin1:0

Hibernate: select addset0_.user_id as user4_0_1_, addset0_.id as id1_, addset0_.id as id1_0_, addset0_.address as address1_0_, addset0_.phone as phone1_0_, addset0_.user_id as user4_1_0_ from t_address addset0_ where addset0_.user_id in (?, ?)
admin:0

Hibernate: select addset0_.user_id as user4_0_1_, addset0_.id as id1_, addset0_.id as id1_0_, addset0_.address as address1_0_, addset0_.phone as phone1_0_, addset0_.user_id as user4_1_0_ from t_address addset0_ where addset0_.user_id in (?, ?)
admin:0
admin:0
admin:2

Hibernate: select addset0_.user_id as user4_0_1_, addset0_.id as id1_, addset0_.id as id1_0_, addset0_.address as address1_0_, addset0_.phone as phone1_0_, addset0_.user_id as user4_1_0_ from t_address addset0_ where addset0_.user_id in (?, ?)
admin:0
admin:0
赵莉:0


一次查询2个地址,数据库里面有8个地址 需要查询4次

上面是1-1-3-3 我猜测是输出快慢的原因

HQL查询

  • HQL(Hibernate Query Language)提供了丰富灵活的查询方式,使用HQL进行查询也是Hibernate官方推荐使用的查询方式。

  • HQL在语法结构上和SQL语句十分的相同,所以可以很快的上手进行使用。使用HQL需要用到Hibernate中的Query对象,该对象专门执行HQL方式的操作

查询所有示例

session.beginTransaction();
String hql = "from User"; // from 后跟的是要查询的对象,而不是表
Query query = session.createQuery(hql);

List<User> userList = query.list();

for(User user:userList){
    System.out.println(user.getUserName());
}

session.getTransaction().commit();

带where的查询示例


session.beginTransaction();
String hql = "from User where userName = 'James'";
Query query = session.createQuery(hql);

List<User> userList = query.list();
for(User user:userList){
    System.out.println(user.getUserName());
}
session.getTransaction().commit();

/*
在HQL中where语句中使用的是持久化对象的属性名,如上面示例中的userName。当然在HQL中也可以使用别名
*/

String hql = "from User as u where u.userName = 'James'";

/*
过滤条件
在where语句中还可以使用各种过滤条件,如:=、<>、<、>、>=、<=、between、not between、
in、not in、is、like、and、or等
*/

获取一个不完整的对象

session.beginTransaction();
String hql = "select userName from User";
Query query = session.createQuery(hql);

List<Object> nameList = query.list();
for(Object obj:nameList){
   String name=(String)obj;
   System.out.println(name);
}

session.getTransaction().commit();

// 多个属性的话,需要用object[]接收
session.beginTransaction();
String hql = "select userName,userPwd from User";
Query query = session.createQuery(hql);

List nameList = query.list();
for(Object obj:nameList){
    Object[] array = (Object[]) obj; // 转成object[]
    System.out.println("name:" + array[0]);
    System.out.println("pwd:" + array[1]);
}
session.getTransaction().commit();

统计和分组查询

session.beginTransaction();
String hql = "select count(*),max(id) from User";
Query query = session.createQuery(hql);

List nameList = query.list();
for(Object obj:nameList){
    Object[] array = (Object[]) obj;
    System.out.println("count:" + array[0]);
    System.out.println("max:" + array[1]);
}

session.getTransaction().commit();

/*
该条sql语句返回的是单条数据,所以还可以这样写
单列数据用Object,多列数据用Object[]
*/
Object[] object = (Object[]) query.uniqueResult();
System.out.println("count:" + object[0]);
System.out.println("max:" + object[1]);

更多写法

select distinct name from Student;
select max(age) from Student;
select count(age),age from Student group by age;
from Student order by age;

HQL占位符

session.beginTransaction();
String hql = "from User where userName = ?";
Query query = session.createQuery(hql);

// 索引从0开始
query.setString(0, "James");
List<User> userList = query.list();

for(User user:userList){
    System.out.println(user.getUserName());
}
session.getTransaction().commit();

HQL引用占位符

session.beginTransaction();
String hql = "from User where userName = :name";
Query query = session.createQuery(hql);
query.setParameter("name", "James");

List<User> userList = query.list();
for(User user:userList){
    System.out.println(user.getUserName());
}
session.getTransaction().commit();

HQL分页

session.beginTransaction();
String hql = "from User";

Query query = session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(2);

List<User> userList = query.list();

for(User user:userList){
    System.out.println(user.getUserName());
}
session.getTransaction().commit();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值