Mybatis 多对多(易百教程)

mybatis3.0 添加了association和collection标签专门用于对多个相关实体类数据进行级联查询,但仍不支持多个相关实体类数据的级联保存和级联删除操作。因此在进行实体类多对多映射表设计时,需要专门建立一个关联对象类对相关实体类的关联关系进行描述。下文将以“User”和“Group"两个实体类之间的多对多关联映射为例进行CRUD操作。

1、应用场景

假设项目中存在用户和用户组,从一个用户读取出它所在的用户组,从一个用户组也知道这个组内的所有用户信息。

2、先做一些准备工作

我们首先在创建一个 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‘, ‘yiibai‘, ‘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中。

2、创建表对应的 JavaBean 对象

这个例子中,我们需要在包 com.yiibai.pojo 下创建三个类,它们分别是: User.java 、Group.java 和 UserGroup.java,让我们一个一个地来看它们的代码,User.java 类的代码如下:

package com.yiibai.pojo;

import java.util.List;

/**
 * @describe: User
 * @author: Yiibai
 * @version: V1.0
 * @copyright http://www.yiibai.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.yiibai.pojo;

import java.util.List;

/**
 * @describe: Group
 * @author: Yiibai
 * @version: V1.0
 * @copyright http://www.yiibai.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.yiibai.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;
	}

}

3、配置文件

在这一章节中,要用到的配置文件有四个,一个是 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.yiibai.pojo.User" />
		<typeAlias alias="UserGroup" type="com.yiibai.pojo.UserGroup" />
		<typeAlias alias="Group" type="com.yiibai.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/yiibai" />
				<property name="username" value="root" />
				<property name="password" value="" />
			</dataSource>
		</environment>
	</environments>

	<mappers>
		<!-- // power by http://www.yiibai.com -->
		<mapper resource="com/yiibai/maper/UserMaper.xml" />
		<mapper resource="com/yiibai/maper/GroupMaper.xml" />
		<mapper resource="com/yiibai/maper/UserGroupMaper.xml" />
	</mappers>
</configuration>

Group.java 对应的配置文件 src/com/yiibai/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.yiibai.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.yiibai.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/yiibai/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.yiibai.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.yiibai.maper.UserGroupMaper.getGroupsByUserId"/>
	</resultMap>

	<select id="getUser" resultMap="resultUser" parameterType="int">
		SELECT *
		FROM user
		WHERE id=#{id}
	</select>
</mapper>

UserGroup.java 对应的配置文件 src/com/yiibai/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.yiibai.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类。

4、测试程序运行

到这里,整个工作准备得已经差不多了,我们创建一个主类来测试上面程序,在 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.yiibai.maper.GroupMaper;
import com.yiibai.maper.UserGroupMaper;
import com.yiibai.maper.UserMaper;
import com.yiibai.pojo.Group;
import com.yiibai.pojo.User;
import com.yiibai.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	yiibai
	:2	User-name-1

原文地址:https://www.cnblogs.com/pingxin/p/p00014.html

时间: 2024-10-27 05:38:30

Mybatis 多对多(易百教程)的相关文章

易百教程人工智能python修正-人工智能监督学习(回归)

回归是最重要的统计和机器学习工具之一. 我们认为机器学习的旅程从回归开始并不是错的. 它可以被定义为使我们能够根据数据做出决定的参数化技术,或者换言之,允许通过学习输入和输出变量之间的关系来基于数据做出预测. 这里,依赖于输入变量的输出变量是连续值的实数. 在回归中,输入和输出变量之间的关系很重要,它有助于我们理解输出变量的值随输入变量的变化而变化. 回归常用于预测价格,经济,变化等. 在Python中构建回归器 在本节中,我们将学习如何构建单一以及多变量回归器. 线性回归器/单变量回归器 让我

Mybatis与Spring集成(易百教程)

整个Mybatis与Spring集成示例要完成的步骤如下: 1.示例功能描述 2.创建工程 3.数据库表结构及数据记录 4.实例对象 5.配置文件 6.测试执行,输出结果 1.示例功能描述 在本示例中,需要完成这样的一个简单功能,即,指定一个用户(ID=1),查询出这个用户的基本信息,并关联查询这个用户的所有订单. 2.创建工程 首先创建一个工程的名称为:mybatis07-spring,在 src 源代码目录下建立文件夹 config,并将原来的 mybatis 配置文件 Configurat

MyBatis整合Spring MVC(易百教程)

MyBatis是ibatis的升级版,作为hibernate的老对手,它是一个可以自定义SQL.存储过程和高级映射的持久层框架.与Hibernate 的主要区别就是 Mybatis 是半自动化的,而 Hibernate 是全自动的,所以当应用需求越来越复杂的时候,自动化的 SQL 显得比较笨拙.经常搭框架的人应该都清楚,框架搭建的核心就是配置文件. 在这里我们需要创建 web 工程.今天将直接用 mybatis与Spring mvc 的方式集成起来,源码在本文结尾处下载.主要有以下几个方面的配置

Struts2 类型转换(易百教程)

在HTTP请求中的一切都被视为一个String由协议.这包括数字,布尔值,整数,日期,小数和一切.每一件事情是一个字符串,将根据HTTP.然而,Struts类可以有任何数据类型的属性.Struts的自动装配属性? Struts使用了多种类型转换器在幕后做繁重.例如,如果Action类的属性有一个整数,Struts的自动转换请求参数的整数属性没有做任何事情.默认情况下,Struts的一些类型转换器.下面列出了他们中的一些,如果您正在使用其中任何一个,那么你有什么可担心的: Integer, Flo

易百教程人工智能python修正-人工智能数据准备-标记数据

我们已经知道,某种格式的数据对于机器学习算法是必需的. 另一个重要的要求是,在将数据作为机器学习算法的输入发送之前,必须正确标记数据. 例如,如果所说的分类,那么数据上会有很多标记. 这些标记以文字,数字等形式存在.与sklearn中的机器学习相关的功能期望数据必须具有数字标记. 因此,如果数据是其他形式,那么它必须转换为数字. 这个将单词标签转换为数字形式的过程称为标记编码. 标记编码步骤 按照以下步骤在Python中对数据标记进行编码 - 第1步 - 导入有用的软件包 如果使用Python,

mybatis多对一关联

mybatis多对一关联查询实现 1.定义实体 定义实体的时候需要注意,若是双向关联,就是说双方的属性中都含有对方对象作为域属性出现, 那么在写toString()方法时需要注意,只让某一方输出即可,不要让双方的toString()都输出对方, 这样会形成递归调用,程序会出错,报堆栈溢出. Country实体类 Minsiter 实体类 2.数据库设计 a) country数据库 b) minsiter数据库 3.DAO层设计 4.service层设计 5.impl实现类 6.Controlle

Python CGI编程(转自易百)

Python CGI编程 Python的CGI编程,公共网关接口或CGI,Web服务器和一个自定义的脚本之间交换信息是一组定义的标准. 什么是CGI ? 公共网关接口或CGI,Web服务器和一个自定义的脚本之间交换信息是是一组定义的标准.. CGI规范在由NCSA和NCSA定义的CGI保持如下: 公共网关接口或CGI,如HTTP服务器信息服务器的标准接口是外部网关方案. 当前版本CGI/1.1和CGI/1.2. 网页浏览 理解CGI的概念,让我们看看会发生什么,当我们点击一个超链接到浏览特定网页

mybatis 多对多 处理

下面的例子让新手看不错.可以改进的一点是 1.不必建立 关联对象实体,可以用map传递两个id进去 2.文章的resultMap 继承和 查询配置 比较清楚,可以借鉴 mybatis3.0添加了association和collection标签专门用于对多个相关实体类数据进行级联查询,但仍不支持多个相关实体类数据的级联保存和级联删除操作.因此在进行实体类多对多映射表设计时,需要专门建立一个关联对象类对相关实体类的关联关系进行描述.下文将以"User"和"Group"两

mybatis多对多关联查询——(十)

1.需求 查询用户及用户购买商品信息. 2     sql语句 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表: orders.orderdetail.items SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.