如果您对在具有循环引用的SQL中插入TABLES和存在循环引用感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解在具有循环引用的SQL中插入TABLES的各种细节,并对存在循环引用进行深入的分析,
如果您对在具有循环引用的SQL中插入TABLES和存在循环引用感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解在具有循环引用的SQL中插入TABLES的各种细节,并对存在循环引用进行深入的分析,此外还有关于android – 使用带有循环引用的Parcelable、ARC下使用MJRefresh时需要注意tableView循环引用、block循环引用的问题:、bootstrap table处理含有子集json的数据以及fastjson禁止循环引用的问题的实用技巧。
本文目录一览:- 在具有循环引用的SQL中插入TABLES(存在循环引用)
- android – 使用带有循环引用的Parcelable
- ARC下使用MJRefresh时需要注意tableView循环引用
- block循环引用的问题:
- bootstrap table处理含有子集json的数据以及fastjson禁止循环引用的问题
在具有循环引用的SQL中插入TABLES(存在循环引用)
我有2张表:
Empleados(**numEmpl**, nombre, apellido, sexo, telefono, salario, numDept)Departamentos(**numDept**, nombreDept, numDirect)
在部门中:
- numEmpl是主键
- numDept是对Departamentos(numDept)的外键引用。在部门中:
- numDept是主键
- numDirect是对Empleados(numEmpl)的外键引用
因此,有一个循环参考。
首先,我创建了表格:
CREATE TABLE EMPLEADOS(numEmpl primary key, nombre, apellido, sexo, telefono, salario, numDept)CREATE TABLE DEPARTAMENTOS(numDept primary key, nombreDept, numDirect)(i didn''t write here each of type is each colum)
现在,我在它们之间创建引用:
ALTER TABLE DEPARTAMENTOS ADD CONSTRAINT FK_DEPT_EMP FOREIGN KEY (numDirect) REFERENCES EMPLEADOS(numEmpl)ALTER TABLE EMPLEADOS ADD CONSTRAINT FK_EMP_DEPT FOREIGN KEY (numDept) REFERENCES DEPARTAMENTOS(numDept).
它起作用了,所以现在我尝试插入一些数据:
INSERT INTO Empleados(numEmpl, nombre, apellidos, sexo, telefono, salario, numDept)VALUES (1, ''Pepito'', ''P茅rez'', ''H'', ''111111111'', 20000, 1);INSERT INTO Departamentos(numDept, nombreDept, numDirect)VALUES (1, ''Direccion'', 1);
但是现在它引发了一个错误,告诉我不能在循环引用中引入数据,我试图禁用循环引用并插入数据,然后再次启用它,它起作用了,但是有人告诉我这不是正确的方法,在创建表以这种方式插入数据时我必须做一些特殊的事情,它会起作用,但是我不知道该怎么做。我正在使用oracle
sql developer。
编辑:感谢您的答案,但他们没有用。首先,我只能拥有该表,当我执行插入操作时,它必须以这种方式工作,而无需将参数设置为null并随后对其进行更新,很抱歉,我之前没有说过。因此,我要做的唯一方法就是允许圆参考,但是当我尝试以某人在这里所说的方式来做时,它告诉我一些有关回滚的信息,有人可以提供帮助吗?
答案1
小编典典要允许循环引用,您需要可延迟的约束:
ALTER TABLE DEPARTAMENTOS ADD CONSTRAINT FK_DEPT_EMP FOREIGN KEY (numDirect) REFERENCES EMPLEADOS(numEmpl) DEFERRABLE INITIALLY DEFERRED ;ALTER TABLE EMPLEADOS ADD CONSTRAINT FK_EMP_DEPT FOREIGN KEY (numDept) REFERENCES DEPARTAMENTOS(numDept) DEFERRABLE INITIALLY DEFERRED ;
在 事务结束时 检查可延展性约束;在提交时间之前,允许存在虚假的 无效数据库状态
(在原始问题中:两个插入语句之间)。但是语句必须在事务内部,因此语句应包含在BEGIN [WORK];
和中COMMIT [WORK];
。
android – 使用带有循环引用的Parcelable
I/TestRunner( 1571): java.lang.StackOverflowError I/TestRunner( 1571): at android.os.Parcel.writeParcelable(Parcel.java:1106) I/TestRunner( 1571): at android.os.Parcel.writeValue(Parcel.java:1029) I/TestRunner( 1571): at com.XXX.util.ParcelableTest$Bar.writetoParcel(ParcelableTest.java:209) I/TestRunner( 1571): at android.os.Parcel.writeParcelable(Parcel.java:1106) I/TestRunner( 1571): at android.os.Parcel.writeValue(Parcel.java:1029) I/TestRunner( 1571): at com.XXX.util.ParcelableTest$Baz.writetoParcel(ParcelableTest.java:246) I/TestRunner( 1571): at android.os.Parcel.writeParcelable(Parcel.java:1106) I/TestRunner( 1571): at android.os.Parcel.writeValue(Parcel.java:1029) I/TestRunner( 1571): at com.XXX.util.ParcelableTest$Bar.writetoParcel(ParcelableTest.java:209) I/TestRunner( 1571): at android.os.Parcel.writeParcelable(Parcel.java:1106) I/TestRunner( 1571): at android.os.Parcel.writeValue(Parcel.java:1029) public void testCircular() throws Exception { final Bar bar = new Bar(); final Baz baz = new Baz(bar); bar.baz = baz; // First,serialize final ByteArrayOutputStream bytes = new ByteArrayOutputStream(); new ObjectOutputStream(bytes).writeObject(bar); final ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes.toByteArray()); final Bar bar2 = (Bar) new ObjectInputStream(bytesIn).readobject(); assertNotNull(bar2); assertNotNull(bar2.baz); assertEquals( bar2,bar2.baz.bar ); // Now try same thing using parcelable final Parcel p = Parcel.obtain(); p.writeValue(bar); // FAIL! StackOverflowError p.setDataPosition(0); final Bar bar3 = (Bar) p.readValue(Bar.class.getClassLoader()); assertNotNull(bar3); assertNotNull(bar3.baz); assertEquals( bar3,bar3.baz.bar ); } protected static class Bar implements Parcelable,Serializable { private static final long serialVersionUID = 1L; public static final Parcelable.Creator<Bar> CREATOR = new Parcelable.Creator<Bar>() { public Bar createFromParcel(Parcel source) { final Bar f = new Bar(); f.baz = (Baz) source.readValue(Bar.class.getClassLoader()); return f; } public Bar[] newArray(int size) { throw new UnsupportedOperationException(); } }; public Baz baz; public Bar() { } public Bar( Baz baz ) { this.baz = baz; } public int describeContents() { return 0; } public void writetoParcel(Parcel dest,int ignored) { dest.writeValue(baz); } } protected static class Baz implements Parcelable,Serializable { private static final long serialVersionUID = 1L; public static final Parcelable.Creator<Baz> CREATOR = new Parcelable.Creator<Baz>() { public Baz createFromParcel(Parcel source) { final Baz f = new Baz(); f.bar = (Bar) source.readValue(Baz.class.getClassLoader()); return f; } public Baz[] newArray(int size) { throw new UnsupportedOperationException(); } }; public Bar bar; public Baz() { } public Baz( Bar bar ) { this.bar = bar; } public int describeContents() { return 0; } public void writetoParcel(Parcel dest,int ignored) { dest.writeValue(bar); } }
我正在尝试将一些代码从使用Serializable转换为使用循环引用的Parcelable.使用Parcelable处理此问题是否有一个好的策略?
解决方法
在我的脑海中,您可以保留已经完全写入给定Parcel的对象列表,并仅通过标记(可能是其本地identityHashCode())来标识它们. (请注意,这不是一个全局列表,它是明确的per-Parcel;也许它本身是通过半全局Map< Parcel,Set< Integer>>存储的?你需要确保一旦包裹遗忘了这个集合完全写了.)
writetoParcel()的相关位看起来像这样:
HashSet<Integer> set = getWrittenSetFor(dest); final int tag = identityHashCode(); if (set.contains(tag)) { // Already sent dest.writeInt(tag); } else { set.put(tag); dest.writeInt(tag); dest.writeValue(this); }
相应的createFromParcel()会稍微复杂一些.
我希望这种方法存在潜在的问题,但这是我开始的地方.正如我在这里所说的,它依赖于identityHashCode()保证对于不同的对象是不同的 – 它通常在32位JVM上(作为底层C指针的值).普通的hashCode()可能是值得的(可能添加了输入信息?),或者某种序列号.
另一个选择可能是将对象简单地序列化为byte []并将其写入Parcel,但它让我觉得有点低效……
ARC下使用MJRefresh时需要注意tableView循环引用
直接上代码,这是一个懒加载,相信大多数朋友已经发现在使用MJRefresh时出现了内存管理的错误
#pragma mark======创建主界面
- (UITableView *)tableView
{
if (!_tableView) {
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 108, WIDTH, HEIGHT-108-44) style:UITableViewStylePlain];
_tableView.backgroundColor = [UIColor colorWithRed:220/255.0 green:222/255.0 blue:222/255.0 alpha:1];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.dataSource = self;
_tableView.delegate = self;
[_tableView registerNib:[UINib nibWithNibName:@"OldGoodsCell" bundle:nil] forCellReuseIdentifier:@"cell"];
_tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(refersh)];
_tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
#pragma mark======加载更多数据
NSLog(@"加载更多数据");
[_tableView.mj_footer endRefreshing];
}];
}
return _tableView;
}
上述代码中,造成循环引用的地方依然是最基本的block,即
_tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
#pragma mark======加载更多数据
NSLog(@"加载更多数据");
[_tableView.mj_footer endRefreshing];
}];
_tableView的mj_footer内部是这样的,self就是_tableView;
- (void)setMj_footer:(MJRefreshFooter *)mj_footer
{
if (mj_footer != self.mj_footer) {
// 删除旧的,添加新的
[self.mj_footer removeFromSuperview];
[self addSubview:mj_footer];
// 存储新的
[self willChangeValueForKey:@"mj_footer"]; // KVO
objc_setAssociatedObject(self, &MJRefreshFooterKey,
mj_footer, OBJC_ASSOCIATION_ASSIGN);
[self didChangeValueForKey:@"mj_footer"]; // KVO
}
}
但是,我们在block里是这样写的
[MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
[_tableView.mj_footer endRefreshing];
}]
很明显,造成了_tableView 的 循环引用,紧接着由于我们的_tableView 是 strong 类型的,它的循环引用带来的结果就是所属的viewController对象无法释放,继而造成dealloc无法执行。我们要打破这种情况,只要打破_tableView的循环引用就成功了。
所以我们要把viewController的self变成弱类型的weakSelf ,(不会变的请看这个__weak __typeof(&*self)weakSelf = self;会的请忽略) 即整行代码变成 [weakSelf.tableView.mj_footer endRefreshing];
这样一来,即使在给mj_footer的block里出现了
[weakSelf.tableView.mj_footer endRefreshing]; weakSelf都是弱类型的了,里面的tableView也会随之释放,tableView的循环引用也就解决,循环引用的解决,dealloc方法也就恢复正常
block循环引用的问题:
在ARC模式下
执行下面语句:
1. - (IBAction)onTest:(id)sender
2. {
3. BlockDemo *demo = [[BlockDemo alloc]init];
4. [demo setExecuteFinished:^{
5. if (demo.resultCode == 200) {
6. NSLog(@"call back ok.");
7. }
8. }];
9.
10. [demo executeTest];
11.
12. }
执行输出结果:
1. 2015-07-24 19:20:33.997 blockDemo[25215:60b] Object Constructor!
2. 2015-07-24 19:20:39.000 blockDemo[25215:60b] call back ok.
同样会被引入循环。
相信看到这里的人,大多都要喷了,这哪个不知道呀,还知道怎么解决呢,非ARC中加了个__block,当然的在ARC中加一个__weak就搞定了。嗯,确实是这样,但别急,接着往下看,绝对有收获。在这里先自己默认想一下,你是如何加这个__weak的。
对于第一个问是点block 的循环引用(retain cycle)到这里暂告结束。下面讲第二点。因为block告警在非ARC 中暂未发现因写法引入(如果你知道,麻烦告诉我怎么弄产生告警,我好研究一下。)
下面讲在ARC模式下去除因写法产生的告警时需要注意的问题。
像上面的写法其实在ARC中会产生(Capturing ''demo'' strongly in this block is likely to lead to a retain cycle)告警。如下图:

在ARC中,编译器智能化了,直接提示这样写会产生循环引用。因此很多爱去除告警的朋友就会想法去掉,好,咱再来看去掉时需注意的问题。
情况一:
1. - (IBAction)onTest:(id)sender
2. {
3. __weak BlockDemo *demo = [[BlockDemo alloc]init];
4. [demo setExecuteFinished:^{
5. if (demo.resultCode == 200) {
6. NSLog(@"call back ok.");
7. }
8. }];
9. [demo executeTest];
10. }
直接在前面加一个__weak,但这样真的没有告警了吗?如果有,哪么恭喜欢你,说明编译器还帮你大忙。见下图

这时还会告警,说这是一个WEAK变量,就马上会被release。因此就不会执行block中的内容。大家可以运行一下看
输出结果为:
1. 2014-07-24 19:38:02.453 blockDemo[25305:60b] Object Constructor!
2. 2014-07-24 19:38:02.454 blockDemo[25305:60b] Object Destoryed!
很显然,马上被release了,所以block 中的代码根本就不执行。
谢天谢地,幸好编译器提前告诉了我们有这个隐性危险。相信大家为解决告警,又会得到一个比较圆满的解决方案,见下:
1. - (IBAction)onTest:(id)sender
2. {
3. BlockDemo *demo = [[BlockDemo alloc]init];
4.
5. __weak typeof(BlockDemo) *weakDemo = demo;
6.
7. [demo setExecuteFinished:^{
8. if (weakDemo.resultCode == 200) {
9. NSLog(@"call back ok.");
10. }
11. }];
12. [demo executeTest];
13. }
这样写,即去除了告警又保证了block的运行。这才是我们最终想要的结果。
输出为:
1. 2014-07-24 19:40:33.204 blockDemo[25328:60b] Object Constructor!
2. 2014-07-24 19:40:38.206 blockDemo[25328:60b] call back ok.
3. 2014-07-24 19:40:38.207 blockDemo[25328:60b] Object Destoryed!
但大家别得意。有提示,相信大家都能处理,并得到个好的解决方法。哪么下面大来再来看一下这个写法,让你真心甘拜下风。。。。。
1. - (IBAction)onTest:(id)sender
2. {
3. __weak BlockDemo *demo = [BlockDemo blockdemo]; //这里才是重点,前面是[[BlockDemo alloc]init];会有告警。
4.
5. [demo setExecuteFinished:^{
6. if (demo.resultCode == 200) {
7. NSLog(@"call back ok.");
8. }
9. }];
10. [demo executeTest];
11. }
其实只是把init放到了类方法中进行书写而已,但会有什么不同。
1. + (BlockDemo *)blockdemo
2. {
3. return OBJC_AUTORELEASE([[BlockDemo alloc]init]);
4. }
不同点见下图:真心看不到作何告警,是不是。但这存在什么风险,风险就是运行的时候,block根本就没有run。因为对象早就释放了。

