有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如最常见到的多对一,一对多等。这些查询是如何处理的呢,这一讲就讲这个问题。我们首先创建一个角色这个表,并初始化数据.
CREATE TABLE `roleinfo` ( `roleId` int(11) NOT NULL AUTO_INCREMENT, `roleName` varchar(255) DEFAULT NULL, PRIMARY KEY (`roleId`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 -- 添加几条测试数据 INSERT into roleinfo(roleId, roleName) values(1, "admin"); INSERT into roleinfo(roleId, roleName) values(2, "user"); INSERT into roleinfo(roleId, roleName) values(3, "customer"); INSERT into roleinfo(roleId, roleName) values(4, "other");
按照一般需求,一个用户可以拥有多个角色,因此产生第三张表userandrole
CREATE TABLE `userandrole` ( `userAndRoleId` int(11) NOT NULL AUTO_INCREMENT, `adminId` int(11) DEFAULT NULL, `roleId` int(11) DEFAULT NULL, PRIMARY KEY (`userAndRoleId`), KEY `FK_Reference_25` (`adminId`), KEY `FK_Reference_26` (`roleId`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 -- 添加几条测试数据 INSERT into userandrole(userAndRoleId, adminId, roleId) values(1, 1, 1); INSERT into userandrole(userAndRoleId, adminId, roleId) values(2, 1, 2); INSERT into userandrole(userAndRoleId, adminId, roleId) values(3, 1, 3);
对应实体类
package com.handly.mybatis.model; /** * 角色信息 * @author handly */ public class RoleInfo { private Integer roleId; private String roleName; //省略get、set方法 }
package com.handly.mybatis.model; import java.util.List; public class UserAndRole { private Integer userAndRoleId; private Integer adminId; private Integer roleId; private User user; private List<RoleInfo> roles; public UserAndRole(){} @Override public String toString() { return "Classes [id=" + userAndRoleId + ", user=" + user + ", roles=" + roles + "]"; } //省略get/set方法 }
方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集 封装联表查询的数据(去除重复的数据)
<!-- 方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集 封装联表查询的数据(去除重复的数据) SELECT * from user u, roleinfo r, userandrole ur where ur.adminId=u.id and ur.roleId=r.roleId and u.id=1 --> <select id="getRole1" parameterType="int" resultMap="UserRoleResultMap"> SELECT * from user u, roleinfo r, userandrole ur where ur.adminId=u.id and ur.roleId=r.roleId and u.id=#{id} </select> <!-- 使用resultMap映射实体类和字段之间的一一对应关系 --> <resultMap type="com.handly.mybatis.model.UserAndRole" id="UserRoleResultMap"> <id property="userAndRoleId" column="userAndRoleId" /> <result property="adminId" column="adminId" /> <result property="roleId" column="roleId" /> <association property="user" javaType="com.handly.mybatis.model.User"> <id property="id" column="id" /> <result property="username" column="username" /> <result property="password" column="password" /> <result property="name" column="name" /> </association> <!-- ofType指定students集合中的对象类型 --> <collection property="roles" ofType="com.handly.mybatis.model.RoleInfo"> <id property="roleId" column="roleId" /> <result property="roleName" column="roleName" /> </collection> </resultMap>
方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
<!-- 方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型 SELECT * from userandrole ur where ur.adminId=1; SELECT id, username from user where id=1 //1 是上一个查询得到的adminId的值 SELECT roleId, roleName from roleinfo where roleId=2 //2是第一个查询得到的roleId字段的值 --> <select id="getRole2" parameterType="int" resultMap="UserRoleResultMap2"> SELECT * from userandrole ur where ur.adminId=#{id} </select> <resultMap type="com.handly.mybatis.model.UserAndRole" id="UserRoleResultMap2"> <id property="userAndRoleId" column="userAndRoleId" /> <result property="adminId" column="adminId" /> <result property="roleId" column="roleId" /> <association property="user" column="adminId" javaType="com.handly.mybatis.model.User" select="getUser"></association> <collection property="roles" column="roleId" ofType="com.handly.mybatis.model.RoleInfo" select="getRoles"></collection> </resultMap> <select id="getUser" parameterType="int" resultType="com.handly.mybatis.model.User"> SELECT id, username from user where id=#{id} </select> <select id="getRoles" parameterType="int" resultType="com.handly.mybatis.model.RoleInfo"> SELECT roleId, roleName from roleinfo where roleId=#{id} </select>
新加接口
package com.handly.mybatis.dao; import java.util.List; import com.handly.mybatis.model.UserAndRole; public interface RoleInfoDao { public List<UserAndRole> getRole1(Integer id); public List<UserAndRole> getRole2(Integer id); }
测试代码
/** * 获取用户角色列表 */ @Test public void testGetRoleListByUserId(){ SqlSession session = sqlSessionFactory.openSession(); try { RoleInfoDao roleDao = session.getMapper(RoleInfoDao.class); // List<UserAndRole> list = roleDao.getRole1(1); List<UserAndRole> list = roleDao.getRole2(1); if(null!=list && list.size()>0){ for(UserAndRole ur : list){ // System.out.println(ur.getDomainId()); System.out.println("u:" + ur.getUser().getUsername()); if(null!=ur.getRoles() && ur.getRoles().size()>0){ for(RoleInfo r : ur.getRoles()){ System.out.print(r.getRoleName() + ", "); } } } } } finally { session.close(); } }
相关推荐
MyBatis支持一对多、多对多的复杂关联映射,通过`association`和`collection`标签,可以实现级联查询和更新。 10. **缓存机制** MyBatis提供了本地缓存和二级缓存,可以提高数据访问效率。开发者可以通过配置开启...
【MyBatis入门以及提高】 在Java EE框架中,MyBatis是一个广泛使用的持久层框架,它极大地简化了原生JDBC编程的繁琐过程。MyBatis的核心在于输入映射和输出映射,以及动态SQL,这些特性使得SQL的编写和维护变得更加...
本项目"mybatis入门学习的完整项目代码"旨在为初学者提供一个完整的 MyBatis 学习环境,帮助理解 MyBatis 的基本概念、配置以及如何在实际项目中应用。 首先,我们要了解 MyBatis 的核心概念: 1. **配置文件**:...
【标题】"第一个mybatis程序 mybatis入门" 涉及到的是MyBatis框架的基础使用,这是一个轻量级的Java持久层框架,它简化了与数据库交互的过程,提供了强大的映射功能。以下是对MyBatis入门的详细解析: 1. **MyBatis...
9. **嵌套查询与关联映射**:`MyBatis-03-Nesting`可能涵盖了多表联查或嵌套查询的示例,例如通过一对一、一对多或多对多的关系映射,将关联的数据一起加载。 10. **测试**:编写JUnit或其他测试框架的测试用例,...
MyBatis是一款强大的Java持久层框架,它与iBatis一脉相承,但功能更加丰富和强大。这个经典入门实例旨在为初学者提供一个...通过实践,你将能够熟练地在项目中应用MyBatis,提高开发效率,并实现优雅的数据访问层设计。
这个入门项目实例将带你深入了解Mybatis的核心概念和基本用法。首先,我们来分析一下提供的文件内容。 1. **用户指南(图片文件)** - `111115114.jpg`、`1.png`、`2.png`、`3.png`:这些很可能是项目教程或步骤的...
通过这个入门教程,读者将学习如何配置Derby数据库,创建表,以及如何利用MyBatis的XML映射文件和SQL语句进行数据操作。 【知识点详细说明】: 1. **Apache Derby**:Apache Derby是一个开源、免费的Java数据库...
"Mybates学习(五)实现关联表查询.docx"会涉及Mybatis的多表查询,包括一对一、一对多、多对多的关联映射。Mybatis提供了、等标签来处理关联关系,并且支持嵌套查询和级联查询。正确使用关联查询能够使代码更加清晰...
1. 数据库SQL语句:MyBatis的核心功能之一就是将Java对象与数据库中的SQL语句进行映射。在项目中,通常会创建一个`resources`目录下的`sqlmap`文件夹,其中包含`.xml`格式的映射文件,如`UserMapper.xml`。这些文件...
- **延迟加载**:只在需要时加载关联数据,提高性能。 - **查询缓存**:一级缓存(SqlSession 级别)和二级缓存(Mapper 级别)。 - **MyBatis 与 Spring 整合**:通过 Spring 管理 SqlSessionFactory 和 SqlSession...
在这个"Mybatis入门JavaSE案例"中,我们将深入理解Mybatis的基本配置、DAO层的注解方式以及XML配置方式。 首先,让我们来了解Mybatis的配置过程。Mybatis的配置文件(mybatis-config.xml)是整个框架的入口,它包含...
这个"MyBatis入门程序"是为初学者设计的,旨在帮助他们快速理解并开始使用MyBatis。在这个程序中,我们将探讨几个关键知识点,包括MyBatis的基本架构、配置、映射文件以及如何连接MySQL数据库。 1. **MyBatis基本...
标题 "mybatis入门测试dao资源" 提到的是关于MyBatis框架的基础学习和DAO(Data Access Object)层的测试。MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。其核心是将SQL语句与Java代码...
### MyBatis 入门知识点概述 #### 一、MyBatis 概念与特点 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis...
在这个"MyBatis入门实例源码"中,我们可能看到以下几个关键的知识点: 1. **MyBatis基本概念**:MyBatis的核心组件包括SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession和Mapper接口。...
MyBatis是一款流行的持久层框架,支持SQL查询、存储过程以及高级映射,它极大地简化了Java应用和数据库之间的交互。与ORM框架Hibernate相比,MyBatis的灵活性更高,对于需要复杂查询和精细操作的场景更为适用。...
在"mybatis入门教程Demo"中,我们将会看到一个名为"MyBatisFirstDemo"的项目,其中包含了一个简单的MyBatis配置和一个基础的Mapper接口。 1. **环境搭建**:要开始MyBatis的学习,首先需要安装JDK和MySQL数据库,并...
MyBatis主要由四个部分组成:SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession和Mapper。SqlSessionFactoryBuilder用于构建SqlSessionFactory,它是整个MyBatis的核心,可以理解为数据库会话工厂。...
同时,MyBatis提供自动结果映射功能,根据Java类的字段与数据库表的列名匹配,将查询结果转换为Java对象。 6. **动态SQL** MyBatis的动态SQL功能非常强大,允许在XML映射文件中使用if、choose、when、otherwise、...