Hibernate:加载策略
1.立即加载–get加载数据
使用get获取数据,会立即查找(缓存—数据库)
2、 延迟加载懒加载 lazy—load,不会立即查找,当需要的时候才会查找
容易造成:LazyInitialaztionException异常:因为session被关闭。
3、 Load支持延迟加载,get不支持延迟加载。如果没有设置延迟加载,那么load也会立即加载对象。
4、 class的lazy
class默认情况下是支持懒加载如果设置lazy=false,get和load都会立即加载对象。
5、 set\list默认下是lazy=true的。支持懒加载,但是当使用size()的时候依然要去查询整个set集合的内容。
6.什么是懒加载策略?
- 在调用session会话的数据库操作方式时,并不会直接生成sql语句去操作数据库, 而是先创建一个代理对象,将oid(object id)存放在session的代理对象中, 当具体的要用到持久化对象的时候,才会生成sql语句进行查询
注:hibernate3以上,所有的关系查询都是使用懒加载的策略
7.测试代码:
7.1:实体类:User.java
public class User implements Serializable {
private Integer id;
private String userName;
private String userPwd;
public User() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
@Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + ", realName=" + realName
+ ", sex=" + sex + ", birthday=" + birthday + ", createDatetime=" + createDatetime + ", remark="
+ remark + "]";
}
}
7.2
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="t_hibernate_user" name="com.zking.one.entity.User">
<id name="id" type="java.lang.Integer" column="id">
<generator class="increment"></generator>
</id>
<property name="userName" type="java.lang.String" column="user_name"></property>
<property name="userPwd" type="java.lang.String" column="user_pwd"></property>
</class>
</hibernate-mapping>
7.3:hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<!-- 1. 数据库相关 -->
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 连接MySQL数据库 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 2.配置本地事务(No CurrentSessionContext configured!) -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 3. 调试相关 -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- 4.hibernate需要管理的数据库表对应的实体类映射文件 -->
<mapping resource="com/zking/one/entity/User.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
7.4:测试方法
7.4.1:立即加载:get方法
public class UserDao {
//立即加载 马上生成sql语句,不管你用不用
public User getUser(User user) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
System.out.println(123);
User u=session.get(User.class, user.getId());
System.out.println(456);
System.out.println(u.getUserName());
transaction.commit();
session.close();
return u;
}
}
junit测试:
public class UserDaoTest {
private UserDao userDao=new UserDao();
private User user=new User();
@Test
public void testGetUser() {
user.setId(1);
User u = this.userDao.getUser(user);
System.out.println(u.getId());
System.out.println(u.getUserName());
}
}
结果:
通过log日志就可以看出session.get(Customer.class, 2l);就输出sql语句
7.4.2:懒加载:load方法
//懒加载 在你要用的时候才生成sql语句
public class UserDao {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
//第一次,没有使用,session关闭了,不会查询,会报错
/*User u=session.load(User.class, user.getId());*/
//第二次,使用了,进行查询
System.out.println(123);
User u=session.load(User.class, user.getId());
System.out.println(456);
System.out.println(u.getUserName());
transaction.commit();
session.close();
return u;
}
}
junit测试:
public class UserDaoTest {
private UserDao userDao=new UserDao();
private User user=new User();
@Test
public void testLoadUser() {
user.setId(1);
User u = this.userDao.loadUser(user);
System.out.println(u.getId());
System.out.println(u.getUserName());
}
}
第二次使用结果: 使用了, 生成sql语句,进行查询
第一次结果:仅仅获得没有使用.不会查询.在使用时才进行查询. 还会报错
错误: