hibernate《轻量级框架应用与开发--S2SH》笔记

hibernate入门

hibernate框架

hibernate的持久化解决方案将开发者从复杂的JDBC访问中释放出来,用户无需关注底层的JDBC操作,一面想对象的形式进行持久层操作。
将应用层从底层的JDBC/JTA API中抽象出来。通过配置文件管理底层JDBC链接,让Hibernate解决持久化访问的实现。

hibernate主要对象和功能

https://blog.csdn.net/weixin_34306446/article/details/91927193

hibernate的api(就是操作的时候使用的对象)
Configuration接口:配置和启动Hibernate,创建SessionFactory对象,Hibernate应用通过Configuration实例获得对象-关系映射文件的源数据,以及动态配置Hibernate的属性,然后创建sessionFactory实例;
SessionFactory接口:初始化Hibernate,充当数据存储源的代理,创建session对象;
session接口:也成为了持久化管理器,提供持久化相关的操作,如保存、更新、删除、加载和查询对象;
Transaction:接口:管理实务;
Query和Criteria接口:执行数据库查询,Query接口用于执行HQL数据库查询,而Criteia接口用于QBC检索方式。

在这里插入图片描述

持久化对象

1、创建pojo
2、创建student.hbm.xml(注意pojo和hbm.xml映射文件要在同一个目录下面)

student.java

package com.qst.chapter05.pojos;

public class Student {
	// 属性
	private String id;
	private String name;
	private int score;

	// 省略getter和setter方法

}

student.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">
<hibernate-mapping>
	<class name="com.qst.chapter05.pojos.Student" table="STUDENTS">
		<id name="id" column="ID">
			<generator class="uuid.hex" />
		</id>
		<property name="name" column="NAME" type="string" not-null="true" />
		<property name="score" column="SCORE" type="java.lang.Integer" not-null="true" />
	</class>
</hibernate-mapping>

hibernate配置文件

hibernate配置文件用于配置访问数据库的一些参数,比如链接数据库的URL链接字符串、用户名、密码以及是否创建或更新表等信息。

常用的形式是新建hibernate.cfg.xml文件
hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 配置访问Oracle数据库参数信息 -->
		<property name="dialect">
			org.hibernate.dialect.OracleDialect
		</property>
		<property name="connection.driver_class">
			oracle.jdbc.driver.OracleDriver
		</property>
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:orcl
		</property>
		<property name="connection.username">scott</property>
		<property name="connection.password">scott123</property>
		<!-- 在控制台显示SQL语句 -->
		<property name="show_sql">true</property>
		<!--根据需要自动生成、更新数据表 -->
		<property name="hbm2ddl.auto">update</property>
		<!-- 注册所有ORM映射文件 -->
		<mapping resource="com/qst/chapter05/pojos/Student.hbm.xml" />
		<mapping resource="com/qst/chapter05/pojos/User.hbm.xml" />

	</session-factory>
</hibernate-configuration>

hibernae-configuration,hibernate配置文件根元素
session-factory,根元素的子元素
property,session-factory子元素,用于配置方位数据库参数信息,可以有多个property
mapping:session-factory子元素,用于注册所有orm樱色号文件,每个mapping子元素注册一个hibernate映射文件,可以有多个mapping子元素。

hibernate配置文件常用属性

属性功能描述
hibernate.dialect针对不同数据库提供不同方言,允许hibernate针对特定数据库生成优化sql语句
hibernate.connection.driver_class数据库驱动类
hibernate.connection.datasource数据库原的jndi名字
hibernate.connection.urlJNDI数据库提供的URL
hibernate.connection.username连接数据库用户名
hibernate.connection.password链接数据库的password
hibernate.connection.pool_size数据库连接池的最大容量
hibernate.show_sql是否输出hibernate操作数据库使用的sql语句
hibernate.format_sql是否格式化输出的sql语句
hibernate.hbm2ddl.auto是否根据映射文件自动创建数据库表,有create、create-drop\updateqizhong,create会根据pojo创建表,每次运行重新生成表;值为create-drop,关闭sessionFactory是自动删除创建的表;update最常用属性,不会删除以前的行记录

hibernate映射文件

hibernate映射文件根元素是hibernate-mapping,该元素有多个class子元素,每个class元素对应一个pojo持久化类的映射,将类和表之间关系进行映射。

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">
	<hibernate-mapping>
		<class name="com.qst.chapter05.pojos.User" table="tbUsers">
			<id name="id" column="ID">
				<generator class="native"></generator>
			</id>
			<property name="userName" column="USERNAME" type="string" not-null="true"></property>
			<property name="userPwd" column="USERPWD" type="string" not-null="true"></property>
			<property name="role" column="ROLE" type="java.lang.Interger" not-null="true"></property>
		</class>
	</hibernate-mapping>

class元素常用属性

属性功能描述
name持久化类名(java pojo类)
table持久化类映射的表名(数据表名)
discriminator-value区分不同子类的值
mutable指定持久化类实例是否可变,默认为true
proxy延迟装载是的代理,可以是该类自己的名称

id常用属性

属性功能描述
name标识属性名
type标识属性的数据类型,改数据类型既可以是hibernate内奸诶性,也可以是java类型
column标识属性锁映射的数据库中标的列名
unsaved-value指定刚创建、未保存的某个实例的表示属性值
access指定访问表示属性的访问策略,默认property

主键生成器列表

类型名功能描述
increment获取数据库表所有主键最大值,最大值基础上加1
identity自动增长。MS SQL Server、MySQL和DB2数据库可以设置表单额某个字段的数值增长
sequence序列。Oracle、DB2等数据库可以创建一个序列,然后从序列中获取当前序列号作为主键值
hilo高低位高效算法产生主键
seqhilo使用指定sequence获取高位置
uuid采用128位uuid算法生成字符串类型的主键
guid采用guid字符串产生主键值
native有hibernate根据使用的数据库支持能力从identity、sequence或者hilo中选择,例如oracle使用sequence,MySQL用identity
assigned指派值
foreign通过关联持久化对象为主键赋值

