2017-08-07 4 views
0

を使用して、INSERT文の中にサブINSERT文を実行するので、私は次のような構造MyBatisの

int id 
String name 
Array tags 

を持っており、私が最初に挿入したいと思いデータベースに挿入しようとしているオブジェクトを持っています次の表

CREATE TABLE foo (
id number(20) PRIMARY KEY, 
name varchar2(50) NOT NULL 
); 

このテーブルにアレイに二つの列

CREATE TABLE fooTags (
id number(20) PRIMARY KEY, 
fooId number(20), //foreign key to foo. I don't know what the sql is for that. 
tagName varchar2(50) 
); 

H owは最初の挿入作業によって作成されたIDをとるサブ挿入を実行するでしょうか?私はSELECTが必要と仮定したいと思いますが、必要な情報を各オブジェクトの適切な領域に挿入するように指示する方法は不明です。

+0

はあなたが手順にしたいですか? –

+0

@mehmetsahinもしそれがmybatisで動作するのか、それとも簡単に変換されるのでしょうか?正直言って、この特定の行動のベストプラクティスがわからない。 – canadiancreed

+0

Foo.idとFooTags.idはシーケンスではありません。あなたはそれらを渡すと思いますか? –

答えて

1

私は2つの手順を書いた。

idsのseq名を知ることができます。

create or replace procedure FOO_INSERT(foo_name in varchar2, FooTags_tagName in varchar2) 
is 
foo_seq_val number; 
footag_seq_val number; 
begin 
select foo_seq.nextval into foo_seq_val from dual;  
insert into foo(id,name) values (foo_seq_val, foo_name); 
select footag_seq.nextval into footag_seq_val from dual; 
insert into footags (id,fooid,tagName) values(footag_seq_val,foo_seq_val,FooTags_tagName); 
commit; 
end; 

IDのseq名がわからない場合は、

create or replace procedure FOO_INSERT_T(foo_name in varchar2, FooTags_tagName in varchar2) 
is 
foo_seq_val number; 
begin 
insert into foo_T(name) values (foo_name); 
select id into foo_seq_val from FOO_T where name =foo_name; 
insert into footags_T (fooid,tagName) values(foo_seq_val,FooTags_tagName); 
commit; 
end; 

idsを渡すと、

insert into foo (id, name) values (123,'foo_name'); 
insert into footags (id,fooid,tagname) select 444,id, 'tag_name' from foo ; 
commit; 

2番目の手順では、foo_T.nameの値が一意であるか、各行の他の値によってIDが一意であると仮定します。あなたの選択の末尾にあなたの選択の末尾に置くことができますand ... and ..

それぞれCOMMITが表示されます。エラーがある場合は、foo_tablefooTags_tableのすべての挿入をロールバックします。これは正確です。

1

私の解決策:2つのINSERTクエリ、親オブジェクト(FOO表)の最初の、そして彼のタグ(fooTagsテーブル)のための第二:

<insert id="fooInsert" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> 
    INSERT INTO foo (name) VALUES (#{name}) 
</insert> 

<insert id="fooTagsInsert"> 
    INSERT INTO fooTags ("fooId", "tagName") VALUES 
    <foreach item="tag" collection="tags" separator=","> 
     (#{id}, #{tag}) 
    </foreach> 
</insert> 

属性 "useGeneratedKeys"、 "keyProperty" と " keyColumn "は、JDBCドライバがgetGeneratedKeys関数をサポートしている場合に、データベースから新たに生成されたキーを再ロードするために使用されます。あるいは、selectクエリを使用してIDをリロードする必要があります。詳細情報:http://www.mybatis.org/mybatis-3/sqlmap-xml.html#insert_update_and_delete

タグは、タグ名を繰り返し処理するために "foreach"を使用します(この場合、文字列配列を使用しましたが、オブジェクトでも可能です)。 「内部」挿入部は、「foo」オブジェクトの「id」と、反復文字列「タグ」を参照します。オブジェクトの場合、 "tag.name"という名前の内部フィールドにアクセスできます。 Javaコードで

使用法:

Foo foo = new Foo(); 
foo.setName("James"); 
foo.setTags(new String[] {"one", "two", "three"}); 

fooMapper.fooInsert(foo); 
fooMapper.fooTagsInsert(foo); 

テーブル定義(PostgreSQLのでテスト):

CREATE TABLE public.foo (
    id numeric NOT NULL DEFAULT nextval('seq_foo_id'::regclass), 
    "name" varchar NULL, 
    CONSTRAINT foo_pk PRIMARY KEY (id) 
) 

CREATE TABLE public.footags (
    id varchar NOT NULL DEFAULT nextval('seq_foo_id'::regclass), 
    "fooId" numeric NULL, 
    "tagName" varchar NULL, 
    CONSTRAINT footags_pk PRIMARY KEY (id), 
    CONSTRAINT footags_foo_fk FOREIGN KEY ("fooId") REFERENCES public.foo(id) 
)