iBatis2 级联保存
 
目前在做一个项目,因为忙,很少关注开发者的代码,今天突然发现所有的人的都还不会写级联保存,太失望了。
 
这是我给出的一个例子:
 
MySQL 5.5.21
ibatis 2.3.x
Spring 3.1
 
1、数据脚本
CREATE TABLE `test_dept` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `dept_name` varchar(24) NOT NULL COMMENT '部门名称',
    `createtime` datetime NOT NULL COMMENT '创建时间',
    `updatetime` datetime NOT NULL COMMENT '更新时间',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=gbk COMMENT='部门(测试)'

CREATE TABLE `test_person` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `person_name` varchar(24) NOT NULL COMMENT '人员名',
    `dept_id` bigint(20) NOT NULL COMMENT '部门ID',
    `createtime` datetime NOT NULL COMMENT '创建时间',
    `updatetime` datetime NOT NULL COMMENT '更新时间',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk COMMENT='员工(测试)'
 
2、java代码
 
/**
* 部门(测试)
*
* @author leizhimin
*/

public class Test_dept extends GenericEntity implements Serializable {
        private String dept_name;                    //部门名称
        private java.sql.Timestamp createtime;                    //创建时间
        private java.sql.Timestamp updatetime;                    //更新时间

        private List<Test_person> personList= new ArrayList<Test_person>(0);
 
/**
* 员工(测试)
*
* @author leizhimin
*/

public class Test_person extends GenericEntity implements Serializable {
        private String person_name;                    //人员名
        private long dept_id;                    //部门ID
        private java.sql.Timestamp createtime;                    //创建时间
        private java.sql.Timestamp updatetime;                    //更新时间
 
package com.asiainfo.tdmc.service;

import com.asiainfo.tdmc.entity.Test_dept;
import com.asiainfo.tdmc.entity.Test_person;

import java.util.List;
import java.util.Map;

/**
* Created by IntelliJ IDEA.
*
* @author leizhimin 2012-03-16 09:57
*/

public interface TestSV {
        Test_dept saveTest_dept(Test_dept test_dept);

        Test_dept updateTest_dept(Test_dept test_dept);

        void deleteTest_dept(long id);

        List<Test_dept> queryTest_dept(Map<String,Object> map);


        Test_person saveTest_person(Test_person test_person);

        Test_person updateTest_person(Test_person test_person);

        void deleteTest_person(long id);

        List<Test_person> queryTest_person(Map<String,Object> map);


}
 
package com.asiainfo.tdmc.service.impl;

import com.asiainfo.tdmc.dao.Test_deptDAO;
import com.asiainfo.tdmc.dao.Test_personDAO;
import com.asiainfo.tdmc.entity.Test_dept;
import com.asiainfo.tdmc.entity.Test_person;
import com.asiainfo.tdmc.service.TestSV;

import java.util.List;
import java.util.Map;

/**
* Created by IntelliJ IDEA.
*
* @author leizhimin 2012-03-16 10:02
*/

public class TestSVImpl implements TestSV{
        private Test_deptDAO test_deptDAO;
        private Test_personDAO test_personDAO;
        
        @Override
        public Test_dept saveTest_dept(Test_dept test_dept) {
                test_dept =    test_deptDAO.insert(test_dept);
//                if(true) throw new RuntimeException();
                for (Test_person person : test_dept.getPersonList()) {
                        person.setDept_id(test_dept.getId());
                }
                test_personDAO.batchInsert(test_dept.getPersonList());
                return test_dept;
        }

        @Override
        public Test_dept updateTest_dept(Test_dept test_dept) {
                return test_deptDAO.update(test_dept);
        }

        @Override
        public void deleteTest_dept(long id) {
                test_deptDAO.delete(id);
        }

        @Override
        public List<Test_dept> queryTest_dept(Map<String, Object> map) {
                return test_deptDAO.query(map);
        }

        @Override
        public Test_person saveTest_person(Test_person test_person) {
                return test_personDAO.insert(test_person);
        }

        @Override
        public Test_person updateTest_person(Test_person test_person) {
                return test_personDAO.update(test_person);
        }

        @Override
        public void deleteTest_person(long id) {
                test_personDAO.delete(id);
        }

        @Override
        public List<Test_person> queryTest_person(Map<String, Object> map) {
                return test_personDAO.query(map);
        }

        public void setTest_deptDAO(Test_deptDAO test_deptDAO) {
                this.test_deptDAO = test_deptDAO;
        }

        public void setTest_personDAO(Test_personDAO test_personDAO) {
                this.test_personDAO = test_personDAO;
        }
}
 
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
                "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<!-- test_dept: 部门(测试)-->
<sqlMap namespace="Test_dept">
        <typeAlias alias="Test_dept" type="com.asiainfo.tdmc.entity.Test_dept"/>
        <resultMap id="result_base" class="Test_dept">
                <result property="id" column="id"/>
                <result property="dept_name" column="dept_name"/>
                <result property="createtime" column="createtime"/>
                <result property="updatetime" column="updatetime"/>
        </resultMap>
        <resultMap id="result" class="Test_dept" extends="result_base">
                <result property="personList" column="id" select="Test_person.load"/>
        </resultMap>

        <insert id="insert" parameterClass="Test_dept">
                insert into test_dept(
                        dept_name,
                        createtime,
                        updatetime
                ) values(
                        #dept_name#,
                        now(),
                        now()
                )
                <selectKey keyProperty="id" resultClass="long">
                        select LAST_INSERT_ID()
                </selectKey>
        </insert>

        <update id="update" parameterClass="Test_dept">
                update test_dept set
                        dept_name=#dept_name#,
                        updatetime=now()
                where id = #id#
        </update>

        <delete id="delete" parameterClass="long">
                delete from test_dept where id=#value#
        </delete>

        <select id="load" parameterClass="long" resultClass="Test_dept" resultMap="Test_dept.result_base">
                select * from test_dept where id=#value#
        </select>

        <sql id="sql_query_where">
                <dynamic prepend="where">
                        <isNotEmpty prepend="and" property="dept_name">
                                dept_name=#dept_name#
                        </isNotEmpty>
                        <isNotEmpty prepend="and" property="createtime">
                                createtime=#createtime#
                        </isNotEmpty>
                        <isNotEmpty prepend="and" property="updatetime">
                                updatetime=#updatetime#
                        </isNotEmpty>
                </dynamic>
        </sql>

        <select id="query" parameterClass="map" resultMap="Test_dept.result">
                select * from test_dept
                <include refid="sql_query_where"/>
                <dynamic prepend="">
                        <isNotEmpty property="sortColumns">
                                order by #sortColumns#
                        </isNotEmpty>
                </dynamic>
        </select>

        <select id="count" parameterClass="map" resultClass="int">
                select count(1) from test_dept
                <include refid="sql_query_where"/>
        </select>
</sqlMap>
 
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
                "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<!-- test_person: 员工(测试)-->
<sqlMap namespace="Test_person">
        <typeAlias alias="Test_person" type="com.asiainfo.tdmc.entity.Test_person"/>
        <resultMap id="result_base" class="Test_person">
                <result property="id" column="id"/>
                <result property="person_name" column="person_name"/>
                <result property="dept_id" column="dept_id"/>
                <result property="createtime" column="createtime"/>
                <result property="updatetime" column="updatetime"/>
        </resultMap>

        <insert id="insert" parameterClass="Test_person">
                insert into test_person(
                        person_name,
                        dept_id,
                        createtime,
                        updatetime
                ) values(
                        #person_name#,
                        #dept_id#,
                        now(),
                        now()
                )
                <selectKey keyProperty="id" resultClass="long">
                        select LAST_INSERT_ID()
                </selectKey>
        </insert>

        <update id="update" parameterClass="Test_person">
                update test_person set
                        person_name=#person_name#,
                        dept_id=#dept_id#,
                        updatetime=now()
                where id = #id#
        </update>

        <delete id="delete" parameterClass="long">
                delete from test_person where id=#value#
        </delete>

        <select id="load" parameterClass="long" resultClass="Test_person" resultMap="Test_person.result_base">
                select * from test_person where id=#value#
        </select>

        <sql id="sql_query_where">
                <dynamic prepend="where">
                        <isNotEmpty prepend="and" property="person_name">
                                person_name=#person_name#
                        </isNotEmpty>
                        <isNotEmpty prepend="and" property="dept_id">
                                dept_id=#dept_id#
                        </isNotEmpty>
                        <isNotEmpty prepend="and" property="createtime">
                                createtime=#createtime#
                        </isNotEmpty>
                        <isNotEmpty prepend="and" property="updatetime">
                                updatetime=#updatetime#
                        </isNotEmpty>
                </dynamic>
        </sql>

        <select id="query" parameterClass="map" resultMap="Test_person.result_base">
                select * from test_person
                <include refid="sql_query_where"/>
                <dynamic prepend="">
                        <isNotEmpty property="sortColumns">
                                order by #sortColumns#
                        </isNotEmpty>
                </dynamic>
        </select>

        <select id="count" parameterClass="map" resultClass="int">
                select count(1) from test_person
                <include refid="sql_query_where"/>
        </select>
</sqlMap>
 
3、测试类
package com.asiainfo.tdmc.service.impl;

import com.asiainfo.tdmc.common.ApplicationContextUtils;
import com.asiainfo.tdmc.entity.Test_dept;
import com.asiainfo.tdmc.entity.Test_person;
import com.asiainfo.tdmc.service.TestSV;

/**
* Created by IntelliJ IDEA.
*
* @author leizhimin 2012-03-16 10:07
*/

public class Test {

        /**
         * @param args
         */

        public static void main(String[] args) {
                TestSV testSV = (TestSV) ApplicationContextUtils.getApplicationContext().getBean("testSV");
                
                Test_dept dept = new Test_dept();
                dept.setDept_name("dept1");
                Test_person person1 = new Test_person();
                person1.setPerson_name("zhangsan");
                Test_person person2 = new Test_person();
                person2.setPerson_name("lisi");

                dept.getPersonList().add(person1);
                dept.getPersonList().add(person2);

                //级联保存
                testSV.saveTest_dept(dept);

                System.out.println(dept.getId());
        }
}
 
4、说明
 
级联保存是在:
        public Test_dept saveTest_dept(Test_dept test_dept) {
                test_dept =    test_deptDAO.insert(test_dept);
                //级联保存
                for (Test_person person : test_dept.getPersonList()) {
                        person.setDept_id(test_dept.getId());
                }
                test_personDAO.batchInsert(test_dept.getPersonList());
                return test_dept;
        }
 
 
级联保存的目的是为了数据一致,业务完整,操作便捷。