在使用生成策略。
应用系统不需要分布式,数据库支持情况下使用sequence、identity、hilo、seqhilo和uuid
应用需要使用多个数据库或者进行分布式部署,使用uuid最佳

创建hibernate完整过程

1、配置hibernate应用环境,在应用中添加hibernate所需要的的jar包,创建hibernate配置文件;
2、编写po
3、创建configuration对象
4、创建sessionfactory对象;
5、获取session对象
6、transaction管理实务
7、使用Query进行HQL查询后利用Criteria实现条件查询

session中的方法

方法功能描述
save()保持持久化对象,在数据库中新增一条记录
get()获取数据库中一条记录,当未找到符合条件的持久化对象是返回null
load()获取数据库中一条记录,当没找到符合条件的持久化对象是抛出异常
update()更新数据库中敌营的数据
delete()删除数据库中的一条记录

session获取多条数据查询
使用Query进行hql查询或使用Criteria进行查询

Query query = session.createQuery("from User");
List<User> list = query.list();

Criteria criteria = session.createCriteria(Student.class);
List<Student> list = criteria.list();

导入相应的hibernate包
新建hibernate.cfg.xml文件

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 配置访问Oracle数据库参数信息 -->
		<property name="dialect">
			org.hibernate.dialect.OracleDialect
		</property>
		<property name="connection.driver_class">
			oracle.jdbc.driver.OracleDriver
		</property>
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:orcl
		</property>
		<property name="connection.username">scott</property>
		<property name="connection.password">scott123</property>
		<!-- 在控制台显示SQL语句 -->
		<property name="show_sql">true</property>
		<!--根据需要自动生成、更新数据表 -->
		<property name="hbm2ddl.auto">update</property>
		<!-- 注册所有ORM映射文件 -->
		<mapping resource="com/qst/chapter05/pojos/Student.hbm.xml" />
		<mapping resource="com/qst/chapter05/pojos/User.hbm.xml" />
	</session-factory>
</hibernate-configuration>

创建pojo、pojo.hbm.xml、修改hibernate.cfg.xml添加mapping映射文件

User.java

package com.qst.chapter05.pojos;

import java.io.Serializable;

public class User implements Serializable {
	/* 用户ID */
	private Integer id;
	/* 用户名 */
	private String userName;
	/* 密码 */
	private String userPwd;
	/* 权限 */
	private Integer role;
	/* 默认构造方法 */
	public User() {
	}
	/* 根据属性创建 构造方法 */
	public User(String userName, String userPwd,Integer role) {
		this.userName = userName;
		this.userPwd=userPwd;
		this.role=role;
	}
	//省略getter和setter方法

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">
	<hibernate-mapping>
		<class name="com.qst.chapter05.pojos.User" table="tbUsers">
			<id name="id" column="ID">
				<generator class="native"></generator>
			</id>
			<property name="userName" column="USERNAME" type="string" not-null="true"></property>
			<property name="userPwd" column="USERPWD" type="string" not-null="true"></property>
			<property name="role" column="ROLE" type="java.lang.Interger" not-null="true"></property>
		</class>
	</hibernate-mapping>

hibernate.cfg.xml在session-factory子元素最后添加

<mapping resource="com/qst/chapter05/pojos/User.hbm.xml" />

测试
UserDemo

package com.qst.chapter05.demo;

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

import com.qst.chapter05.pojos.User;

public class UserDemo {

	public static void main(String[] args) {
		// 创建User对象
		User user = new User("zhangsan", "123", 1);
		// 实例化Configuration
		Configuration configuration = new Configuration();
		// 加载hibernate.cfg.xml文件
		configuration.configure("/hibernate.cfg.xml");
		// 创建SessionFactory
		// Hibernate4.3创建SessionFactory的方式
		StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder();
		standardServiceRegistryBuilder.applySettings(configuration
				.getProperties());
		SessionFactory sessionFactory = configuration
				.buildSessionFactory(standardServiceRegistryBuilder.build());
		// 打开Session
		Session session = sessionFactory.openSession();
		// 开始一个事务
		Transaction trans = session.beginTransaction();
		// 持久化操作
		session.save(user);
		// 提交事务
		trans.commit();
		// 关闭Session
		session.close();
	}

}

pojo状态

瞬时状态:刚刚new对象,没有持久化,没有与hibernate session关联,不处于session的缓存之中。处于顺势状态的对象被称为瞬态对象,瞬态对象不会被持久化到数据库。也不会被赋予持久化表示。

持久化状态:已经被持久化加入session缓存中,数据库表中记录对应,并且拥有一个持久化表示。持久化状态对象可以保存,也可以被夹在。hi贝尔纳特检测到持久化状态的对象可以任何改动,并且在session关闭或者transaction提交的时候更新数据库中的对应数据,不需要手动更新。

脱管状态:已经被持久化,不再session缓存中,如果对象曾经处于持久化状态,但是与之关联的session关闭后,该对象变成托管状态,如果该对象与某个session重新关联又变成持久化状态

hibernate工具类
HibernateUtils.java

package com.qst.chapter05.util;

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

public class HibernateUtils {
	private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
	private static final ThreadLocal<Session> threadLocal 
									= new ThreadLocal<Session>();
	private static Configuration configuration = new Configuration();
	private static StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder();
	private static SessionFactory sessionFactory;
	private static String configFile = CONFIG_FILE_LOCATION;
	/* 静态代码块创建SessionFactory */
	static {
		try {
			configuration.configure(configFile);
			//Hibernate4.3创建SessionFactory的方式
			standardServiceRegistryBuilder.applySettings(configuration.getProperties());
			sessionFactory = configuration.buildSessionFactory(standardServiceRegistryBuilder.build());
		} catch (Exception e) {
			System.err.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
	}
	private HibernateUtils() {
	}
	/**
	 * 返回ThreadLocal中的session实例
	 */
	public static Session getSession() throws HibernateException {
		Session session = (Session) threadLocal.get();
		if (session == null || !session.isOpen()) {
			if (sessionFactory == null) {
				rebuildSessionFactory();
			}
			session = (sessionFactory != null) ? sessionFactory.openSession()
					: null;
			threadLocal.set(session);
		}
		return session;
	}
	/**
	 * 返回Hibernate的SessionFactory
	 */
	public static void rebuildSessionFactory() {
		try {
			configuration.configure(configFile);
			sessionFactory = configuration.buildSessionFactory(standardServiceRegistryBuilder.build());
		} catch (Exception e) {
			System.err.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
	}
	/**
	 * 关闭Session实例并且把ThreadLocal中副本清除
	 */
	public static void closeSession() throws HibernateException {
		Session session = (Session) threadLocal.get();
		threadLocal.set(null);
		if (session != null) {
			session.close();
		}
	}
	/**
	 * 返回SessionFactory
	 */
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	public static void setConfigFile(String configFile) {
		HibernateUtils.configFile = configFile;
		sessionFactory = null;
	}
	public static Configuration getConfiguration() {
		return configuration;
	}
}


HibernateSessionDemo.java

package com.qst.chapter05.demo;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.qst.chapter05.pojos.User;
import com.qst.chapter05.util.HibernateUtils;

public class HibernateSessionDemo {

	public static void main(String[] args) {
		// 调用getUser()方法获取用户对象
		User user = getUser(new Integer(1));
		System.out.println("--------原始数据-----------");
		System.out.println(user.getId() + "\t" + user.getUserName()
				+ "\t" + user.getUserPwd() + "\t" +user.getRole());
		user.setUserPwd("987654");
		// 调用changeUser()方法修改用户对象信息
		changeUser(user);
		System.out.println("--------修改后的数据-----------");
		System.out.println(user.getId() + "\t" + user.getUserName()
				+ "\t" + user.getUserPwd() + "\t" +user.getRole());
	}
	/* 获取用户 */
	public static User getUser(Integer key) {
		Session session = HibernateUtils.getSession();
		Transaction trans = session.beginTransaction();
		// 根据主键获取用户对象
		User user = (User) session.get(User.class, key);
		trans.commit();
		HibernateUtils.closeSession();
		return user;
	}
	/* 修改用户信息 */
	public static void changeUser(User user) {
		Session session = HibernateUtils.getSession();
		Transaction trans = session.beginTransaction();
		// 更新
		session.update(user);
		trans.commit();
		HibernateUtils.closeSession();
	}

}

hibernate进阶

hibernate关联关系

单向N-1关系(many-to-one) 比如订单和客户

实际开发当中不建议使用单向1-N关联,建议使用双向1-N关联,在1端配置<set>,在N端配置<many-to-one>元素即可形成双向关联

1、在N类中添加1类的对象,比如
Order.java中添加
private Customer customer;

2、order.hbm.xml中添加

<many-to-one name="customer" column="CUSTOMER_ID" class="Customer"/>

3、检查hibernate.cfg.xml是否添加链接

N-1关联成功建立

many-to-one属性介绍

属性名描述
name指定属性名称,例如order类中的customer属性名
column指定进行关联的外键列的列名,例如,order表的外键CUSTOMER_ID
class指定关联实体的类名,默认通过反射得到该属性所属类的类名
cascade指定哪些持久化操作会从主表记录级联到子表记录
fetch指定hibernate抓取策略可以join和select
property-ref指定关联类中的属性,该属性和贝类外检对象,默认直接使用地方关联类的主键
access指定hibernate访问此关联属性的访问策略,默认是property
unique指定hibernatte通过DDL为外检列添加唯一约束,可以用作property-ref的目标属性
lazy指定引用关联实体的延迟加载特性,该属性只能接受false、proxy、no-proxy三个值:hibernate默认会启动但实力代理,当指定no-proxy是实例变量第一次被访问采用延迟抓取,指定为false关联实体总是被预先抓取。
not-null指定DDL为外键字段添加非空约束,如果为true表示不为空。默认为false,该属性会影响hi贝尔纳特运行行为,比如hibernate保存order对象,检查customer属性是否为null
not-found该属性指定当外检参照的主表记录不存在是如何处理,是ignore和exeption(默认)
formula指定一个sql表达式,改外键值根据sql表达式计算

实例请看第六章order和customer N-1的实例 193页

单向1-N关系映射(set) 比如客户和订单

1、添加customer中的属性,表示1-N
private Set orders = new HashSet(0);

2、customer.hbm.xml的class紫属性中添加set标签

<set name="orders">
	<key column="CUSTOMER_ID"/>
	<one-to-many class="Order"/>
</set>

双向关联(1-N)实际开发推荐使用

双向关联就是单向1-N和N-1同时配置,注意实际开发建议同时配置。
步骤
1、在N类中添加1类的对象,比如
Order.java中添加

private Customer customer;

2、order.hbm.xml中添加

<many-to-one name="customer" column="CUSTOMER_ID" class="Customer"/>

3、添加customer中的属性,表示1

private Set<Order> orders = new HashSet<Order>(0);

4、customer.hbm.xml的class紫属性中添加set标签

<set name="orders">
	<key column="CUSTOMER_ID"/>
	<one-to-many class="Order"/>
</set>

1-1关联(one-to-one)

one-to-one在两个对象中加上相应对象的属性
被关联对象修改,同时对关联对象进行级联操作

基于外键单向,可以理解为特殊的单向N-1关系,N端为1 N端用many-to-one 设置unique属性
基于主键单向,基于主键的关联持久化类不能拥有自己的主键生成策略,主键有关联实体负责生成
基于外键双向,外键可以房子啊任意一边,存储外键的一端增加<many-to-one>元素,另一端需要使用<one-to-one>元素
基于主键的双向1-1关联,连个关联表使用相同的主键值,其中一个表的主键值共享另外一个表的主键值

基于主键双向,关联和被关联对象都用one-to-one,但是被关联对象设置cascade属性,关联对象设置constrained属性

基于外键的双向1-1
1、IdCard添加

private Customer customer;

2、Customer添加

private IdCard idCard;

2、IdCard.hbm.xml添加

<one-to-one name="customer" class="Customer" constrained="true"/>

3、Customer.hbm.xml添加

<many-to-one name="idCard" class="IdCard" cascade="all" column = "IDCARD_ID" unique="true"/>

基于主键的双向1-1
1、添加IdCard.hbm.xml

<one-to-one name="customer" class="Customer" class="Customer" constrained="true">

2、添加Customer.hbm.xml

<one-to-one name="idCard" class="IdCard" cascade="all">

N-N拆分两个1-N关联实现(Order和Product)

实际开发当中,数据库表之间N-N关联使用不太多,通常是拆分成连个1-N关联实现,同样在hibernate中也是使用两个1-N替换N-N关联。

1、创建中间表OrderItem(id,order,product,)
2、orderitem.hbm.xml添加<many-to-one>对应order和product
3、在order.hbm.xml和product.hbm.xml中添加<set>标签 <one-to-many>

创建OrderItem.java

package com.qst.chapter06.pojos;

public class OrderItem {

	private Integer id;
	private Order order;
	private Product product;
	private Integer quantity;
	private Double purchasePrice;
	//省略getter和setter方法
}

order.hbm.xml
添加<set> 1-N标签

<?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.qst.chapter06.poojos">
		<class name="OrderItem" table="ORDERITEM">
			<id name="id" column="ID">
			<generator class="native"></generator>
			</id>
			<many-to-one name="order" class="Order" column="ORDER_ID"></many-to-one>
			<many-to-one name="product" class="Product" column="PRODUCT_ID"></many-to-one>
			<property name="quantity" column="QUANTITY" type="integer"></property>
			<property name="purchasePrice" column="PURCHASEPRICE" type="double"></property>
		</class>
	</hibernate-mapping>

Product.hbm.xml
添加<1-n标签>

<?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.qst.chapter06.poojos">
		<class name="Product" table="PRODUCT">
			<id name="id" column="ID">
				<generator class="native"/>
			</id>
			<property name="name" column="NAME" type="string" not-null="true"></property>
			<property name="price" column="PRICE" type="double" not-null="true"></property>
			<property name="description" column="DESCRIPTION" type="string"></property>
			
			<set name="orders" table="ORDERITEM">
				<key column="PRODUCT_ID"></key>
				<many-to-many class="Order" column="ORDER_ID"></many-to-many>
			</set>
			
<set name="orderitems" table="ORDERITEM" inverse="true">
	<key column="PRODUCT_ID"></key>
	<one-to-many class="OrderItem"></one-to-many>
</set>
		</class>
	</hibernate-mapping>

级联关系(比如修改customer同时修改order关联对象)

持久化对象通过关联关系相互引用是很常见的,通常对其中一个对象进行修改、删除或更新等操作的时候,被关联的对象需要进行相应的操作。进行这样的操作的时候通过使用hibernate的级联功能即可解决。

cascade属性级介绍

属性值描述
none默认值表示关联对象之间无级联操作
save-update表示主动方在调用save()、update()和saveOrUpdate()方法是对被关联对象执行保存或更新操作
delete表示主动方独享调用delete()是对被关联对象执行删除操作
delete-orphan用在1-N关联中,表示主动方对象调用delete()方法是删除不被任何一个关联对象锁引用的关联对象,多用于父子关联对象中
all等价于save-update和delete的联合使用

1、修改Customer.hbm.xml(关联对象) <set>标签添加inverse="true"关联关系交给order和cascade="save-update"交给对方保存和修改

<set name="orders" inverse="true" cascade="save-update">
				<key column="CUSTOMER_ID"></key>
				<one-to-many class="Order"/>
			</set>

HQL与QBC查询和批量处理

hql查询带有sql语句,qbc查询完全是java语句查询

hql查询依赖于query对象,通常hql的检索方式步骤如下
1、获取hibernate的session对象;
2、编写hql查询语句;
3、以hql作为参数,调用session对象的createquery()方法,创建query对象;
4、如果hql语句中包含参数,调用query对象的setXXX()方法为参数赋值;
5、调用query对象的list()等方法得出查询结果。
HQL查询依赖于query接口,query是hibernate提供的查询接口,每个query实例都对应一个查询对象,用于向数据库查询对象以及控制执行查询的过程。

hql查询关键字

关键字功能示例
from指定查询类from Customer(返回Customer类的所有实例,默认情况下省略select子句,返回实例所有属性)
where指定条件,用来筛选数据源from Customer where address=‘青岛市’(返回地址是"青岛市"的所有Customer实例,其中address是Customer类的属性)
select执行查询后,返回元素所包含的内容select realName,address from Customer
group by对查询结果进行分组select count(o) from
order by对查询结果进行排序from Customer order by age(默认按照属性age进行升序排序,可以使用asc或desc关键字之名了按照升序或降序进行)
joinjoin单独使用是表示内连接,left join表示做外链接,right join表示右外连接select c from Customer c inner join fecth c.orders(返回Customer的所有实例,并把该实例的orders属性进行预先加载,而不是延迟加载)
fetch一次性去除当前对象和锁被关联的对象,也叫预先抓取对象select c from Customer c inner join c.orders(返回Customer的所有实例,并把该实例的orders属性进行预先加载,不是延迟加载)

Query接口的方法及描述

方法名描述
int executeUpdate()执行更新或删除等操作,返回值是首次操作影响的记录数
Iterator iterate()返回一个Iterator对象,用于迭代查询的结果集。使用该方法是,首先检索ID字段,然后根据ID字段到Hibernate的一级缓存和耳机缓存中查找匹配的对象,如果存在就放到结果集中,否则执行额外的select语句,根据ID查询数据库。如果对象位于缓存中,该方法性能比list()方法要高
List list()返回List类型的结果集,如果是投影查询即查询部分属性,则返回Object[]形式
Query setFirstResult(int first)设定开始检索的起始位置,参数first表示帝乡在查询结果中的索引位置,索引位置的其实质为0.默认情况下,query接口从索引位置为0的对象开始检索
Query setMaxResult(int max)设定一次最多检索出的对象数据,默认情况下,query接口检索出查询结果中的所有对象,该方法通常和setFirstReuslt()方法匹配实现分页查询
Object uniqueResult()返回单个对象,如果没有查询到结果则返回null,该方法通常和setMaxResul()方法配合使用,用于返回单个对象
Query setString(String name,Stringval)绑定映射类型为String的参数,query接口提供了绑定各种hibernate映射类型的参数的方法
Query setEntity(String name,Object val)把参数与一个持久化对象绑定,该方法有多个重载方法
Query setParameter(String name,Object val)用于绑定任意类型的参数,该方法有多个重载方法
Query setProperties(String name,Object val)用命名参数与一个对象的属性值绑定,该方法有多个重载方法

使用hql查询

//1、获取session对象
Session session = HibernateUtils.getSession();
//2、编写hql语句
String hql = "from Customer c where c.address=:address";
//3、以HQL作为参数,调用session的createQuery()方法创建Query对象
Query query = session.createQuery(hql);
//4、调用Query对象的setXXX()方法为参数赋值
query.setString("address",address);
//5、调用Query对象的list()等方法得到查询结果
List<Customer> list = query.list();
//遍历输出结果
for(Customer c:list){
	System.out.println(c.getId()+"\t"+c.getUserName());
}

QBC检索
主要通过连个接口和一个工具类实现
Criteria接口,代表依次查询;
Criterion接口,代表一个查询条件;
Restrictions类,产生查询条件的工具类;

QBC检索方式的步骤:
1、获取Hibernate的Session对象;
2、调用Session对象的createCriteria()方法,创建Criteria对象;
3、调用Criteria对象的add()方法,增加Criterion查询条件;
4、执行Criteria的list()或uniqueResult()方法返回查询结果集。

//1、获取Session对象
Session session = HibernateUtils.getSession();
//2、以Customer的Class对象作为参数,创建Criteria对象
Criteria critera = session.createCriteria(Customer.class);
//3、调用Criteria对象的add()方法,增加Criterion查询条件
critera.add(Restrictions.eq("address",address));
//4、执行Criteria的list()方法,增加Criterion查询条件
List<Customer> list = critera.list();
//遍历输出结果
for(Customer c:list){
	System.out.println(c.getId()+"\t"+c.getUserName());
}

查询结果排序
1、HQL查询结果排序
使用order by升序和降序
注意hql语句中order by

Session session = HibernateUtils.getSession();
String hql = "from Customer c order by c.uesrName desc";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
for(Customer c:list){
System.out.println(c.getId()+"\t"+c.getUserName());
}

2、Criteria查询结果排序
使用org.hibernate.criterion.Order类对查询结果进行排序,其中Order类是代表排序的类,该类提供了asc()和desc()两个静态方法,用于升序和降序。

Session session = HibernateUtils.getSession();
Criteria critera = session.createCriteria(Customer.class);
critera.addOrder(org.hibernate.criterion.Order.desc("userName"));
List<Customer> list = critera.list();
for(Customer c:list){
	System.out.println(c.getId()+"\t"+c.getUserName());
}

分页查询
1、HQL分页查询
通过Query接口中的setFirstResult和setMaxResult实现

//pageNo表示第几页,perPageNum表示一页多少条记录
Session session = HibernateUtils.getSession();
String hql = "from Customer c order by c.userName desc";
Query query = session.createQuery(hql);
query.setFirstResult(pageNo-1)*perPageNum);
queyr.setMaxResults(perPageNum);
List<Customer> list = query.list();

Criteria分页查询
通过Criteria接口中的setFirstResult()和setMaxResults()方法结合使用

Session session = HibernateUtils.getSession();
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFristResult((pageNo-1)*perPageNum);
criteria.setMaxResults(perPageNum);
List<Customer> list = criteria.list();

查询单条记录
1、先调用Query或Criteria接口中的setMaxResults(1)方法,将最大检索数设置为1;
2、然后调用uniqueResult()方法返回一个Object类型的对象。

HQL绑定参数
查询条件,绑定参数返回
创建查询语句
使用:name命名

Session session = HibernateUtils.getSession();
String hql = "from Customer as c where c.userName = :name";
Query query = session.createQuery(hql);
query.setString("name",name);

使用?

设定查询条件

userName查询

Session session = HibernateUtils.getSession();
String hql = "from Customer as c where c.userName = ?";
Query query = session.createQuery(hql);
query.setString(0,name);

比较运算
HQL检索地址不是"青岛"的Customer
session.createQuery(“from Customer c where c.address <> ‘青岛’”)

范围运算
HQL检索在指定范围
session.createQuery(“from Customer c where c.userName in(‘zhangsan’,‘list’,‘wangwu’)”);

指定订单日期为2015年3月

String hql = "from Order o where o.date between ? and ?";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
	List<Order> list = session.createQuery(hql).setParameter(0,dateFormat.parse("2015-03-01 00:00:00")).setParameter(1,dateFormat.parse("2015-03-31 23:59:59")).list();
}catch(ParseException e){
	e.printStckTrace();
}

字符串匹配
hql检索用户名以z开头的Customer
session.createQuery(“from Customer c where c.userName like ‘z%’”);

逻辑运算
HQL检索用户已z开头
session.createQuery(“from Customer c where c.userName like ‘z%’ and c.address=‘青岛’”)

连接查询
Hql连接查询
内连接(inner join)

String hql = "from Customer c inner join c.orders o where c.userName like :name";
Query query = session.createQuery(hql);
query.setString("name","z%");

预先抓取内连接(inner join fetch)

String hql = "from Customer c inner join fetch c.orders o where c.userName like :name";
Query query = session.createQuery(hql);
query.setString("name","z%");
List<Customer> list = query.list();
Set<Customer> set = new HashSet<Customer>(list);

分组与统计查询
HQL常用统计函数

函数名称功能
count()统计记录条数
min()求最小值
max()求最大值
sum()求和
avg()求平均值

例如:

String hql = "select count(p.id) from Product p";
Long count = (Long)session.createQuery(hql).uniqueResult();

动态查询
HQL动态查询

Session session = HibernateUtils.getSession();
StringBuffer buffer = new StringBuffer();
buffer.append("from Product p where 1=1");
if(name!=null&&!name.equals("")){
	buffer.append("and lower(p.name) like :name");
}
if(price != null && price != 0){
	buffer.append("and p.price = :price");
}
Query query = session.createQuery(buffer.toString());
if(name!=null){
	query.setString("name",""%"+name.toLowerCase()+"%"");
}
if(price!=null&&price!=0){
	query.setDouble("price",price);
}

QBC动态查询

Session session = HibernateUtils.getSession();
Criteria criteria = session.createCriteria(Product.class);
if(name != null){
	criteria.add(Restrictions.ilke("name",name,MatchMode.ANYWHERE));
}
if(price!=null&&price!=0){
	criteria.add(Restrictioins.eq("price",price));
}

单行子查询

Session session = HibernateUtils.getSession;
String hql = "from Product p where p.price = (select p1.price from Product p1 where p1.name = :name) and p.name!=:name";
Query query = session.createQuery(hql);
queyr.setStirng("name","打印机");

多行子查询
多行运算符
all运算符,返回所有订单的价格小于100的客户
from Customer c where 100>all(select o.total from c.orders o)
any运算符,返回一条订单价格小于100的客户
from Customer c where 100>and(select o.total from c.orders o)
in运算符。返回一条订单的价格等于100的客户
from Customer c where 100 in(select o.total from c.orders o)
返回至少一个订单客户
from Customer c where exists(from c.orders)

批量添加

Session session = HibernateUtils.getSession();
Transaction trans = session.beginTransaction();
for(int i = 0;i<1000000;i++){
Customer customer = new Customer();
session.save(customer);
//没保存10个Customer对象清空一次缓存
if(i%10==0){
session.flush();
session.clear();
trans.commit();
trans=session.beginTransaction();
}
}

批量更新

Session session = HibernateUtils.getSession();
Transaction trans = session.beginTransaction();
ScrollableResults customers = session.createQuery("from Customer").scroll();
int count = 0;
while(customers.next()){
	Customer customer = (Customer)customers.get(0);
	customer.setUserName("username"+count);
	if(i%10==0){
session.flush();
session.clear();
trans.commit();
trans=session.beginTransaction();
}
count++;	
}
trans.commit();
HibernateUtils.closeSession();
}

批量删除

Session session = HibernateUtils.getSession();
Transaction trans = session.beginTransaction();
String hql = "delete Customer";
int count = session.createQuery(hql).executeUpdate();
trans.commit();
HibernateUtils.closeSession();

HQL与QBC查询和批量处理(demo.java)

HqlCriteriaBusinessDemo.java

package com.qst.chapter06.demo;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.List;
import java.util.Set;



import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import com.qst.chapter06.pojos.Customer;
import com.qst.chapter06.pojos.Order;
import com.qst.chapter06.pojos.Product;
import com.qst.chapter06.util.HibernateUtils;


public class HqlCriteriaBusinessDemo {

	public static void main(String[] args) {
		findCustomersByAddress_HQL("青岛市");
	}
	
	/*hql获取数据*/
	public static void findCustomersByAddress_HQL(String address){
		Session session = HibernateUtils.getSession();
		String hql="from Customer c where c.address = :address";
		Query query = session.createQuery(hql);
		query.setString("address", address);
		List<Customer> list = query.list();
		for(Customer c:list){
			System.out.println(c.getId()+"\t"+c.getUserName());
		}
	}
	
	/*qbc获取数据*/
	public static void findCustomerByAddress_QBC(String address){
		Session session = HibernateUtils.getSession();
		Criteria critera = session.createCriteria(Customer.class);
		critera.add(Restrictions.eq("address", address));
		List<Customer> list = critera.list();
		for(Customer c:list){
			System.out.println(c.getId()+"\t"+c.getUserName());
		}
	}
	
