在本文中,我们将为您详细介绍休眠:一对一延迟加载,可选=false的相关知识,并且为您解答关于休眠延迟15秒的疑问,此外,我们还会提供一些关于AngularLazyload(延迟加载,惰性加载)机制和
在本文中,我们将为您详细介绍休眠:一对一延迟加载,可选= false的相关知识,并且为您解答关于休眠延迟15秒的疑问,此外,我们还会提供一些关于Angular Lazy load (延迟加载,惰性加载) 机制和 feature module 的学习笔记、angular – 如何在延迟加载的模块中提供服务,并将该服务限定为延迟加载的模块及其组件?、entity-framework – 实体框架中的延迟加载,延迟加载和Eager加载、Hibernate延迟加载以实现一对一的反向解决方法-这项工作如何进行?的有用信息。
本文目录一览:- 休眠:一对一延迟加载,可选= false(休眠延迟15秒)
- Angular Lazy load (延迟加载,惰性加载) 机制和 feature module 的学习笔记
- angular – 如何在延迟加载的模块中提供服务,并将该服务限定为延迟加载的模块及其组件?
- entity-framework – 实体框架中的延迟加载,延迟加载和Eager加载
- Hibernate延迟加载以实现一对一的反向解决方法-这项工作如何进行?
休眠:一对一延迟加载,可选= false(休眠延迟15秒)
我遇到了 一个 问题,即 一对一的延迟加载 在hibernate状态下不起作用。我 已经解决了它 ,但仍然 无法 正确 理解
会发生什么。
我的代码( 延迟加载在这里不起作用 ,当我拉人时-地址也被获取):
@Entitypublic class Person{ @Id @SequenceGenerator(name = "person_sequence", sequenceName = "sq_person") @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "person_sequence") @Column(name = "id") private long personID; @OneToOne(mappedBy="person", cascade=CascadeType.ALL, fetch = FetchType.LAZY) private Adress address; //.. getters, setters}@Entitypublic class Address { @Id @Column(name="id", unique=true, nullable=false) @GeneratedValue(generator="gen") @GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="person")) private long personID; @PrimaryKeyJoinColumn @OneToOne private FileInfo person;}
但是 :如果我添加 optional=false
OneToOne关系,则延迟加载 效果很好 !
@OneToOne(mappedBy="person", cascade=CascadeType.ALL, optional = false, fetch = FetchType.LAZY)private Adress address;
问题/完整性: 请向我解释optional=false
注释如何帮助实现延迟加载。
PS 我已经阅读了post1和post2的帖子,并了解了为什么简单的OneToOne不能偷懒,但是我仍然无法掌握optional=false
魔术。
答案1
小编典典如果关联是可选的,则Hibernate无法在不发出查询的情况下知道给定人员的地址是否存在。因此,它不能使用代理填充地址字段,因为可能没有引用该人的地址,并且不能填充null,因为可能存在引用该人的地址。
当您使关联成为强制性(即optional=false
)时,它会信任您并假定一个地址存在,因为关联是强制性的。因此,在知道有引用该人的地址的情况下,它直接用代理填充地址字段。
Angular Lazy load (延迟加载,惰性加载) 机制和 feature module 的学习笔记
官网链接
默认情况下,NgModules 是贪婪加载的,这意味着一旦应用程序加载,所有 NgModules 也会加载,无论它们是否立即需要。 对于有很多路由的大型应用程序,可以考虑延迟加载 —— 一种根据需要加载 NgModules 的设计模式。 延迟加载有助于保持较小的初始包大小,从而有助于减少加载时间。
要惰性加载 Angular 模块,请在 AppRoutingModule routes 中使用 loadChildren 代替 component 进行配置,代码如下。
const routes: Routes = [
{
path: ''items'',
loadChildren: () => import(''./items/items.module'').then(m => m.ItemsModule)
}
];
在惰性加载模块,也就是被 AppRoutingModule 加载的模块,的路由模块中,添加一个指向该组件的路由。
const routes: Routes = [
{
path: '''',
component: ItemsComponent
}
];
还要确保从 AppModule 中移除了 ItemsModule。这一步很关键,即 AppModule 中不能出现 import ItemsModule 的语句。否则最后 ItemsModule 会和 AppModule 打包在同一个 chunk 里。
Feature Module
特性模块是用来对代码进行组织的模块。
随着应用的增长,你可能需要组织与特定应用有关的代码。 这将帮你把特性划出清晰的边界。使用特性模块,你可以把与特定的功能或特性有关的代码从其它代码中分离出来。 为应用勾勒出清晰的边界,有助于开发人员之间、小组之间的协作,有助于分离各个指令,并帮助管理根模块的大小。
特性模块 vs. 根模块
与核心的 Angular API 的概念相反,特性模块是最佳的组织方式。特性模块提供了聚焦于特定应用需求的一组功能,比如用户工作流、路由或表单。 虽然你也可以用根模块做完所有事情,不过特性模块可以帮助你把应用划分成一些聚焦的功能区。特性模块通过它提供的服务以及共享出的组件、指令和管道来与根模块和其它模块合作。
创建 feature module 的命令行:
ng generate module CustomerDashboard
这会让 CLI 创建一个名叫 customer-dashboard 的文件夹,其中有一个名叫 customer-dashboard.module.ts,内容如下:
import { NgModule } from ''@angular/core'';
import { CommonModule } from ''@angular/common'';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class CustomerDashboardModule { }
无论根模块还是特性模块,其 NgModule 结构都是一样的。在 CLI 生成的特性模块中,在文件顶部有两个 JavaScript 的导入语句:第一个导入了 NgModule,它像根模块中一样让你能使用 @NgModule 装饰器;第二个导入了 CommonModule,它提供了很多像 ngIf 和 ngFor 这样的常用指令。 特性模块导入 CommonModule,而不是 BrowserModule,后者只应该在根模块中导入一次。 CommonModule 只包含常用指令的信息,比如 ngIf 和 ngFor,它们在大多数模板中都要用到,而 BrowserModule 为浏览器所做的应用配置只会使用一次。
declarations 数组让你能添加专属于这个模块的可声明对象(组件、指令和管道)。 要添加组件,就在命令行中输入如下命令,这里的 customer-dashboard 是一个目录,CLI 会把特性模块生成在这里,而 CustomerDashboard 就是该组件的名字:
ng generate component customer-dashboard/CustomerDashboard
这会在 customer-dashboard 中为新组件生成一个目录,并使用 CustomerDashboardComponent 的信息修改这个特性模块:
CustomerDashboardComponent 出现在了顶部的 JavaScript 导入列表里,并且被添加到了 declarations 数组中,它会让 Angular 把新组件和这个特性模块联系起来。
导入特性模块
要想把这个特性模块包含进应用中,你还得让根模块 app.module.ts 知道它。要想把它导入到 AppModule 中,就把它加入 app.module.ts 的导入表中,即将其加入 imports 数组:
当 CLI 为这个特性模块生成 CustomerDashboardComponent 时,还包含一个模板 customer-dashboard.component.html,它带有如下页面脚本:
<p>
customer-dashboard works!
</p>
要想在 AppComponent 中查看这些 HTML,你首先要在 CustomerDashboardModule 中导出 CustomerDashboardComponent。 在 customer-dashboard.module.ts 中,declarations 数组的紧下方,加入一个包含 CustomerDashboardModule 的 exports 数组:
然后,在 AppComponent 的 app.component.html 中,加入标签 :
2021-7-12 Monday
看一个例子:
CustomerMainModule 是 eager load,在其实现代码里引用了 ProductModule,后者本意是期望 Lazy Load,但是这种代码里静态 import 方式,破坏了 ProductModule 的懒加载,最终两个 module 会被打包在一起,出现在一个 chunk 里。
更多 Jerry 的原创文章,尽在:“汪子熙”:
本文同步分享在 博客 “汪子熙”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与 “OSC 源创计划”,欢迎正在阅读的你也加入,一起分享。
angular – 如何在延迟加载的模块中提供服务,并将该服务限定为延迟加载的模块及其组件?
这里的’module-scoped’是指模块还是扩展为包含属于该模块的所有组件?
我问的原因是因为我有一个带有2个属于它的组件的延迟加载模块.我在模块中注册了一个服务,但由于某种原因,每个组件都获得了该服务的不同实例.
为了在我的延迟加载模块中提供LazyModuleService并将该服务限定为延迟加载的模块及其组件,我需要更改什么?请包含所需的任何其他文件.我试图做一个通用的例子来帮助其他可能找到这个问题的人.
延迟加载模块:
import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { Component1 } from './component1.component'; import { Component2 } from './component2.component'; import { LazyModuleService } from './lazy-module.service'; @NgModule({ imports: [ CommonModule,],declarations: [ Component1,Component2,}) export class LazyLoadedModule { }
解决方法
经过深入调查后,似乎问题与如何实现延迟加载有关.
在您的情况下,您的延迟加载模块实际上已路由到其中的两个不同组件 – 这两个组件都直接公开为Router.forChild路由.但是,因此,当您导航到每个组件时,会为每个组件添加一个单独的延迟加载模块提供程序实例.
由于您实际上希望延迟加载模块中的所有组件共享其提供的服务的相同实例,因此您需要创建一个“根”组件,然后让您的两个组件成为该根组件的子组件.
似乎在延迟加载时,模块中的提供程序将添加到模块根部的组件的注入器中.由于您有两个“根组件”,因此每个组件都有不同的服务实例.
解决方案是创建一个单个根组件,其注入器将接收延迟加载的服务,然后可以由任何子组件共享.
entity-framework – 实体框架中的延迟加载,延迟加载和Eager加载
@H_301_0@解决方法
var people = (from p in people SELECT p).ToList(); var jobs = (from j in jobs SELECT j).ToList(); var peopleAndJobs = (from p in people JOIN j on j.personId equals p.personId SELECT p).ToList()
这是急切加载的一个例子.我们得到所有人,所有工作,我们正在加入记忆.不是很聪明(通常).这就是懒惰风格.
var people = (from p in people SELECT p); var jobs = (from j in jobs SELECT j); var peopleAndJobs = (from p in people JOIN j on j.personId equals p.personId SELECT p).ToList()
这样做是为人和工作创建一个IQueryable(IQueryable是懒惰的),并且连接发生在数据库中.这样可以节省网络活动,并且通常实际上更快,因为DB已经过优化以进行连接等.
除非我们明确说“我需要那些数据!” (通过ToListing,迭代它等)它是懒惰的.还有一些更多的怪癖,但这应该是一个不错的入门.
Hibernate延迟加载以实现一对一的反向解决方法-这项工作如何进行?
我今天遇到问题,在使用按映射的集合时,延迟加载无法正常工作。我发现这篇出色的文章似乎可以解决问题
http://justonjava.blogspot.co.uk/2010/09/lazy-one-to-one-and-one-to-
many.html
我不明白的一件事是使用FieldHandled的解决方法如何工作。谁能帮我理解这一点?有问题的代码如下(从链接中的示例复制):
@Entitypublic class Animal implements FieldHandled { private Person owner; private FieldHandler fieldHandler; @OneToOne(fetch = FetchType.LAZY, optional = true, mappedBy = "animal") @LazyToOne(LazyToOneOption.NO_PROXY) public Person getOwner() { if (fieldHandler != null) { return (Person) fieldHandler.readObject(this, "owner", owner); } return owner; } public void setOwner(Person owner) { if (fieldHandler != null) { this.owner = fieldHandler.writeObject(this, "owner", this.owner, owner); return; } this.owner = owner; } public FieldHandler getFieldHandler() { return fieldHandler; } public void setFieldHandler(FieldHandler fieldHandler) { this.fieldHandler = fieldHandler; }}
我想念什么?也许我对Hibernate的生命周期了解不够?我乐意进行调查,但任何人都可以给我一些指导。
提前致谢。
编辑
我进行了很多更改,因此许多实体实现了FieldHandled,但随后发现我的某些测试失败了。如果仅使用这些方法集来实现该接口,那么我就抽出了SQL,并得到了一些奇怪的信息,这些SQL以不同的顺序发生了。
public FieldHandler getFieldHandler() { return fieldHandler; } public void setFieldHandler(FieldHandler fieldHandler) { this.fieldHandler = fieldHandler; }
这导致测试失败,因为我断言时事情还没有处于正确的状态。这增加了我对该FieldHandler变量的误解。
答案1
小编典典下面的代码告诉Hibernate使用拦截处理程序代替代理。
@LazyToOne(LazyToOneOption.NO_PROXY)
从javadoc:
返回请求引用时加载的真实对象(此选项必须增强字节码,如果未增强该类,则退回到PROXY)
可以看出,在使用字节码之前需要对其进行检测。检测“字节码”后,“持久类得到增强”。
这个想法是要愚弄Hibernate,我们要使用的实体类已经被检测了
编译代码后将调用检测任务。工具实体扩展FieldHandled
。FieldHandled
是“引入增强类的接口”
Hibernate在运行时验证实体,并得出结论,类得到了增强,这就是为什么它使用真实对象而不是代理并且不像往常那样加载相关实体对象的原因。
编辑:
让我们来看看幕后花絮:
AnnotationBinder句柄
NO_PROXY
选项if ( lazy != null ) {toOne.setLazy( !( lazy.value() == LazyToOneOption.FALSE ) );toOne.setUnwrapProxy( ( lazy.value() == LazyToOneOption.NO_PROXY ) );
}
这两个
org.hibernate.mapping.ManyToOne
和org.hibernate.mapping.OneToOne
是的子类org.hibernate.mapping.ToOne
。ToOne#isUnwrapProxy()
唯一的用途是#getType
:
getMappings()。getTypeResolver()。getTypeFactory()。oneToOne(
这两个
ManyToOneType
和OneToOneType
是的子类EntityType
,只有“的EntityType#unwrapProxy”的用法是在EntityType#resolveIdentifier(Serializable, SessionImplementor)
boolean isProxyUnwrapEnabled = unwrapProxy && session.getFactory() .getEntityPersister( getAssociatedEntityName() ) .isInstrumented();
这是暂定的呼叫层次结构:
AbstractEntityPersister#isInstrumented()
->EntityMetamodel#isInstrumented()
->EntityInstrumentationMetadata#isInstrumented()
->等,最后BytecodeProviderImpl.EntityInstrumentationMetadataImpl.EntityInstrumentationMetadataImpl()
this.isInstrumented = FieldHandled.class.isAssignableFrom( entityClass );
这就是为什么需要检测代码(例如使用InstrumentTask
)或实现的原因FieldHandled
。
为了使长话短说你可以看一看EntityType#resolveIdentifier(Serializable,SessionImplementor)
。这就是为什么即使第二个对象为空也不会加载的原因。
关于休眠:一对一延迟加载,可选= false和休眠延迟15秒的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Angular Lazy load (延迟加载,惰性加载) 机制和 feature module 的学习笔记、angular – 如何在延迟加载的模块中提供服务,并将该服务限定为延迟加载的模块及其组件?、entity-framework – 实体框架中的延迟加载,延迟加载和Eager加载、Hibernate延迟加载以实现一对一的反向解决方法-这项工作如何进行?等相关内容,可以在本站寻找。
本文标签: