在前面的章节中,我们学习了一对多,多对一的关系,现在我们来看看 mybatis 中的多对多应用。
mybatis3.0 添加了association和collection标签专门用于对多个相关实体类数据进行级联查询,但仍不支持多个相关实体类数据的级联保存和级联删除操作。因此在进行实体类多对多映射表设计时,需要专门建立一个关联对象类对相关实体类的关联关系进行描述。下文将以“user”和“group"两个实体类之间的多对多关联映射为例进行crud操作。
假设项目中存在用户和用户组,从一个用户读取出它所在的用户组,从一个用户组也知道这个组内的所有用户信息。
我们首先在创建一个 java 工程,工程名称为:mybatis06-many2many(下载),还需要创建三张表,它们分别是用户表 user,用户组表 group 和 用户组映射表 user_group ,一个户用户可以在多个用户组中,一个用户组中有多个用户。项目工程结构如下:
user表的结构和数据:
create table `user` ( `id` int(10) unsigned not null auto_increment, `username` varchar(64) not null default '', `mobile` varchar(16) not null default '', primary key (`id`) ) engine=innodb auto_increment=3 default charset=utf8; -- ---------------------------- -- records of user -- ---------------------------- insert into `user` values ('1', 'h3', '13838009988'); insert into `user` values ('2', 'user-name-1', '13838009988');
用户组 group 表的结构和数据:
create table `group` ( `group_id` int(10) unsigned not null auto_increment, `group_name` varchar(254) not null default '', primary key (`group_id`) ) engine=innodb auto_increment=3 default charset=utf8; -- ---------------------------- -- records of group -- ---------------------------- insert into `group` values ('1', 'group-1'); insert into `group` values ('2', 'group-2');用户组映射表 user_group 的结构和数据:
create table `user_group` ( `user_id` int(10) unsigned not null default '0', `group_id` int(10) unsigned not null ) engine=innodb default charset=utf8; -- ---------------------------- -- records of user_group -- ---------------------------- insert into `user_group` values ('1', '1'); insert into `user_group` values ('2', '1'); insert into `user_group` values ('1', '2');
从上面应该看出,用户id为1同时在用户组id为 1 和 2 中,而用户id为 2 仅在一个用户组id为1中。
这个例子中,我们需要在包 com.h3.pojo 下创建三个类,它们分别是: user.java 、group.java 和 usergroup.java,让我们一个一个地来看它们的代码,user.java 类的代码如下:
package com.h3.pojo; import java.util.list; /** * @describe: user * @author: h3 * @version: v1.0 * @copyright http://www.h3.com */ public class user { private int id; private string username; private string mobile; private list<group> groups; public list<group> getgroups() { return groups; } public void setgroups(list<group> groups) { this.groups = groups; } public int getid() { return id; } public void setid(int id) { this.id = id; } public string getusername() { return username; } public void setusername(string username) { this.username = username; } public string getmobile() { return mobile; } public void setmobile(string mobile) { this.mobile = mobile; } }group.java 类的代码如下:
package com.h3.pojo; import java.util.list; /** * @describe: group * @author: h3 * @version: v1.0 * @copyright http://www.h3.com */ public class group { private int groupid; private string groupname; private list<user> users; public list<user> getusers() { return users; } public void setusers(list<user> users) { this.users = users; } public int getgroupid() { return groupid; } public void setgroupid(int groupid) { this.groupid = groupid; } public string getgroupname() { return groupname; } public void setgroupname(string groupname) { this.groupname = groupname; } }usergroup.java 类(用户和用户组的关系映射)的代码如下:
package com.h3.pojo; public class usergroup { private int userid; private int groupid; public int getuserid() { return userid; } public void setuserid(int userid) { this.userid = userid; } public int getgroupid() { return groupid; } public void setgroupid(int groupid) { this.groupid = groupid; } }
在这一章节中,要用到的配置文件有四个,一个是 mybatis 的主配置文件:src/config/configure.xml ,另外就是上面三个bean类对应的配置文件,如,user.java 对应的配置文件 user.xml,等,我们先来看看 src/config/configure.xml,其详细配置信息如下:
<?xml version="1.0" encoding="utf-8"?> <!doctype configuration public "-//mybatis.org//dtd config 3.0//en" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typealiases> <typealias alias="user" type="com.h3.pojo.user" /> <typealias alias="usergroup" type="com.h3.pojo.usergroup" /> <typealias alias="group" type="com.h3.pojo.group" /> </typealiases> <environments default="development"> <environment id="development"> <transactionmanager type="jdbc" /> <datasource type="pooled"> <property name="driver" value="com.mysql.jdbc.driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/h3" /> <property name="username" value="root" /> <property name="password" value="" /> </datasource> </environment> </environments> <mappers> <!-- // power by http://www.h3.com --> <mapper resource="com/h3/maper/usermaper.xml" /> <mapper resource="com/h3/maper/groupmaper.xml" /> <mapper resource="com/h3/maper/usergroupmaper.xml" /> </mappers> </configuration>group.java 对应的配置文件 src/com/h3/maper/group.xml 的内容如下:
<?xml version="1.0" encoding="utf-8" ?> <!doctype mapper public "-//mybatis.org//dtd mapper 3.0//en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.h3.maper.groupmaper"> <parametermap type="group" id="parametergroupmap"> <parameter property="groupid"/> <parameter property="groupname"/> </parametermap> <insert id="insertgroup" parametermap="parametergroupmap"> insert into `group` (group_name) values(#{groupname}); </insert> <resultmap type="group" id="resultgroupmap_1"> <result property="id" column="id" /> <result property="groupname" column="group_name" /> <collection property="users" column="group_id" select="com.h3.maper.usergroupmaper.getusersbygroupid" /> </resultmap> <select id="getgroup" resultmap="resultgroupmap_1" parametertype="int"> select * from `group` where group_id=#{id} </select> </mapper>
user.java 对应的配置文件 src/com/h3/maper/user.xml 的内容如下:
<?xml version="1.0" encoding="utf-8" ?> <!doctype mapper public "-//mybatis.org//dtd mapper 3.0//en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.h3.maper.usermaper"> <parametermap type="user" id="parameterusermap"> <parameter property="id"/> <parameter property="username"/> <parameter property="mobile"/> </parametermap> <insert id="insertuser" parametermap="parameterusermap"> insert into user(username,mobile) values(#{username},#{mobile}); </insert> <resultmap type="user" id="resultuser"> <result property="id" column="group_id"/> <result property="name" column="name"/> <collection property="groups" column="id" select="com.h3.maper.usergroupmaper.getgroupsbyuserid"/> </resultmap> <select id="getuser" resultmap="resultuser" parametertype="int"> select * from user where id=#{id} </select> </mapper>usergroup.java 对应的配置文件 src/com/h3/maper/usergroup.xml 的内容如下:
<?xml version="1.0" encoding="utf-8" ?> <!doctype mapper public "-//mybatis.org//dtd mapper 3.0//en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.h3.maper.usergroupmaper"> <parametermap type="usergroup" id="parameterusergroupmap"> <parameter property="userid"/> <parameter property="groupid"/> </parametermap> <insert id="insertusergroup" parametermap="parameterusergroupmap"> insert into user_group(user_id, group_id) values(#{userid},#{groupid}) </insert> <!-- 根据一个用户组id,查看这个用户组下的所有用户 --> <resultmap type="user" id="resultusermap_2"> <result property="id" column="id"/> <result property="username" column="username"/> <result property="mobile" column="mobile"/> </resultmap> <select id="getusersbygroupid" resultmap="resultusermap_2" parametertype="int"> select u.*, ug.group_id from user u, user_group ug where u.id=ug.user_id and ug.group_id=#{group_id} </select> <!-- 根据一个用户id,查看这个用户所对应的组--> <resultmap type="group" id="resultgroupmap_2"> <result property="groupid" column="group_id"/> <result property="groupname" column="group_name"/> </resultmap> <select id="getgroupsbyuserid" resultmap="resultgroupmap_2" parametertype="int"> select g.*, u.user_id from group g, user_group u where g.group_id=u.group_id and u.user_id=#{user_id} </select> </mapper>
注:在上面的配置文件中,使用到了 <association>和 <clollection>标签,关联对应的 user 类和 group类。
到这里,整个工作准备得已经差不多了,我们创建一个主类来测试上面程序,在 src 下创建一个 main.java,代码如下:
import java.io.reader; import java.text.messageformat; import java.util.list; import org.apache.ibatis.io.resources; import org.apache.ibatis.session.sqlsession; import org.apache.ibatis.session.sqlsessionfactory; import org.apache.ibatis.session.sqlsessionfactorybuilder; import com.h3.maper.groupmaper; import com.h3.maper.usergroupmaper; import com.h3.maper.usermaper; import com.h3.pojo.group; import com.h3.pojo.user; import com.h3.pojo.usergroup; public class main { private static sqlsessionfactory sqlsessionfactory; private static reader reader; static { try { reader = resources.getresourceasreader("config/configure.xml"); sqlsessionfactory = new sqlsessionfactorybuilder().build(reader); } catch (exception e) { e.printstacktrace(); } } public static sqlsessionfactory getsession() { return sqlsessionfactory; } /** * @param args */ public static void main(string[] args) { // todo auto-generated method stub // testaddgroup(); // testadduser(); // testaddusergroup(); testgetgroupandusers(); } public static void testgetgroupandusers() { usergroup usergroup = new usergroup(); sqlsession session = sqlsessionfactory.opensession(); try { groupmaper groupmaper = session.getmapper(groupmaper.class); group group = groupmaper.getgroup(1); system.out.println("group => " + group.getgroupname()); list<user> users = group.getusers(); for (user user : users) { system.out.println("\t:" + user.getid() + "\t" + user.getusername()); } } finally { session.close(); } } public static void testaddusergroup() { usergroup usergroup = new usergroup(); usergroup.setgroupid(1); usergroup.setuserid(2); sqlsession session = sqlsessionfactory.opensession(); try { usergroupmaper usergroupmaper = session .getmapper(usergroupmaper.class); usergroupmaper.insertusergroup(usergroup); session.commit(); } finally { session.close(); } } public static void testadduser() { // todo auto-generated method stub sqlsession session = sqlsessionfactory.opensession(); try { user user = new user(); user.setusername("user-name-1"); user.setmobile("13838009988"); usermaper usermaper = session.getmapper(usermaper.class); usermaper.insertuser(user); session.commit(); // system.out.println(user.getgroupid()); } finally { session.close(); } } public static void testaddgroup() { // todo auto-generated method stub sqlsession session = sqlsessionfactory.opensession(); try { group group = new group(); group.setgroupname("用户组-1"); groupmaper groupmapper = session.getmapper(groupmaper.class); groupmapper.insertgroup(group); session.commit(); system.out.println(group.getgroupid()); } finally { session.close(); } } }
运行上述程序,得出结果:
group => group-1 :1 h3 :2 user-name-1