mybatis多表查询(一对多,多对一,多对多)
程序员文章站
2022-05-23 17:53:25
...
mybatis多表查询、多对一,一对多,多对多
多对一、一对多
准备阶段
建立一个部门表和员工表:
多个员工可以同属一个部门:这是多对一
一个部门有多个员工:这是一对多
首先在mysql数据库中建表。建立dept表和emp表
dept表
emp表
建立dept实体类和emp实体类
emp实体类(其中包含部门的实体类对象)
dept实体类(包含员工的实体类对象集合)
建立Dao接口
查询所有员工的Dao接口
public interface IEmpDao {
/**
*查询所有操作
* @return
*/
List<Emp> findAll();
}
查询所有部门的Dao接口
public interface IDeptDao {
/**
*查询所有操作
* @return
*/
List<Dept> findAll();
}
写Dao的Mapper映射
Emp的Mapper映射文件
完整配置如下:
<?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.jjp.dao.IEmpDao">
<!--这边配置java对应的数据库映射-->
<resultMap type="emp" id="empMap">
<!--配置主键-->
<id property="e_id" column="e_id"/>
<!--配置非主键-->
<result property="e_name" column="e_name"/>
<result property="e_tel" column="e_tel"/>
<result property="e_dept" column="e_dept"/>
<result property="e_time" column="e_time"/>
<!--里面为另一张表的关联-->
<association property="type" javaType="dept">
<id property="d_id" column="d_id"/>
<result property="d_name" column="d_name"/>
</association>
</resultMap>
<!--查询所有-->
<select id="findAll" resultMap="empMap">
select *from emp left join dept on emp.e_dept=dept.d_id
</select>
</mapper>
dept的Mapper映射文件
完整配置如下:
<?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.jjp.dao.IDeptDao">
<!--这边配置java对应的数据库映射-->
<resultMap type="dept" id="deptMap">
<!--配置主键-->
<id property="d_id" column="d_id"/>
<!--配置非主键-->
<result property="d_name" column="d_name"/>
<collection property="empType" ofType="emp">
<!--配置主键-->
<id property="e_id" column="e_id"/>
<!--配置非主键-->
<result property="e_name" column="e_name"/>
<result property="e_tel" column="e_tel"/>
<result property="e_dept" column="e_dept"/>
<result property="e_time" column="e_time"/>
</collection>
</resultMap>
<select id="findAll" resultMap="deptMap">
select * from dept d left join emp e on d.d_id=e.e_dept
</select>
</mapper>
主配置文件中的别名配置
完整配置如下:
<?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">
<!-- mybatis的主配置文件 -->
<configuration>
<properties>
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/ssmdemo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT" />
<property name="username" value="root" />
<property name="password" value="J123" />
</properties>
<typeAliases>
<typeAlias type="com.jjp.domain.Emp" alias="emp"/>
<typeAlias type="com.jjp.domain.Dept" alias="dept"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com\jjp\dao\IEmpDao.xml"/>
<mapper resource="com\jjp\dao\IDeptDao.xml"/>
</mappers>
</configuration>
然后在测试文件中编写测试类
多对一测试类EmpTest
package com.jjp.test;
import com.jjp.dao.IEmpDao;
import com.jjp.dao.IUserDao;
import com.jjp.domain.Emp;
import com.jjp.domain.QueryVo;
import com.jjp.domain.User;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class EmpTest {
private InputStream in;
private SqlSession sqlSession;
private IEmpDao EmpDao;
@Before
/**用于在测试方法执行之前执行*/
public void init() throws Exception {
/**1.读取配置文件,生成字节输入流*/
in = Resources.getResourceAsStream("SqlMapConfig.xml");
/**2.获取SqlSessionFactory*/
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
/**3.获取SqlSession对象*/
sqlSession = factory.openSession();
/**4.获取dao的代理对象*/
EmpDao = sqlSession.getMapper(IEmpDao.class);
}
@After
/**用于在测试方法执行之后执行*/
public void destory() throws Exception {
/**提交事务*/
sqlSession.commit();
/**释放资源*/
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test /**多对一查询*/
public void testFindAll() {
/**执行查询的所有方法*/
List<Emp> Emps = EmpDao.findAll();
for(Emp emp:Emps){
System.out.println(emp);
}
}
}
运行结果如下:
Emp{e_id=41, e_name='老王', e_tel='133', e_dept=1, e_time=Tue Feb 27 17:47:08 CST 2018, type=Dept{d_id=1, d_name='产品部', empType=null}}
Emp{e_id=42, e_name='老李', e_tel='135', e_dept=2, e_time=Tue Feb 27 17:47:08 CST 2018, type=Dept{d_id=2, d_name='市场部', empType=null}}
Emp{e_id=43, e_name='老宋', e_tel='138', e_dept=2, e_time=Tue Feb 27 17:47:08 CST 2018, type=Dept{d_id=2, d_name='市场部', empType=null}}
Emp{e_id=44, e_name='老杨', e_tel='137', e_dept=3, e_time=Tue Feb 27 17:47:08 CST 2018, type=Dept{d_id=3, d_name='销售部', empType=null}}
一对多测试类DeptTest
package com.jjp.test;
import com.jjp.dao.IDeptDao;
import com.jjp.dao.IEmpDao;
import com.jjp.domain.Dept;
import com.jjp.domain.Emp;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class DeptTest {
private InputStream in;
private SqlSession sqlSession;
private IDeptDao DeptDao;
@Before
/**用于在测试方法执行之前执行*/
public void init() throws Exception {
/**1.读取配置文件,生成字节输入流*/
in = Resources.getResourceAsStream("SqlMapConfig.xml");
/**2.获取SqlSessionFactory*/
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
/**3.获取SqlSession对象*/
sqlSession = factory.openSession();
/**4.获取dao的代理对象*/
DeptDao = sqlSession.getMapper(IDeptDao.class);
}
@After
/**用于在测试方法执行之后执行*/
public void destory() throws Exception {
/**提交事务*/
sqlSession.commit();
/**释放资源*/
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
/**多对一查询*/
public void testFindAll() {
/**执行查询的所有方法*/
List<Dept> Depts = DeptDao.findAll();
for(Dept dept:Depts){
System.out.println(dept);
}
}
}
运行结果如下:
Dept{d_id=1, d_name='产品部', empType=[Emp{e_id=41, e_name='老王', e_tel='133', e_dept=1, e_time=Tue Feb 27 17:47:08 CST 2018, type=null}]}
Dept{d_id=2, d_name='市场部', empType=[Emp{e_id=42, e_name='老李', e_tel='135', e_dept=2, e_time=Tue Feb 27 17:47:08 CST 2018, type=null}, Emp{e_id=43, e_name='老宋', e_tel='138', e_dept=2, e_time=Tue Feb 27 17:47:08 CST 2018, type=null}]}
Dept{d_id=3, d_name='销售部', empType=[Emp{e_id=44, e_name='老杨', e_tel='137', e_dept=3, e_time=Tue Feb 27 17:47:08 CST 2018, type=null}]}
多对多
多对多配置就是两个一对多的结合,再加上一个中间表
一个用户可能有多种角色
一个角色也可能对应多个用户。
在mysql中创建user表 role表 以及user_role中间映射表
role表:
user表:
user_role表
然后表创建好后,按照上述流程创建user表和role表的实体类,以及在主配置文件中起好实体类的别名。并创建user类和role类的Dao接口。接着配置映射文件。如下所示
IUserDao.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.jjp.dao.IUserDao">
<!-- 定义User的resultMap-->
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!-- 配置角色集合的映射 -->
<collection property="roles" ofType="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</collection>
</resultMap>
<!-- 查询所有 -->
<select id="findAll" resultMap="userMap">
select u.*,r.id as rid,r.role_name,r.role_desc from user u
left outer join user_role ur on u.id = ur.uid
left outer join role r on r.id = ur.rid
</select>
</mapper>
IRoleDao.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.jjp.dao.IRoleDao">
<!--定义role表的ResultMap-->
<resultMap id="roleMap" type="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
<collection property="users" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</collection>
</resultMap>
<!--查询所有-->
<select id="findAll" resultMap="roleMap">
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id = ur.rid
left outer join user u on u.id = ur.uid
</select>
</mapper>
接下来编写测试类。并测试得到结果如下:
运行UserTest
-----每个用户的信息------
User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京', roles=[Role{roleId=1, roleName='院长', roleDesc='管理整个学院', users=null}, Role{roleId=2, roleName='总裁', roleDesc='管理整个公司', users=null}]}
-----每个用户的信息------
User{id=45, username='传智播客', birthday=Sun Mar 04 12:04:06 CST 2018, sex='男', address='北京金燕龙', roles=[Role{roleId=1, roleName='院长', roleDesc='管理整个学院', users=null}]}
-----每个用户的信息------
User{id=42, username='小二王', birthday=Fri Mar 02 15:09:37 CST 2018, sex='女', address='北京金燕龙', roles=[]}
-----每个用户的信息------
User{id=43, username='小二王', birthday=Sun Mar 04 11:34:34 CST 2018, sex='女', address='北京金燕龙', roles=[]}
-----每个用户的信息------
User{id=46, username='老王', birthday=Wed Mar 07 17:37:26 CST 2018, sex='男', address='北京', roles=[]}
-----每个用户的信息------
User{id=49, username='modify,User property', birthday=Mon Nov 04 21:49:45 CST 2019, sex='男', address='北京市顺义区', roles=[]}
-----每个用户的信息------
User{id=50, username='mybastis update user', birthday=Mon Nov 04 21:53:56 CST 2019, sex='女', address='北京市顺义区', roles=[]}
运行RoleTest
---每个角色的信息----
Role{roleId=1, roleName='院长', roleDesc='管理整个学院', users=[User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京', roles=null}, User{id=45, username='传智播客', birthday=Sun Mar 04 12:04:06 CST 2018, sex='男', address='北京金燕龙', roles=null}]}
---每个角色的信息----
Role{roleId=2, roleName='总裁', roleDesc='管理整个公司', users=[User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京', roles=null}]}
---每个角色的信息----
Role{roleId=3, roleName='校长', roleDesc='管理整个学校', users=[]}
这就是多对多配置
上一篇: tomcat单机多实例