session.load()和session.get()的区别

本文详细解析了Hibernate框架中Load与Get方法的区别,包括它们如何处理数据库查询、缓存利用及异常处理等关键方面。

Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:
1. 对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查询数据库,数据库中没有就返回null。 
2. load方法加载实体对象的时候,根据映射文件上类级别的lazy属性的配置(默认为true),分情况讨论: 
(1)若为true,则首先在Session缓存中查找,看看该id对应的对象 是否 存在,不存在则使用延迟加载,返回实体的代理类对象(该代理类为实体类的子类,由CGLIB动态生成)。等到具体使用该对象(除获取OID以外)的时候, 再查询二级缓存和数据库,若仍没发现符合条件的记录,则会抛出一个ObjectNotFoundException。
(2)若为false,就跟get方法查找顺序一样,只是最终若没发现符合条件的记录,则会抛出一个ObjectNotFoundException。 
这里get和load有两个重要区别: 
如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException。 

load方法可返回没有 加载实体数据的代理类实例,而get方法永远返回有实体数据的对象。(对于load和get方法返回类型:好多书中都说:“get方法永远只返回实体 类”,实际上并不正确,get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被 其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会 查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。)

Java代码 
  1. Users user = (Users)session.load(Users.class, userId);   

这句代码不会去执行数据库查询,只有用到user时才会去执行数据库查询。

而:

Java代码
  1. Users user = (Users)session.get(Users.class, userId);    

 则立即去执行数据库查询。 所以Users user = (Users)session.load(Users.class, userId);不会执行任何sql。

注意:

Java代码
  1. Users user = (Users)session.load(Users.class, userId);     
  2. System.out.println(user.getId());   

上面这2句代码,不会去执行数据库操作。因为load后会在hibernate的一级缓存里存放一个map对象,该map的key就是userId的值,但是当你getId()时,它会去一级缓存里拿map的key值,而不去执行数据库查询。所以不会报任何错。不会执行任何数据库操作。

并且注意:这两个方法的第二个参数id,它必须是实现了Java.io.Serializable接口,也就是可序列化的。

 

/** *//**
  * load()方法的执行顺序如下:
  * a):首先通过id在session缓存中查找对象,如果存在此id的对象,直接将其返回
  * b):在二级缓存中查找,找到后将 其返回。
  * c):如果在session缓存和二级缓存中都找不到此对象,则从数据库中加载有此ID的对象
  * 因此load()方法并不总是导致SQL语句,只有缓存中无此数据时,才向数据库发送SQL!  
  */

 /** *//**
  * 与get()的区别:
  * 1:在立即加载对象(当hibernate在从数据库中取得数据组装好一个对象后
  * 会立即再从数据库取得数据此对象所关联的对象)时,如果对象存在,
  * load()和get()方法没有区别,都可以取得已初始化的对象;但如果当对
  * 象不存在且是立即加载时,使用get()方法则返回null,而使用load()则
  * 抛出一个异常。因此使用load()方法时,要确认查询的主键ID一定是存在
  * 的,从这一点讲它没有get方便!
  * 2:在延迟加载对象(Hibernate从数据库中取得数据组装好一个对象后,
  * 不会立即再从数据库取得数据组装此对象所关联的对象,而是等到需要时,
  * 都会从数据库取得数据组装此对象关联的对象)时,get()方法仍然使用
  * 立即加载的方式发送SQL语句,并得到已初始化的对象,而load()方法则
  * 根本不发送SQL语句,它返回一个代理对象,直到这个对象被访问时才被
  * 初始化。
  */

get()----不支持LAZY

load()----支持LAZY

转载于:https://www.cnblogs.com/xijin-wu/p/5730104.html

### Python 爬虫 Requests Session `get` 方法详解 #### 什么是 `Session.get()` 方法? 在 Python 的 `requests` 库中,`Session` 类提供了一种更高效的方式来管理 HTTP 请求。相比于普通的 `requests.get()` 或者其他独立的请求方式,`Session` 能够自动保存并重用连接池中的 TCP 连接[^1]。这不仅提高了性能,还允许跨多个请求共享 Cookie 头部信息。 当调用 `session.get(url)` 时,实际上是向指定 URL 发送了一个 GET 请求,并返回响应对象。此方法适用于需要多次交互的状态保持场景,比如登录后的页面浏览操作。 #### 基本语法 以下是 `session.get()` 的基本语法: ```python response = session.get(url, params=None, **kwargs) ``` - 参数说明: - `url`: 需要访问的目标地址。 - `params`: 字典形式的数据结构,用于传递查询参数到目标URL上附加成键值对的形式。 - `**kwargs`: 支持额外的关键字参数,例如 headers、cookies、timeout 等。 #### 示例代码 下面展示如何利用 `Session` 对象执行带状态保持功能的GET请求: ```python import requests # 创建一个新的会话实例 with requests.Session() as session: # 添加自定义头信息 session.headers.update({'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}) # 登录接口模拟提交表单数据 login_url = "https://example.com/login" payload = {'username': 'your_username', 'password': 'your_password'} response_login = session.post(login_url, data=payload) if response_login.status_code == 200 and "logged_in" in response_login.text: print("Login successful!") # 访问受保护资源页 protected_page_url = "https://example.com/dashboard" try: response_dashboard = session.get(protected_page_url, timeout=10) # 设置超时时间为10秒 [^2] if response_dashboard.ok: print(response_dashboard.content.decode('utf-8')) except requests.exceptions.Timeout: print("The request timed out.") ``` 上述例子展示了创建一个持久化的HTTP会话过程,先完成身份验证再加载仅限已认证用户的网页内容。同时设置了合理的超时时长以防程序卡死于无回应的服务端节点之上[^2]。 #### 处理 SSL 错误情况下的解决方案 有时因目标站点的安全证书存在问题而引发异常状况,可以尝试忽略这些警告继续运行脚本。不过需要注意的是这样做存在安全隐患,请谨慎对待生产环境部署此类改动! ```python import ssl from urllib3 import disable_warnings from urllib3.exceptions import InsecureRequestWarning disable_warnings(InsecureRequestWarning) context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE with requests.Session() as sesh: resp = sesh.get('https://expired.badssl.com/', verify=False, context=context)[^4] if resp.status_code != 200: raise Exception(f'Failed to load page with status code {resp.status_code}') else: print(resp.text[:50]) # 打印前五十字符确认成功读取文档主体部分 ``` 以上片段演示了禁用SSL验证从而绕过某些特定条件下无法正常工作的链接限制情形。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值