在前面的章节中,我们学习了一对多,多对一的关系,现在我们来看看 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