- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我决定尝试将 mybatis 用于一个新项目。我对 SQL 相当熟悉,最近我对 hibernate 有一些不好的体验,所以我正在寻找一种更底层的 DAO 方法。
除了一件事之外似乎相当不错,那就是处理集合。
我有两个 POJO,组和用户,它们是多对多的。我已经决定了一种设计理念,即具有集合的 POJO 应该只在保存时更新表之间的 M-M 关系。因此,例如,当我保存一个包含用户集合的组对象时,设计理念规定用户应该已经保存,我只需要在数据库中保存组和 group_user 关系。
所以,对于接口(interface)中的saveGroup函数,我为mybatis做了这样的XML映射:
<insert id="saveGroup" keyColumn="id"
parameterType="se.myapp.domain.Group">
<choose>
<when test="id == null">
INSERT INTO myapp_group (name, description)
VALUES
(#{username}, #{password});
</when>
<otherwise>
UPDATE myapp_group set name=#{name}, description=#{description}
where id=#{id};
</otherwise>
</choose>
<if test="users != null">
create temporary table tmpnewgroups (group_id integer, user_id integer);
insert into tmpnewgroups (group_id, user_id) values (
<foreach collection="users" item="user" open="" close="" separator="),()">
#{id},#{user.id}
</foreach>
);
insert into myapp_user_group(group_id, user_id)
select tmp.group_id, tmp.user_id
from tmpnewgroups tmp
left outer join myapp_user_group ug
on ug.group_id = tmp.group_id and ug.user_id = tmp.user_id
where ug.group_id is null;
delete from myapp_user_group
where group_id = #{id} and user_id not in (select user_id from tmpnewgroups);
</if>
</insert>
这确实按预期工作(插入/更新组,将用户集合保存为数据库中的关系)。但我真的不觉得这是最佳实践。制作应用程序以便我可以在需要时切换到 hibernate 状态,因此保存集合的逻辑最好应该在数据库层。 mybatis 中是否有一些我不知道的“魔法”可以简化这样的操作?
关于如何改进这个的任何想法?还是我应该重新考虑应用程序设计并在模型中进一步处理集合?
最佳答案
您的 saveGroup 数据映射操作的第二部分确实是重新考虑您的应用程序设计的一个理由。将内存中的用户集合保存到一个临时表中,以便将其与持久化表进行比较,以便插入和删除增量是一项相当繁重的操作,如果只需要更新组的名称或描述,则根本没有必要,即当没有增量时。是否属于这种情况可以由数据库服务器(您当前的解决方案)或数据库客户端(您的应用程序)决定。
除了组和可能是用户需要首次插入的情况外,如果您希望您的应用程序决定是否需要更新链接表,那么您的应用程序需要知道用户集合是否自从从数据库中检索后已更改。不幸的是,MyBatis 不会帮助您的应用程序做到这一点。
看,与 Hibernate 相比,MyBatis 很高兴地不知道你的对象和它们在 MyBatis 完成它的工作后携带的状态,这是数据映射,而不是对象关系映射。 Hibernate 可以自动检测对象的所谓脏状态,而 MyBatis 不能,因为这从来都不是其工作描述的一部分。因此,您只能使用自己的设备。
一个 super 简单的方法是在选择后存储用户的哈希码,并使用名为 isUserDirty()
的方法检查该哈希码是否已更改。 .您可以使用 <if test="isUserDirty">
在您的映射中简单地测试该条件。 .这当然不是一种非常通用的方法,并且取决于体面的 hashCode() 实现。看看 answer leonbloy 的类似问题以获得更通用的方法。当然,这可能还是有点太简单了,尤其是当我们谈论多对多关系时。哪种方法最好取决于您的情况。
现在你应该知道该怎么做了。祝你好运!
PS 而不是插入和删除增量,我会建议一个简单的覆盖:在事务中删除所有然后插入所有。您的临时表策略是一种优化策略,实际上可能根本不会提高数据库的性能,实际上我的猜测是它可能会使情况变得更糟。如果您已正确描述此策略并知道自己在做什么,则可以忽略此后记。
关于java - 使用 mybatis 保存/更新集合,常见的做法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15224992/
我尝试根据表单元素的更改禁用/启用保存按钮。但是,当通过弹出按钮选择更改隐藏输入字段值时,保存按钮不受影响。 下面是我的代码。我正在尝试序列化旧的表单值并与更改后的表单值进行比较。但我猜隐藏的字段值无
我正在尝试保存模型的实例,但我得到了 Invalid EmbeddedDocumentField item (1) 其中 1 是项目的 ID(我认为)。 模型定义为 class Graph(Docum
我有一个非常奇怪的问题......在我的 iPhone 应用程序中,用户可以打开相机胶卷中的图像,在我的示例中 1920 x 1080 像素 (72 dpi) 的壁纸。 现在,想要将图像的宽度调整为例
目前,我正在使用具有排序/过滤功能的数据表成功地从我的数据库中显示图像元数据。在我的数据表下方,我使用第三方图像覆盖流( http://www.jacksasylum.eu/ContentFlow/
我的脚本有问题。我想按此顺序执行以下步骤: 1. 保存输入字段中的文本。 2. 删除输入字段中的所有文本。 3. 在输入字段中重新加载之前删除的相同文本。 我的脚本的问题是 ug()- 函数在我的文本
任何人都可以帮助我如何保存多对多关系吗?我有任务,用户可以有很多任务,任务可以有很多用户(多对多),我想要实现的是,在更新表单中,管理员可以将多个用户分配给特定任务。这是通过 html 多选输入来完成
我在 Tensorflow 中训练了一个具有批归一化的模型。我想保存模型并恢复它以供进一步使用。批量归一化是通过 完成的 def batch_norm(input, phase): retur
我遇到了 grails 的问题。我有一个看起来像这样的域: class Book { static belongsTo = Author String toString() { tit
所以我正在开发一个应用程序,一旦用户连接(通过 soundcloud),就会出现以下对象: {userid: userid, username: username, genre: genre, fol
我正在开发一个具有多选项卡布局的 Angular 7 应用程序。每个选项卡都包含一个组件,该组件可以引用其他嵌套组件。 当用户选择一个新的/另一个选项卡时,当前选项卡上显示的组件将被销毁(我不仅仅是隐
我尝试使用 JEditorPane 进行一些简单的文本格式化,但随着知识的增长,我发现 JTextPane 更容易实现并且更强大。 我的问题是如何将 JTextPane 中的格式化文本保存到文件?它应
使用 Docker 相当新。 我为 Oracle 11g Full 提取了一个图像。创建了一个数据库并将应用程序安装到容器中。 正确配置后,我提交了生成 15GB 镜像的容器。 测试了该图像的新容器,
我是使用 Xcode 和 swift 的新手,仍在学习中。我在将核心数据从实体传递到文本字段/标签时遇到问题,然后用户可以选择编辑和保存记录。我的目标是,当用户从 friendslistViewCon
我正在用 Java 编写 Android 游戏,我需要一种可靠的方法来快速保存和加载应用程序状态。这个问题似乎适用于大多数 OO 语言。 了解我需要保存的内容:我正在使用策略模式来控制我的游戏实体。我
我想知道使用 fstream 加载/保存某种结构类型的数组是否是个好主意。注意,我说的是加载/保存到二进制文件。我应该加载/保存独立变量,例如 int、float、boolean 而不是结构吗?我这么
我希望能够将 QNetworkReply 保存到 QString/QByteArray。在我看到的示例中,它们总是将流保存到另一个文件。 目前我的代码看起来像这样,我从主机那里得到一个字符串,我想做的
我正在创建一个绘图应用程序。我有一个带有 Canvas 的自定义 View ,它根据用户输入绘制线条: class Line { float startX, startY, stopX, stop
我有 3 个 Activity 第一个 Activity 调用第二个 Activity ,第二个 Activity 调用第三个 Activity 。 第二个 Activity 使用第一个 Activi
我想知道如何在 Xcode 中保存 cookie。我想使用从一个网页获取的 cookie 并使用它访问另一个网页。我使用下面的代码登录该网站,我想保存从该连接获得的 cookie,以便在我建立另一个连
我有一个 SQLite 数据库存储我的所有日历事件,建模如下: TimerEvent *Attributes -date -dateForMark -reminder *Relat
我是一名优秀的程序员,十分优秀!