0%

hibernate session接口

hibernate session接口

Session接口是hibernate向应用程序提供的操纵数据库的最主要的接口,提供了保存、更新、删除和加载Java对象的方法。

session具有一个缓存,位于缓存中的对象称为持久化对象,和数据库中的相关记录对应。session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程称为刷新缓存(flush)。

hibernate把对象分为4种状态,持久化状态,临时状态,游离状态,删除状态。session的特定方法可以使对象进行状态转换

session缓存

session实例没有结束生命周期,且没有清理缓存,则存放在session缓存中的对象也不会结束生命周期,session缓存可以减少访问数据库的频率。

操作session缓存

flush方法

缓存中对象同步到数据库(会插入或更新数据库),使数据库中的状态与缓存中一致

注意:

session在以下情况下会刷新缓存

  • hibernate在事务提交之前会执行flush()方法,然后再向数据库提交事务

  • 显式调用session.flush()方法

  • 在执行HQL或者QBC查询,会先进行flush()操作,以得到数据表最新的记录

refresh方法

将数据库同步到缓存中(会查询数据库),使缓存中的状态与数据库一致

1
session.refresh(); 
clear方法

清理缓存,可以将session中的缓存清除

1
session.clear();

四种状态的转换

临时状态(Transient)

  • 在使用代理主键的情况下,OID通常为null
  • 不处于session缓存中
  • 在数据库中也没有对应的记录,此时刚new了一个实体对象,还存在于保存临时数据的内存区域中

持久化状态(Persist)

  • OID不为null
  • 位于session缓存中
  • 若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应
  • session在flush缓存时,会根据持久化对象的属性变化,来同步数据库
  • 在同一个session实例的缓存中,数据库表中每条记录只对应唯一的持久化对象
  • 持久化对象的id不可以被修改,因为hibernate是根据id去进行比较的

删除状态(Removed)

  • 在数据库中没有和其OID对应的记录
  • 不再处于session缓存中

游离状态(Detached)

  • OID不为null

  • 不再处于session缓存中

  • 一般情况下,游离对象是由持久化对象转变过来的(session进行close、clear、evict等情况),数据库中可能还存在它对应的记录,但是因为会话已经消失,对象不在持久化管理之内,所以处于游离状态

    hibernate四种状态转换

save方法和persist方法的区别

在调用persist()方法时如果存在id,则会抛出异常,而save方法则可以正常执行

1
org.hibernate.PersistentObjectException: detached entity passed to persist

get方法和load方法的区别

  • 执行get方法会立即加载对象,执行load方法若不使用该对象,则不会立即查询,而是返回一个代理对象(延时加载)

  • 若数据表中没有对应的记录,get方法返回null,load方法抛出异常

    1
    org.hibernate.ObjectNotFoundException: No row with the given identifier exists
  • load方法可能会抛出懒加载异常

    1
    org.hibernate.LazyInitializationException: could not initialize proxy - no Session

注意:在session缓存中不能够有两个相同OID的对象,否则会报异常

1
2
3
4
5
6
7
8
9
10
public static void testOid(Session session){
User user = (User) session.get(User.class,1);
System.out.println(user);
User user1 = new User();
user1.setId(1);
user1.setName("王五");
session.saveOrUpdate(user1);
}

org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session

evict方法

从session缓存中将指定的持久化对象移除

hibernate获取原生JDBC连接进行操作

可以使用doWork或者doReturnWork来使用原生JDBC操作数据

1
2
3
4
5
6
7
8
9
10
11
12
13
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {

}
});

session.doReturningWork(new ReturningWork<Object>() {
@Override
public Object execute(Connection connection) throws SQLException {
return null;
}
});

session方法说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
public interface Session extends SharedSessionContract {
/**
* Obtain a {@link Session} builder with the ability to grab certain information from this session.
*
* @return The session builder
*/
public SharedSessionBuilder sessionWithOptions();

/**
* Force this session to flush. Must be called at the end of a
* unit of work, before committing the transaction and closing the
* session (depending on {@link #setFlushMode(FlushMode)},
* {@link Transaction#commit()} calls this method).
* <p/>
* <i>Flushing</i> is the process of synchronizing the underlying persistent
* store with persistable state held in memory.
*
* @throws HibernateException Indicates problems flushing the session or
* talking to the database.
*/
public void flush() throws HibernateException;

// 获取创建该会话的sessionFactory
public SessionFactory getSessionFactory();

// 关闭数据库连接
public Connection close() throws HibernateException;

// 取消当前查询的执行
public void cancelQuery() throws HibernateException;

// 当前session是否开启
public boolean isOpen();

// 当前session是否连接
public boolean isConnected();

// 该session中是否包含必须与数据库痛的变化
public boolean isDirty() throws HibernateException;

// 返回与当前实体关联的会话标识符
public Serializable getIdentifier(Object object);

/**
* Check if this instance is associated with this <tt>Session</tt>.
*
* @param object an instance of a persistent class
* @return true if the given instance is associated with this <tt>Session</tt>
*/
public boolean contains(Object object);

/**
* Remove this instance from the session cache. Changes to the instance will
* not be synchronized with the database. This operation cascades to associated
* instances if the association is mapped with <tt>cascade="evict"</tt>.
*
* @param object The entity to evict
*
* @throws NullPointerException if the passed object is {@code null}
* @throws IllegalArgumentException if the passed object is not defined as an entity
*/
public void evict(Object object);

/**
* Return the persistent instance of the given entity class with the given identifier,
* assuming that the instance exists. This method might return a proxied instance that
* is initialized on-demand, when a non-identifier method is accessed.
* <br><br>
* You should not use this method to determine if an instance exists (use <tt>get()</tt>
* instead). Use this only to retrieve an instance that you assume exists, where non-existence
* would be an actual error.
*
* @param theClass a persistent class
* @param id a valid identifier of an existing persistent instance of the class
*
* @return the persistent instance or proxy
*/
public Object load(Class theClass, Serializable id);

/**
* Persist the state of the given detached instance, reusing the current
* identifier value. This operation cascades to associated instances if
* the association is mapped with {@code cascade="replicate"}
*
* @param object a detached instance of a persistent class
* @param replicationMode The replication mode to use
*/
public void replicate(Object object, ReplicationMode replicationMode);

/**
* Persist the state of the given detached instance, reusing the current
* identifier value. This operation cascades to associated instances if
* the association is mapped with {@code cascade="replicate"}
*
* @param entityName The entity name
* @param object a detached instance of a persistent class
* @param replicationMode The replication mode to use
*/
public void replicate(String entityName, Object object, ReplicationMode replicationMode) ;

// 保存对象,生成标识,变为持久化状态
public Serializable save(Object object);

// 保存对象,生成标识,变为持久化状态
public Serializable save(String entityName, Object object);

// 保存或更新对象
public void saveOrUpdate(Object object);

// 保存或更新对象
public void saveOrUpdate(String entityName, Object object);

// 更新该标识符所对应的对象
public void update(Object object);

// 更新该标识符所对应的对象
public void update(String entityName, Object object);

/**
* Copy the state of the given object onto the persistent object with the same
* identifier. If there is no persistent instance currently associated with
* the session, it will be loaded. Return the persistent instance. If the
* given instance is unsaved, save a copy of and return it as a newly persistent
* instance. The given instance does not become associated with the session.
* This operation cascades to associated instances if the association is mapped
* with {@code cascade="merge"}
* <p/>
* The semantics of this method are defined by JSR-220.
*
* @param object a detached instance with state to be copied
*
* @return an updated persistent instance
*/
public Object merge(Object object);

/**
* Make a transient instance persistent. This operation cascades to associated
* instances if the association is mapped with {@code cascade="persist"}
* <p/>
* The semantics of this method are defined by JSR-220.
*
* @param object a transient instance to be made persistent
*/
public void persist(Object object);


// 删除该持久化对象
public void delete(Object object);

// 删除该持久化对象
public void delete(String entityName, Object object);

// 从数据库中重新读取该对象
public void refresh(Object object);

/**
* Re-read the state of the given instance from the underlying database. It is
* inadvisable to use this to implement long-running sessions that span many
* business tasks. This method is, however, useful in certain special circumstances.
* For example
* <ul>
* <li>where a database trigger alters the object state upon insert or update
* <li>after executing direct SQL (eg. a mass update) in the same session
* <li>after inserting a <tt>Blob</tt> or <tt>Clob</tt>
* </ul>
*
* @param entityName a persistent class
* @param object a persistent or detached instance
*/
public void refresh(String entityName, Object object);

// 为给定集合和查询条件创建查询实例
public Query createFilter(Object collection, String queryString);

// 清除该会话
public void clear();

// 返回给定命名和标识符的持久化对象实例
public Object get(Class clazz, Serializable id);

// 返回给定命名和标识符的持久化对象实例
public Object get(String entityName, Serializable id);

/**
* Return the entity name for a persistent entity.
*
* @param object a persistent entity
*
* @return the entity name
*/
public String getEntityName(Object object);

/**
* Create an {@link IdentifierLoadAccess} instance to retrieve the specified entity by
* primary key.
*
* @param entityClass The entity type to be retrieved
*
* @return load delegate for loading the specified entity type by primary key
*
* @throws HibernateException If the specified Class cannot be resolved as a mapped entity
*/
public IdentifierLoadAccess byId(Class entityClass);

/**
* Get the statistics for this session.
*
* @return The session statistics being collected for this session
*/
public SessionStatistics getStatistics();

/**
* Controller for allowing users to perform JDBC related work using the Connection managed by this Session.
*
* @param work The work to be performed.
* @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
*/
public void doWork(Work work) throws HibernateException;

/**
* Controller for allowing users to perform JDBC related work using the Connection managed by this Session. After
* execution returns the result of the {@link ReturningWork#execute} call.
*
* @param work The work to be performed.
* @param <T> The type of the result returned from the work
*
* @return the result from calling {@link ReturningWork#execute}.
*
* @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
*/
public <T> T doReturningWork(ReturningWork<T> work) throws HibernateException;

/**
* Add one or more listeners to the Session
*
* @param listeners The listener(s) to add
*/
public void addEventListeners(SessionEventListener... listeners);
}

欢迎关注我的其它发布渠道