直接输出:
1. 2015-07-24 19:47:53.033 blockDemo[25395:60b] Object Constructor!
2. 2015-07-24 19:47:53.035 blockDemo[25395:60b] Object Destoryed!
因 此,写这个主要用来告戒一些喜欢用BLOCK但又想当然的朋友,有一些朋友喜欢去除告警,但只是盲目的加上__weak 或__block关键语,往往可能存在一些重大的安全隐患。就像演示中block根本不走。如果到了发布时,为了去告警而这样简单的处理了,并没有进行测 试就打包。哪么将死得很惨。。。。。
好,到了尾声,来说说为什么朋友问我block会不会引行死循环,我说不会的理由。
见码:
1. - (IBAction)onTest:(id)sender
2. {
3. BlockDemo *demo = [BlockDemo blockdemo];//[[BlockDemo alloc]init];
4.
5. [demo setExecuteFinishedParam:^(BlockDemo * ademo) {
6. if (ademo.resultCode == 200) {
7. NSLog(@"call back ok.");
8. }
9. }];
10.
11. [demo executeTest];
12. }
不管是在外面init,还是在里面,且没有加__block 及__weak。为什么,因为我个人常常在使用自己写的block时,如果是回调,比较喜欢把自身当作参数传到block中。这样期实是编译器给我们做了弱引用。因此不会产生循环引用。
由 于我一直都这样写block,所以朋友一问起,我就说不会循环引用了,因为压根他碰到的就是前面讲述的哪种访问方式,而我回答的是我的这种使用方式。正因 为口头描述,与实际回复真是差之千里。。。哈哈。为了验证我朋友的这个,我特意写了个这篇文章,希望对大家有所帮助。最后,谢谢大家花时间阅读。
bootstrap table处理含有子集json的数据以及fastjson禁止循环引用的问题
总结
以上是小编为你收集整理的bootstrap table处理含有子集json的数据以及fastjson禁止循环引用的问题全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
今天关于在具有循环引用的SQL中插入TABLES和存在循环引用的分享就到这里,希望大家有所收获,若想了解更多关于android – 使用带有循环引用的Parcelable、ARC下使用MJRefresh时需要注意tableView循环引用、block循环引用的问题:、bootstrap table处理含有子集json的数据以及fastjson禁止循环引用的问题等相关知识,可以在本站进行查询。
本文标签: