Hibernate框架

简介

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。

 

什么是orm

对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。

对象-关系映射,是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

ORM模型的简单性简化了数据库查询过程。使用ORM查询工具,用户可以访问期望数据,而不必理解数据库的底层结构

简单使用流程

  • 创建数据库与表
  • 创建实体类
  • 导入hibernate依赖jar包
  • 创建映射文件
 <hibernate-mapping package="com.itheima.domain">
    <class name="Customer" table="t_customer" catalog="hibernateTest">
    <id name="id" column="id">
    <!--    主键生成策略 -->
    <generator class="native"></generator>
    </id>
    
    <!-- 使用property字段描述属性与字段之间的关系 -->
    <property name="name" column="name" length="20"></property>
    <property name="address" column="address" length="50"></property>
    </class>   
 </hibernate-mapping>
  • 创建hibernate核心配置文件
<hibernate-configuration>
	<session-factory>
	<!-- 配置数据库连接的四个项 -->
	<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
	<property name="hibernate.connection.url">jdbc:mysql:///hibernatetest</property>
	<property name="hibernate.connection.username">root</property>
	<property name="hibernate.connection.password">1234</property>
	<!-- 设置连接池提供者 -->
	<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
	<!-- 设置连接池 -->
	<property name="hibernate.c3p0.max_size">20</property>
	<property name="hibernate.c3p0.min_size">5</property>
	<property name="hibernate.c3p0.timeout">100</property>
	<property name="hibernate.c3p0.idle_test_period">3000</property>
	<!-- 可以将像数据库发送的数据显示出来 -->
	<property name="hibernate.show_sql">true</property>
	<!-- 格式化sql -->
	<property name="hibernate.format_sql">true</property>
	<!-- hibernate方言 -->
	<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
	<!-- 如果数据库中有表,不创建,没有表创建,如果映射不匹配,会自动更新表结构 -->
	<property name="hibernate.hbm2ddl.auto">update</property>
   
    
    <!-- 设置事物自动提交 -->
    <property name="hibernate.connection.autocommit">true</property>
     <!-- 配置hibernate映射所在 -->
    <mapping resource="com/itheima/domain/Customer.hbm.xml"/>
	</session-factory>
	</hibernate-configuration>
  • 编写测试代码
