我的问题是坚持两个具有1:n关系的类:
public class DayRecord {
private Long id;
private List<TimeRecord> timeRecordsToday = new ArrayList<TimeRecord>(4);
...
}
public class TimeRecord {
private Long id;
...
}
因此,在代码中,DayRecord知道TimeRecord。
create table DAY_RECORDS (
id int primary key,
);
create table TIME_RECORDS (
id int primary key,
day_record_id int not null,
foreign key (day_record_id) references DAY_RECORDS (id)
);
在数据库中,TimeRecord知道DayRecord。
我可以一步保存DayRecord及其所有TimeRecords吗?
在Hibernate中,我可以设置逆映射,只保存DayRecord,它的所有TimeRecords也会被保存。使用MyBatis,我试图将这些类彼此独立保存:
<mapper
namespace="de.stevenschwenke.java.javafx.xyz.DayRecordMapper">
<insert id="insertDayRecord"
parameterType="de.stevenschwenke.java.javafx.xyz.DayRecord">
insert into DAY_RECORDS (id) values (NEXT VALUE FOR DAY_RECORDS_SEQ);
</insert>
</mapper>
<mapper
namespace="de.stevenschwenke.java.javafx.xyz.TimeRecordMapper">
<insert id="insertTimeRecord"
parameterType="de.stevenschwenke.java.javafx.xyz.TimeRecord">
insert into TIME_RECORDS (id) values (NEXT VALUE FOR TIME_RECORDS_SEQ);
</insert>
</mapper>
但是如何在TimeRecord中保存DayRecord-ID?
想法:
保存这两个对象的最佳方法是什么?谢谢你的帮助!
答案 0 :(得分:2)
正如jdevelop已经提到的,MyBatis只是一个SQL包装器。因为SQL不提供插入两个具有关系的对象的方法,所以MyBatis也不能这样做。
所以这是我的解决方法:正如我所提到的,我不想通过让TimeRecord了解DayRecord来添加循环依赖。所以我创建了一个仅用于插入TimeRecords的包装类:
public class TimeRecordInsertWrapper {
public Long id;
public int hours;
public long dayRecordId;
[constructor/getter/setter omited but there with public access modifier]
}
首先,我存储DayRecord并获取它的ID。然后我创建包装器对象并存储TimeRecords:
public long insertDayRecord(DayRecord newRecord) {
SqlSession session = sqlSessionFactory.openSession();
try {
session.insert(
"de.stevenschwenke.java.javafx.xyz.DayRecordMapper.insertDayRecord",
newRecord);
for (TimeRecord tr : newRecord.getTimeRecordsToday()) {
TimeRecordInsertWrapper wrapper = new TimeRecordInsertWrapper(tr.getHours(), newRecord.getId());
session.insert("de.stevenschwenke.java.javafx.xyz.TimeRecordMapper.insertTimeRecord",
wrapper);
}
return newRecord.getId();
} finally {
session.commit();
session.close();
}
}
这样,我可以使用我的单向对象模型并在数据库中使用“正确”的映射。
答案 1 :(得分:1)
Mybatis只是SQL映射框架,它允许您从Java代码中抽象出SQL代码,或多或少。他们假装看起来像最新版本的Hibernate,但这导致了XML中奇怪的结构。
我建议存储DayRecord并从selectKey获取它,然后在后续的mapper调用中使用该ID。这是映射器内部实际发生的情况,但复杂的XML意味着内置的复杂FSM。所以保持简单,使用myBatis安全,或者使用Hibernate。
更好的是,您可以为任务定义自定义DAO接口,然后您可以设置某种具有@Transactional属性的服务层。这需要mybatis-guice,但它确实很好,您不需要处理代码中的事务(它们是声明性的)。