	/*order by排序*/
	public static void orderByUserNameByDesc_HQL(){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer c order by c.userName desc";
		Query query = session.createQuery(hql);
		List<Customer> list = query.list();
		for(Customer c:list){
			System.out.println(c.getId()+"\t"+c.getUserName());
		}
	}
	
	/*QBC排序*/
	public static void orderByUserNameByDesc_QBC(){
		Session session = HibernateUtils.getSession();
		Criteria criteria = session.createCriteria(Customer.class);
		criteria.addOrder(org.hibernate.criterion.Order.desc("userName"));
		List<Customer> list = criteria.list();
		for(Customer c:list){
			System.out.println(c.getId()+"\t"+c.getUserName());
		}
	}
	
	/*HQL分页查询*/
	public static List<Customer> listPageCustomer_HQL(int pageNo,int perPageNum){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer c order by c.userName desc";;
		Query query = session.createQuery(hql);
		query.setFirstResult((pageNo-1)*perPageNum);
		query.setMaxResults(perPageNum);
		List<Customer> list = query.list();
		return list;
	}
	
	/*QBC分页查询*/
	public static List<Customer> listPageCustomer_QBC(int pageNo,int perPageNum){
		Session session = HibernateUtils.getSession();
		Criteria criteria = session.createCriteria(Customer.class);
		criteria.setFirstResult((pageNo-1)*perPageNum);
		criteria.setMaxResults(perPageNum);
		List<Customer> list = criteria.list();
		return list;
	}
	
	/*HQL查询单条记录*/
	public static Customer findOneCustomer_HQL(){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer c order by c.userName desc";
		Customer customer = (Customer) session.createQuery(hql).setMaxResults(1).uniqueResult();
		return customer;
	}
	/*QBC查询单条记录*/
	public static Customer findOneCustomer_QBC(){
		Session session = HibernateUtils.getSession();
		Customer customer = (Customer)session.createCriteria(Customer.class).addOrder(org.hibernate.criterion.Order.desc("userName")).setMaxResults(1).uniqueResult();
		return customer;
	}
	
	/*不建议使用造成sql注入*/
	public static List<Customer> findCustomersByName(String name){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer as c where c.realName = '"+name+"'";
		Query query  = session.createQuery(hql);
		return query.list();
	}
	
	/*推荐使用,防止sql注入。在语句中插入值*/
	public static List<Customer> findCustomersByName1(String name){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer as c where c.userName = :name";
		Query query = session.createQuery(hql);
		query.setString("name", name);
		return query.list();
	}
	
	public static List<Customer> findCustomersByName2(String name){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer as c where c.userName = ?";
		Query query = session.createQuery(hql);
		query.setString(0, name);
		return query.list();
	}
	
	/*hql输出日期*/
	public static void printOrders_HQL(){
		Session session = HibernateUtils.getSession();
		String hql = "from Order o where o.date between ? and ?";
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try{
			List<Order> list = session.createQuery(hql).setParameter(0, dateFormat.parse("2015-03-01 00:00:00"))
					.setParameter(1, dateFormat.parse("2015-03-31 23:59:59")).list();
			for(Order o : list){
				System.out.println(o.getId()+"\t"+o.getDate());
			}
		}catch (ParseException e) {
			// TODO: handle exception
		}
	}
	
	/*QBC检索3月份的订单对象*/
	public static void printOrders_QBC(){
		Session session = HibernateUtils.getSession();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try{
			List<Order> list = session.createCriteria(Order.class).add(Restrictions.between("date", dateFormat.parse("2015-03-01 00:00:00"), dateFormat.parse("2015-03-31 23:59:59"))).list();
			for(Order o : list){
				System.out.println(o.getId() + "\t" + o.getDate());
			}
		}catch (ParseException e) {
			// TODO: handle exception
		}
	}
	
	/*内连接获取*/
	public static void findCustomerByJoin(){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer c inner join c.orders o where c.userName like :name";
		Query query = session.createQuery(hql);
		query.setString("name", "z%");
		List<Object[]> list =query.list();
		for(Object[] objs:list){
			Customer customer = (Customer)objs[0];
			System.out.println();
		}
	}
	
	/*使用预先抓取fetch获取内连接*/
	public static void findCustomerByFetchJoin(){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer c inner join fetch c.orders o where c.userName like :name";
		Query query = session.createQuery(hql);
		query.setString("name","z%");
		List<Customer> list =query.list();
		Set<Customer> set = new HashSet<Customer>(list);
		for(Customer customer : list){
			System.out.println(customer.getId()+""+customer.getUserName()+" ");
			for(Order order:customer.getOrders()){
				System.out.println(order.getOrderNo()+" ");
			}
			System.out.println();
		}
	}
	
	/*左连接获取*/
	public static void findCustomerByLeftJoin(){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer c left join c.orders o where c.userName like :name";
		Query query = session.createQuery(hql);
		query.setString("name", "z%");
		List<Object[]> list =query.list();
		for(Object[] objs:list){
			Customer customer = (Customer)objs[0];
			System.out.println();
		}
	}
	
	/*使用预先抓取fetch获取左连接*/
	public static void findCustomerByFetchLeftJoin(){
		Session session = HibernateUtils.getSession();
		String hql = "from Customer c left join fetch c.orders o where c.userName like :name";
		Query query = session.createQuery(hql);
		query.setString("name","z%");
		List<Customer> list =query.list();
		Set<Customer> set = new HashSet<Customer>(list);
		for(Customer customer : list){
			System.out.println(customer.getId()+""+customer.getUserName()+" ");
			for(Order order:customer.getOrders()){
				System.out.println(order.getOrderNo()+" ");
			}
			System.out.println();
		}
	}
	
	/*根据id统计用户总数*/
	public static void groupByCustomer(){
		Session session = HibernateUtils.getSession();
		String hql = "select c.userName,count(o) from Customer c left join c.orders o group by c.id";
		Query query  = session.createQuery(hql);
		List<Object[]> list =query.list();
		for(Object[] objs:list){
			String username = (String)objs[0];
			Long count=(Long)objs[1];
			System.out.println("用户名:"+username+"订单数:"+count);
		}
	}
	
	/*HQL动态查询产品信息*/
	public static List<Product> findProductsByHQL(String name,Double price){
		Session session = HibernateUtils.getSession();
		StringBuffer buffer = new StringBuffer();
		buffer.append("from Product p where 1=1");
		if(name!=null){
			buffer.append("and lower(p.name) like :name");
		}
		if(price!=null&&price!=0){
			buffer.append("and p.price = :price");
		}
		Query query = session.createQuery(buffer.toString());
		if(name!=null){
			query.setString("name", "%"+name.toLowerCase()+"%");
		}
		if(price!=null&&price!=0){
			query.setDouble("price", price);
		}
		return query.list();
	}
	
/*	Criteria动态查询产品信息*/
	public static List<Product> findProductsByCriterial(String name,Double price){
		Session session = HibernateUtils.getSession();
		Criteria criteria = session.createCriteria(Product.class);
		if(name!=null){
			criteria.add(Restrictions.ilike("name", name,MatchMode.ANYWHERE));
			
		}
		if(price!=null&&price!=0){
			criteria.add(Restrictions.eq("price",price));
		}
		return criteria.list();
	}
	
/*	单行子查询*/
	public static void findProductBySubQuerys(){
		Session session = HibernateUtils.getSession();
		String hql = "from Product p where p.price=(select pl.price from Product p1 where p1.name = :name) and p.name!=:name";
		Query query = session.createQuery(hql);
		query.setString("name", "打印机");
		List<Product> list = query.list();
		for(Product p : list){
			System.out.println(p.getId()+"\t"+p.getName()+"\t"+p.getPrice()+"\t"+p.getDescription());
		}
	}
	
/*	批量插入数据*/
	public static void bulkInsert(){
		Session session = HibernateUtils.getSession();
		Transaction trans = session.beginTransaction();
		for(int i = 0;i<1000000;i++){
			Customer customer = new Customer();
			session.save(customer);
			//没保存10个Customer对象,清空缓存
			if(i%10==0){
				session.flush();
				session.clear();
				trans.commit();
				trans = session.beginTransaction();
			}
		}
		HibernateUtils.closeSession();
	}
	
/*	批量修改**/
	public static void bulkUpdate(){
		Session session = HibernateUtils.getSession();
		Transaction trans = session.beginTransaction();
		//查询customer表中所有对象
		ScrollableResults customers = session.createQuery("from Customer").scroll();
		int count = 0;
		while(customers.next()){
			Customer customer = (Customer)customers.get(0);
			customer.setUserName("username"+count);
			if(count%10==0){
				session.flush();
				session.clear();
				trans.commit();
				trans = session.beginTransaction();
			}
			count++;
			
			
		}
	}
}

hibernate高级

检索策略

类级别检索策略:使用Sesssion的load()或者get()方法进行检索,对高档亲对象进行检索的策略,例如对Customer对象进行检索的时候,直接检索该对象本身。类级别建松包括立即加载和延迟加载。
关联级别检索策略:使用Session的load、get()方法或使用HQL进行检索是,对当前对象的关联对象进行建搜的策略,例如对于Customer进行关联的Order对象(及Customer对象的orders集合)进行检索的时候采用的策略,包括:立即加载、延迟加载和预先抓取

类级别检索策略

检索策略功能说明
立即检索如果把<class>标签的lazy属性设置为false时,立即加载;当调用session的load()方法是,会立即加载检索方法指定的对象,立即进行sql查询,并且进队load()方法影响
延迟检索延迟检索是默认检索策略,<class>标签lazy属性,默认为true,当加载对象时,并没有直接进行SQL查询,只有当调用对象当中的属性是,才会真正查询数据库

分为立即加载和延迟加载,在class标签上设置

立即加载
当通过session的load()方法加载Customer对象的时候,Hibernate会立即执行查询t_customer的select语句
select * from t_customer where id = 1

struts.xml

<class name="com.qst.chapter07.pojos.Customer" table="t_customer" lazy="false">

类级别延迟加载
设置之后,session.load()方法不会立即查询,而是等调用,具体实体类的getter或setter方法执行。

当Customer.hbm.xml的<class>标签中lazy属性为true的时候

<class name="com.qst.chapter07.pojos.Customer" table="t_customer" lazy="true">

执行session.load()方法,hibernate不会立即执行select语句并进行数据库的SQL查询,而是返回Customer类的代理类实例。
1、有hibernate运行时动态生成,扩展了Customer类,并继承了Customer类的属性和方法。
2、当hibernate创建customer代理类实例的时候,进初始化该对象的OID,其他属性为null
3、当应用程序第一次访问Customer代理类实例(如调用getter()和setter()方法等),Hibernate会初始化代理类的实例,初始化过程中执行的select语句,真正从数据库中加载Customer对象的所有数据,getId()方法例外。

1-N检索策略

<set>元素的lazy和fetch属性

lazy属性fetch属性检索策略
falseselect采用立即加载,当使用Hibernate的二级缓存是,可以考虑使用立即加载方式
falsefetch采用预先抓取方式检索,这是Hibernate4.x默认的检索方式
truejoin采用预先抓取方式检索,由此可见预先抓取的优先级别比延迟加载的级别高
trueselect采用延迟加载策略

批量检索
<set>元素有一个batch-size属性,用于为延迟加载或立即加载策略设置的批量检索数量,批量检索可以减少select语句的数目,提高延迟或立即加载的性能。

1、批量立即加载
会将与当前检索数据相关联的数据全部查询处理来,Customer与Order对象是1-N的,如果采用立即加载得到Customer对象,Customer对象或通过雷冠希导航取得所有的Order数据。

Session session = HibernateUtils.getSession();
String hql = "from Csutomer";
Query query = session.createQuery(hql);
List list = query.list();
...//提交事务,关闭session

没有设置之前,需要如果有100个订单需要执行100条order的查询语句

<set name="orders" lazy="false" batch-size="2">

设置之后,执行50条查询语句。
select o.* from t_order o_where o_.CUSTOMER_ID in(?,?);


批量延迟加载

<set name="orders" lazy="true" batch-size="2">
Session session = HibernateUtils.getSession();
String hql = "from Customer c";
Query query = session.createQuery(hql);
List list = query.list();
Customer c1 = (Customer)list.get(0);
c1.getOrders().iterator();

当执行c1.getOrders.iterator()的是偶,由于batch-size的属性值为2,会批量初始化2个orders集合代理实例。


预先抓取
当fetch设置为join的时候,语句改变
select c.,o. from t_customer c left outer join t_order o on c.id = o.CUSTOMER_ID where c.id = ?

提高效率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值