如何从Hibernate中的OneToMany Collection中仅选择一些属性?(How to Select only some properties from a OneToMany Collection in Hibernate?)
TL; DR
如何获得B集合中只有少数属性的单个A对象?
说明
我正在研究一个遗留项目,在这个项目中,人们有明智的想法将每个关系映射为EAGER。
现在,我们遇到了性能问题。
例如,我有A类,它有一个B对象列表。 该列表已在hibernate中映射为一个包,并且懒得加载(到目前为止,这么好)。 问题是,B急切地加载了整个怪异的字母表:
A.hbm.xml
<hibernate-mapping> <class="A" table="a" lazy="false"> // properties <bag name="listOfBs" inverse="true"> <key column="a_id" [...]> <one-to-many class="B" /> </bag> </hibernate-mapping>
B.hbm.xml
<hibernate-mapping> <class="B" table="b" lazy="false"> <many-to-one name="a" class="A" column="a_id" /> // lots of other many-to-one mappings // properties // lots of one-to-many properties </hibernate-mapping>
所以我只需要B的4个属性,但它会获取每个相关对象!
为了解决这个问题而不破坏一切,我试图使用hql查询只选择集合的几个列:
"select a, b.field1, b.field2, b.field3, b.field4 from A a inner join B b where a.id = :id"
但我需要一个唯一的结果,因此以下查询会导致异常。
TL;DR
How can I get a single A object with only a few properties in a B collection?
Explanation
I am working on a legacy project where people had the brillant idea to map every relationship as EAGER.
Now, we are having performance problems.
For instance, I have Class A, that has a list of B objects. That list has been mapped as a bag in hibernate, and loads lazily (so far, so good). The problem is, B eagerly loads the whole freaking alphabet:
A.hbm.xml
<hibernate-mapping> <class="A" table="a" lazy="false"> // properties <bag name="listOfBs" inverse="true"> <key column="a_id" [...]> <one-to-many class="B" /> </bag> </hibernate-mapping>
B.hbm.xml
<hibernate-mapping> <class="B" table="b" lazy="false"> <many-to-one name="a" class="A" column="a_id" /> // lots of other many-to-one mappings // properties // lots of one-to-many properties </hibernate-mapping>
So I need only 4 properties of B, but it fetches every related object!
In order to solve this without breaking everything, I am trying to use a hql query to select only a few column of the collection:
"select a, b.field1, b.field2, b.field3, b.field4 from A a inner join B b where a.id = :id"
But I need an Unique Result, so the following query causes an exception.
原文:https://stackoverflow.com/questions/18774101
最满意答案
您需要注意的是,SQLite文档警告您不要从多个线程访问/写入数据库。 只要您从单个线程访问数据库,您就可以了。 如果该线程是程序的主线程或其他线程并不重要。
请记住,iPhone上编译的SQLite版本的线程模式设置为“多线程”,根据文档 ,“禁用数据库连接和准备好的语句对象的静音。应用程序负责序列化对数据库连接的访问并且准备好了语句,但是启用了其他互斥锁,这样只要没有两个线程同时尝试使用相同的数据库连接,SQLite就可以安全地在多线程环境中使用。“ 因此,如果您决定将此事务放在另一个线程上,请注意您尝试对数据库执行的其他操作。
话虽这么说,我首先按照Yonel的建议切换到“BEGIN”和“COMMIT”。 如果这没有帮助,请将事务移动到另一个线程。 根据我所听到的情况,使用“blob”可能会非常缓慢。
The thing that you need to be aware of is that the SQLite documentation warns you away from accessing/writing to the database from multiple threads. As long as you access the database from a single thread, you'll be fine. It doesn't matter if that thread is your program's main thread or some other thread.
Keep in mind that compiled version of SQLite on the iPhone has its threading mode set to "multi-thread" which, according to the documentation, "disables mutexing on database connection and prepared statement objects. The application is responsible for serializing access to database connections and prepared statements but other mutexes are enabled so that SQLite will be safe to use in a multi-threaded environment as long as no two threads attempt to use the same database connection at the same time." So, if you do decide to put this transaction on another thread, be careful of what else you try to do with the database.
That being said, I'd first follow Yonel's advice and switch to "BEGIN" AND "COMMIT". If that doesn't help, move the transaction to another thread. Working with "blobs" can be pretty slow, from what I've heard.
相关问答
更多-
只要调用sqlite3_open函数,它将创建一个数据库,如果路径上没有数据库存在。 // generate databasePath programmatically if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) { // your code here } 如果您需要更多代码示例,请发表评论 Just call the sqlite3_open function it will create a databa ...
-
如何在iphone中的sqlite数据库中存储图像[重复](How to store images in the sqlite database in iphone [duplicate])[2022-01-25]
在nsdocument目录中保存图像。 在数据库中保存此图像的路径。 这是一个很好的方法。 如果你在数据库数据库中保存blob会那么重。 加载需要时间。 save image in your nsdocument directory. in database save the path of this image. this is a good approach. if u save blob in data base database will so heavy. it take time to load ... -
你检查过那个绑定的返回类型了吗? 它可能会返回错误代码(该语句仍然可能在此事件中执行,只是错误地执行)。 作为一种解决方法,您是否尝试过创建ZEROBLOB,然后使用SQLite文档中描述的BLOB I / O例程写入它? 这将是我在查看错误代码后尝试的下一件事。 I've found the perpetrator in this wild good chase... I was taking the value of column 1 instead of column 0, which was the ...
-
您还可以使用SQLite中的attach语句使另一个数据库可见: http://www.sqlite.org/lang_attach.html 这样,您只需要一个连接即可访问这两个数据库。 替换或更新静态内容将不会对用户数据产生任何影响。 You can also use the attach statement from SQLite to make one database visible to the other: http://www.sqlite.org/lang_attach.html That ...
-
如何通过iphone编程插入多行数据到sqlite数据库(How to insert multiple row of data to sqlite database by iphone programming)[2024-03-05]
试试下面给出的sprintf statement , 在变量i的循环中使用这个语句。 sprintf(buffer,"INSERT INTO user (name) VALUES ('%s');",[[names objectAtIndex:i] UTF8String]); Try with sprintf statement given below, use this statement inside the loop with variable i. sprintf(buffer,"INSERT IN ... -
我使用sqlite作为我的db文件的扩展名,所以不应该有任何问题。 你为什么不提供更多的细节,如你实际提供文件路径的位置。 很可能你只是在某处丢失了一些轻微和烦人的细节。 I'm using sqlite as extension for my db file, so there shouldn't be any problem with that. Why don't you provide more details like where you actually provide the file pat ...
-
你的代码缺少sqlite3_step() Your code is missing sqlite3_step()
-
如果您真的对学习如何使用SQLite管理iPhone应用程序中的数据感兴趣,我建议您完成以下教程,因为它是一个非常好的介绍: 使用iPhone编程教程创造-A-待办事项列表- - sqlite的部分-1 本教程使用SQLite处理iPhone应用程序中的选择,更新,插入和删除数据。 If you're really interested in learning how to use SQLite to manage data in an iPhone app, I would recommend you t ...
-
您需要注意的是,SQLite文档警告您不要从多个线程访问/写入数据库。 只要您从单个线程访问数据库,您就可以了。 如果该线程是程序的主线程或其他线程并不重要。 请记住,iPhone上编译的SQLite版本的线程模式设置为“多线程”,根据文档 ,“禁用数据库连接和准备好的语句对象的静音。应用程序负责序列化对数据库连接的访问并且准备好了语句,但是启用了其他互斥锁,这样只要没有两个线程同时尝试使用相同的数据库连接,SQLite就可以安全地在多线程环境中使用。“ 因此,如果您决定将此事务放在另一个线程上,请注意您尝 ...
-
从UITextfield中给出的输入中搜索iPhone中的SQLite3数据库(Searching SQLite3 DB in iPhone from input given in UITextfield)[2023-08-12]
你想做什么? 您可以将readPlayersFromDatabase方法的参数作为参数发送到UITextfield输入。 这是我选择命令的方法:我有一个名为DBOperations的类。 我希望有所帮助 + (int) getUserID{ //check DB if (![DBOperations checkDB]) { NSString *msgAlert = @"can not access db file."; UIAlertView *alert = [[UIAlertView ...