//插入数据
	@Test
	public void addCustomer(){
	Customer c=new Customer();
	c.setName("薛仁贵");
	c.setAddress("高丽都护府");
	c.setSex("男");
	Configuration configure = new Configuration().configure();// 加载hibernate.cfg.xml
	//configure.addResource("com/itheima/domain/Customer.hbm.xml");手动加载映射
	configure.addClass(Customer.class);
	SessionFactory sessionFactory = configure.buildSessionFactory();
	//configure.addClass(Customer.class);
	Session session = sessionFactory.openSession();
	Transaction transaction = session.beginTransaction();
	session.save(c);
	transaction.commit();
	session.close();
	sessionFactory.close();

 

 

Hibernate 工作原理总结

1、通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件

2、由hibernate.cfg.xml中的<mappingresource="xx/xx/xxx.hbm.xml"/>读取解析映射信息。

3、通过config.buildSessionFactory();//得到sessionFactory。

4、sessionFactory.openSession();//得到session。

5、session.beginTransaction();//开启事务。

6、persistent operate;

7、session.getTransaction().commit();//提交事务

8、关闭session;

9、关闭sessionFactory;

Query

使用HQL

、Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。

无名称参数  from Customer where name=?

对其进行赋值   query.setParameter(0,”张三”)

有名称参数  from Customer where name=:myname;

对其进行赋值  query.setParameter(“myname”,”李四”);

如果查询结果可以保证就是唯一 的,我们可以使用

query. uniqueResult()来得到一个单独对象.

SQLQuery

要想执行本地sql    SQLQuery sqlQuery=session.createSqlQuery(String sql);

使用addEntity方法来将结果封装到指定的对象中,如果不封装,得到的是List<Object>

如果sql中有参数,我们使用setParameter方法完成参数传递。如果结果就是一个可以使用uniqueResult()来得到一个单独对象。

Criteria

Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的是Criteria接口也是轻量级的,它不能在Session之外使用。

首先我想使用Criteria,必须得到Criteria    Criteria criteria=Session.createCriteria()

 Session session =HibernateUtils.getSession();
   session.beginTransaction();
   Criteria criteria = session.createCriteria(Customer.class);
		   
		   //查询所有
		   List<Customer> list = criteria.list();
		   System.out.println(list);
		   session.getTransaction().commit();
		   session.close();
		   
		   //分页查询
		   criteria.setFirstResult(10);
		   criteria.setMaxResults(10);
		   List<Customer> list = criteria.list();
		   System.out.println(list);
		   
		   //多条件查询
		   criteria.add(Restrictions.eq("name", "李孝恭"));
		   session.getTransaction().commit();
		   session.close();

 

 

持久化类类三种状态介绍

瞬时态:也叫做临时态或自由态,它一般指我们new出来的对象,它不存在OID,与hibernate session无关联,在数据库中也无记录。它使用完成后,会被jvm直接回收掉,它只是用于信息携带。

简单说:无OID 与数据库中的信息无关联,不在session管理范围内。

持久态:在hibernate session管理范围内,它具有持久化标识OID它的特点,在事务未提交前一直是持久态,当它发生改变时,hibernate是可以检测到的。

简单说:有OID 由session管理,在数据库中有可能有,也有可有没有。

托管态:也叫做游离态或离线态,它是指持久态对象失去了与session的关联,托管态对象它存在OID,在数据库中有可能存在,也有可能不存在。

对于托管态对象,它发生改变时hibernet不能检测到。

三种状态切换

瞬时态(new 出来的)

瞬时------à持久  save   saveOrUpdate

瞬时-----à脱管(游离)  手动设置oid

.持久态   它是由session管理

       持久-------à瞬时   delete() 被删除后持久化对象不在建议使用

       持久-----à脱管  注意:session它的缓存就是所说的一级缓存

                                   evict(清除一级缓存 中指定的一个对象)

                                   clear(清空一级缓存)

                                   close(关闭,清空一级缓存)

.脱管态   (它是无法直接获取)

       脱管-----à瞬时    直接将oid删除

       脱管----à持久  update  saveOrUpdate lock(过时)

Hibernate一级缓存

Hibernate的一级缓存就是指session缓存。

actionQueue它是一个行列队列,它主要记录crud操作的相关信息

persistenceContext它是持久化上下文,它其实是真正缓存。

在session中定义了一系列的集合来存储数据,它们构成session缓存。只要session没有关闭,它就会一直存在。

当我们通过hibernate中的session提供的一些API例如 save  get  update等进行操作时,就会将持久化对象保存到session中,当下一次在去查询缓存中具有的对象(OID值来判断),就不会去从数据库查询,而是直接从缓存中获取。

Hibernate的一级缓存存在的目的就是为了减少对数据库访问。

持久化对象具有自动更新数据库能力

一级缓存常用API

一级缓存特点:

  1. 当我们通过session的save,update saveOrupdate进行操作时,如果一级缓存中没有对象,会将这些对象从数据库中查询到,存储到一级缓存。
  2. 当我们通过session的load,get,Query的list等方法进行操作时,会先判断一级缓存中是否存在,如果没有才会从数据库获取,并且将查询的数据存储到一级缓存中。
  3. 当调用session的close方法时,session缓存清空。

clear 清空一级缓存.

evict 清空一级缓存中指定的一个对象。 

refresh重新查询数据库,用数据库中信息来更新一级缓存与快照

public void test5() {
		// 1.得到session
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		// 操作
		List<Customer> list = session.createQuery("from Customer").list(); // 会存储数据到一级缓存
		session.clear(); // 清空一级缓存
		Customer c = session.get(Customer.class, 1); // 会先从session一级缓存
														// 中获取,如果不存在,才会从数据库获取
		session.evict(c); // 从一级缓存 中删除一个指定的对象
		Customer cc = session.get(Customer.class, 1);

		cc.setName("kkkk");

		session.refresh(cc); // 重新查询数据库,用数据库中信息来更新一级缓存与快照

		// 2.事务提供,关闭
		session.getTransaction().commit();
		session.close();
	}

 

Hibernate关联映射-数据对象三种关系介绍

 Hibernate框架基于ORM设计思想,它将关系型数据库中的表与我们java中的类进行映射,一个对象就对应着表中的一条记录,而表中的字段对应着类中的属性。

数据库中表与表之间存在着三种关系,也就是系统设计中的三种实体关系。

<!-- 一个客户关联多个订单 -->
<set name="orders" inverse="true" cascade="save-update">
    <key column="c_customer_id" />
			<one-to-many class="cn.itheima.oneToMany.Order" />
	</set>

<!-- 使用set来描述在一的一方中关联的多 Set<Order>,它的name属性就是set集合的名称 key:它主要描述关联的多的一方产生的外键名称,注意要与多的一方定义的外键名称相同one-to-many 描述集合中的类型 -->

Inverse它的值如果为true代表,由对方来维护外键。

Inverse它的值如果为false代表,由本方来维护外键。

关于inverse的取值:  外键在哪一个表中,我们就让哪一方来维护外键。

使用cascade可以完成级联操作

它可常用取值:

none这是一个默认值

save-update,当我们配置它时,底层使用save update或save-update完成操作,级联保存临时对象,如果是游离对象,会执行update.

delete 级联删除

delete-ophan 删除与当前对象解除关系的对象。

all 它包含了save-update  delete操作

all-delete-orphan 它包信了delete-orphan与all操作

Hibernate注解开发

@Entity 声明一个实体

@Table来描述类与表对应

@Id来声明一个主键

@GenerateValue 用它来声明一个主键生成策略  默认情况下相当于native  可以选择的主键生成策略 AUTO IDENTITY SEQUENCE

@Column来定义列

@Temporal来声明日期类型

@Transient声明不生成在表中

@OneToMany一对多

@ManyToOne多对一

@Joinclum添加列

@Cascade级联操作

mappedBy主键由哪一方维护

我们在Customer中配置了mappedBy=”c”它代表的是外键的维护由Order方来维护,而Customer不维护,这时你在保存客户时,级联保存订单,是可以的,但是不能维护外键

@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	private String name;
	@ManyToMany(targetEntity = Teacher.class)
	// 使用JoinTabl来描述中间表,并描述中间表中外键与Student,Teacher的映射关系
	// joinColumns它是用来描述Student与中间表中的映射关系
	// inverseJoinColums它是用来描述Teacher与中间表中的映射关系
	@JoinTable(name = "s_t", joinColumns = {
			@JoinColumn(name = "c_student_id", referencedColumnName = "id") }, inverseJoinColumns = {
					@JoinColumn(name = "c_teacher_id", referencedColumnName = "id") })
	@Cascade(CascadeType.ALL)
	private Set<Teacher> teachers = new HashSet<Teacher>();

HQL

HQL是我们在hibernate中是常用的一种检索方式。

HQL(Hibernate Query Language)提供更加丰富灵活、更为强大的查询能力

因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语 句的查询方式,同时也提供了更加面向对象的封装。完整的HQL语句形式如下: Select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc 其中的update/delete为Hibernate3中所新添加的功能,可见HQL查询非常类似于标准SQL查询。

基本步骤:

  1. 得到Session
  2. 编写HQL语句
  3. 通过session.createQuery(hql)创建一个Query对象
  4. 为Query对象设置条件参数
  5. 执行list查询所有,它反胃的是List集合  uniqueResut()返回一个查询结果。
public class HQLTest {

	// 命名查询
	@Test
	public void test9() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		// 1.我要查询张龙这个客户的订单
		Customer c = session.get(Customer.class, 1);

		Query query = session.getNamedQuery("findOrderByCustomer"); // from Order  where c=:c
		// 2.现在hql它的参数是一个实体
		List<Order> list = query.setEntity("c", c).list();

		System.out.println(list);

		session.getTransaction().commit();
		session.close();
	}

	// 命名查询
	@Test
	public void test8() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		Query query = session.getNamedQuery("myHql");
		List<Customer> list = query.list();
		System.out.println(list);
		session.getTransaction().commit();
		session.close();
	}

	// 投影查询
	@Test
	public void test7() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		// 1.查询出所有的Customer的name
		// String hql = "select name from Customer";

		// List list = session.createQuery(hql).list();

		// System.out.println(list); // [张龙, 张三丰]

		// 如果只查询一个列,得到的结果List<Object>

		// 2.查询所有的Customer的id,name
		// String hql = "select id,name from Customer";

		// List<Object[]> list = session.createQuery(hql).list();

		// for(Object[] objs:list){
		// for(Object obj:objs){
		// System.out.print(obj+" ");
		// }
		// System.out.println();
		// }
		// 如果是查询多列,得到的结果是List<Object[]>

		// 3.使用投影将查询的结果封装到Customer对象
		String hql = "select new Customer(id,name) from Customer"; // 必须在PO类中提供对应的构造方法
		List<Customer> cs = session.createQuery(hql).list();
		System.out.println(cs);

		session.getTransaction().commit();
		session.close();
	}

	// 分组统计操作
	@Test
	public void test6() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		// 统计操作----统计一共有多少订单 count
		// String hql="select count(*) from Order";

		// Object count = session.createQuery(hql).uniqueResult();
		// System.out.println(count);

		// 分组统计----每一个人的订单总价
		String hql = "select sum(money) from Order group by c";
		List list = session.createQuery(hql).list();
		System.out.println(list);

		session.getTransaction().commit();
		session.close();
	}

	// 分页检索
	@Test
	public void test5() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		Query query = session.createQuery("from Order");
		// 每页显示6条件 ,我们要得到第二页数据
		query.setFirstResult((2 - 1) * 6); // 设定开始位置
		query.setMaxResults(6); // 设置条数

		List<Order> list = query.list();
		System.out.println(list);

		session.getTransaction().commit();
		session.close();

	}

	// 条件查询
	@Test
	public void test4() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		// 1.根据位置来绑定参数
		// 1.1创建hql
		// String hql = "from Order where money>? ";

		// 1.2.执行hql
		// List<Order> list = session.createQuery(hql).setParameter(0,
		// 2000d).list();
		// 可以使用例如setString() setDouble这样的方法去添加参数,参数的序号是从0开始.

		// 2.根据名称来绑定
		// 1.1创建hql
		String hql = "from Order where money>:mymoney ";

		// 1.2.执行hql
		List<Order> list = session.createQuery(hql).setParameter("mymoney", 2000d).list();
		// 可以使用例如setString() setDouble这样的方法去添加参数

		System.out.println(list);
		session.getTransaction().commit();
		session.close();

	}

	// 排序检索--//查询订单,根据订单的价格进行排序
	@Test
	public void test3() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		// 1.定义hql
		String hql = "from Order order by money desc"; // desc 降序 默认是asc 升序
		// 2.执行hql查询订单,根据价格进行排序
		List<Order> list = session.createQuery(hql).list();

		System.out.println(list);

		session.getTransaction().commit();
		session.close();
	}

	// 基本检索
	@Test
	public void test2() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		// 1.编写HQL
		String hql = "from Customer"; // from是关键字,后面是类名,关键字是不区分大小写,但是类名是区分
		// 2.通过session.createQuery(hql)
		// Query query = session.createQuery(hql);
		// 3.通过list方法得到数据
		// List<Customer> list = query.list();

		List<Customer> list = session.createQuery(hql).list();

		System.out.println(list.get(0));

		session.getTransaction().commit();
		session.close();
	}

	// 准备数据(2个Customer,每一个Customer有10个Order)
	@Test
	public void test1() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		// 操作
		Customer c = new Customer();
		c.setName("张三丰");

		for (int i = 0; i < 10; i++) {
			Order order = new Order();
			order.setMoney(2000d + i * 10);
			order.setReceiverInfo("上海");
			order.setC(c);
			session.save(order);
		}

		session.getTransaction().commit();
		session.close();
	}

QBC

QBC(query by criteria),它是一种更加面向对象的检索方式。

QBC步骤:

       1.通过Session得到一个Criteria对象   session.createCriteria()

       2.设定条件  Criterion实例 它的获取可以通过Restrictions类提供静态。Criteria的add方法用于添加查询条件

       3.调用list进行查询  criterfia.list.

public class QBCTest {

	// 离线的检索
	@Test
	public void test6() {
		// 1.得到一个DetachedCriteria
		DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
		dc.add(Restrictions.like("name", "张_"));

		// 2.生成Criteria执行操作
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		Criteria criteria = dc.getExecutableCriteria(session);
		List<Customer> list = criteria.list();

		System.out.println(list);
		session.getTransaction().commit();
		session.close();

	}

	// 统计检索
	@Test
	public void test5() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		// 1.统计订单总数
		Criteria criteria = session.createCriteria(Order.class);
		// Object obj =
		// criteria.setProjection(Projections.rowCount()).uniqueResult();
		// //统计总行数 count(id)
		// System.out.println(obj);

		// 2.订单的总价格----分组统计根据客户
		// criteria.setProjection(Projections.sum("money")); //统计总金额

		criteria.setProjection(
				Projections.projectionList().add(Projections.sum("money")).add(Projections.groupProperty("c")));

		List<Object[]> list = criteria.list(); // 在这个集合中保存的是Object[money的统计信息,客户信息]

		for (Object[] objs : list) {
			for (Object obj : objs) {
				System.out.println(obj);
			}
		}

		session.getTransaction().commit();
		session.close();
	}

	// 分页检索
	@Test
	public void test4() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		Criteria criteria = session.createCriteria(Order.class);
		criteria.setFirstResult((2 - 1) * 6);
		criteria.setMaxResults(6);
		List<Order> list = criteria.list();

		System.out.println(list);

		session.getTransaction().commit();
		session.close();
	}

	// 条件检索
	@Test
	public void test3() {
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		// 1.查询名称叫张某客户 张_
		Criteria criteria = session.createCriteria(Customer.class);
		Criterion like = Restrictions.like("name", "张_"); // 其它的条件 lt < gt > le
															// <= ge>= eq==
		criteria.add(like);// 添加条件
		Customer c = (Customer) criteria.uniqueResult();
		System.out.println(c);

		// 2.查询订单价格在1050以上的,并且它的客户是张某
		Criteria cri = session.createCriteria(Order.class);
		SimpleExpression lt = Restrictions.gt("money", 1050d); // >1050
		SimpleExpression eq = Restrictions.eq("c", c); // 与c客户相同
		LogicalExpression and = Restrictions.and(lt, eq);
		cri.add(and);
		// List<Order> orders =
		// cri.add(Restrictions.and(Restrictions.gt("money", 1050d),
		// Restrictions.eq("c", c))).list();
		List<Order> orders = cri.list();
		System.out.println(orders);

		session.getTransaction().commit();
		session.close();

	}

	// 排序检索
	@Test
	public void test2() {
		// 查询订单信息 根据订单的价格进行排序
		Session session = HibernateUtils.openSession();
		session.beginTransaction();

		Criteria criteria = session.createCriteria(Order.class);
		// 指定排序
		// criteria.addOrder(org.hibernate.criterion.Order.desc("money")); // 降序
		criteria.addOrder(org.hibernate.criterion.Order.asc("money")); // 升序

		List<Order> list = criteria.list();

		System.out.println(list);

		session.getTransaction().commit();
		session.close();
	}

	// 基本检索
	@Test
	public void test1() {
		// 查询所有Customer
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		// 1.得到一个Criteria对象
		Criteria criteria = session.createCriteria(Customer.class);

		// 2.调用list方法
		List<Customer> list = criteria.list();

		System.out.println(list);

		session.getTransaction().commit();
		session.close();
	}
}

Hibernate事务管理

Hibernate中设置事务隔离级别

它可取的值有 1 2 4 8

1代表的事务隔离级别为READ UNCOMMITTED

2代表的事务隔离级别为READ COMMITTED

4.代表的事务隔离级别为 REPEATABLE READ

8代表的事务隔离级别为 SERIALIZABLE

<!-- 设置事务隔离级别 -->
<property name="hibernate.connection.isolation ">4</property>

Hiberante优化方案

HQL优化

1.使用参数绑定

       1.使用绑定参数的原因是让数据库一次解析SQL,对后续的重复请求可以使用用生成好的执行计划,这样做节省CPU时间和内存。

       2.避免SQL注入

2.尽量少全长NOT

       如果where子句中包含not关键字,那么执行时该字段的索引失效。

3.尽量使用where来替换having

Having在检索出所有记录后才对结果集进行过滤,这个处理需要一定的开销,而where子句限制记录的数目,能减少这方面的开销

4.减少对表的查询

       在含有子查询的HQL中,尽量减少对表的查询,降低开销

5.使用表的别名

当在HQL语句中连接多个表时,使用别名,提高程序阅读性,并把别名前缀与每个列上,这样一来,可以减少解析时间并减少列歧义引起的语法错误。

6.实体的更新与删除

  在hibernate3以后支持hql的update与delete操作

一级缓存管理

一级缓存也叫做session缓存,在一个hibernate session有效,这级缓存的可干预性不强,大多于hibernate自动管理,但它提供清除缓存的方法,这在大批量增加(更新)操作是有效果的,例如,同时增加十万条记录,按常规进行,很可能会出现异常,这时可能需要手动清除一级缓存,session.evict以及session.clear.

检索策略

延迟加载

延迟加载 是hibernate为提高程序执行的效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。

load方法采用的策略延迟加载.

get方法采用的策略立即加载。

检索策略分为两种:

  1. 类级别检索
  2. 关联级别检索

set上的fetch与lazy它主要是用于设置关联的集合信息的抓取策略。

Fetch可取值有:

  1. SELECT 多条简单的sql   (默认值)
  2. JOIN 采用迫切左外连接
  3. SUBSELECT 将生成子查询的SQL

lazy可取值有:

  1. TURE 延迟检索   (默认值)
  2. FALSE 立即检索
  3. EXTRA 加强延迟检索(及其懒惰)

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值