一对一关联查询搞了好久终于搞懂了,写篇博客纪念一下
这篇博客的配置以及实体类映射文件与我的第一篇博客完全相同,你可以参考
解决mybatis一对多查询问题时的只显示一条数据的问题(查询部门的同时把所属部门的员工信息查出来)关联查询
业务要求:是要查出用户的同时也要把用户的所属部门查出来,也存在没有部门的用户,比如管理员,比如老板所以查询的时候要用左外连接查询
附上两张表的图:
查询sql:
该sql放到数据库可以查出来
SELECT u.*,
d.id did,
d.name,
d.parentId,
d.sort,
d.note,
d.createdTime,
d.modifiedTime,
d.createdUser,
d.modifiedUser
FROM sys_users u
LEFT JOIN sys_depts d
ON u.deptId=d.id
UserDao接口:
public interface UserDao{
List<User> selectUsersDept();
}
UserMapepr.xml文件:
<mapper namespace="com.cn.dao.UserDao">
<select id="selectUsersDept" resultMap="ResultUsersDept">
<!-- 这里要把没有部门的员工也查出来所以要用右外连接查询 -->
SELECT u.*,
d.id did,
//这里注意在你两张表的主键都一样的情况下要给其中一张表起别名,
不然容易部门id和用户的id一模一样,重点注意
d.name,
d.parentId,
d.sort,
d.note,
d.createdTime,
d.modifiedTime,
d.createdUser,
d.modifiedUser
FROM sys_users u
LEFT JOIN sys_depts d
ON u.deptId=d.id
</select>
<resultMap type="com.cn.entity.User" id="ResultUsersDept">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="salt" column=""/>
<result property="deptId" column=""/>
<result property="email" column=""/>
<result property="mobile" column=""/>
<result property="valid" column=""/>
<result property="createdTime" column=""/>
<result property="modifiedTime" column=""/>
<result property="createdUser" column=""/>
<result property="modifiedUser" column=""/>
<association property="dept" javaType="com.cn.entity.Dept">
<!--起了别名的id,还要注意javaType属性一定要有,不然报空指针异常 -->
<id property="id" column="did" />
<result property="name" column="name"/>
</association>
</resultMap>
</mapper>
测试:
public class UserTests {
/**
* @author: leebob
* @date: 2020年3月18日 上午11:15:09
*/
public static SqlSessionFactory sqlSessionFactory;
public SqlSession sqlSession;
//添加UserMapper接口
public UserDao up;
//通过SqlSessionFactoryBuilder构造SqlSessionFactory实例
@BeforeClass
public static void testBefore() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
}
// 每个单元测试方法(添加@Test注解的方法)在执行前,创建一个新的SqlSession实例,并获得UserMapper接口的动态代理对象
@Before
public void before() {
sqlSession = sqlSessionFactory.openSession();
up = sqlSession.getMapper(UserDao.class);
}
@After
public void after() {
sqlSession.close();
}
@Test
public void selectUsersDept() {
List<User> users = up.selectUsersDept();
users.forEach(System.out::println);
}
@Test
public void selectUserDeptVo() {
List<UserDeptVo> users = up.selectUserDeptVo();
users.forEach(System.out::println);
}
}
查询结果:
User(id=4, username=王五, password=+HBpqtPuj9KLBIpneR5X0A==, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=2, name=设计部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
User(id=6, username=王花, password=431ebdcccf3404787a144f9ba669a8e2, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=2, name=设计部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
User(id=16, username=李华, password=710058cf374a38d76510d009f63bf28d, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=2, name=设计部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
User(id=1, username=admin, password=4ebd394fbd25e495e0753a7dc9889a8e, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=3, name=营销部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
User(id=3, username=李四, password=c5dc32ec66041aeddf432b3146bd2257, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=3, name=营销部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
User(id=12, username=user-001, password=5bf6593afd106aa544000d559f0c2241, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=3, name=营销部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
User(id=13, username=user-c, password=2630d8bd50c76abf001a9daceeae97e6, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=3, name=营销部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
User(id=15, username=user-b, password=2ce586af95c6431112092f653659c85f, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=3, name=营销部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
User(id=2, username=张三, password=bdcf69375bdb532e50279b91eb00940d, salt=null, deptId=null, email=null, mobile=null, valid=1, createdTime=null, modifiedTime=null, modifiedUser=null, createdUser=null, dept=Dept(id=4, name=人事部, parentId=null, sort=null, note=null, createdTime=null, modifiedTime=null, createdUSer=null, modifiedUser=null, users=null))
总结:
1.一对一的查询用assocation,在你要查的实体内要添加你关联的对象的属性比如:
// 查询用户的时候,将部门的查询结果映射到部门对象
private Dept dept;
两张表的主键字段一致的情况下要给主键字段起别名,javatype属性一定要指定,不然报空指针异常
2.一对多的查询用collection,在你要查询的实体内部添加你要关联的对象集合比如:
//部门查询用户时在部门实体内添加
private List<User> users;
同样的两张表的主键要是一致的话,只能查出一个条件得一条记录,同时注意collection的属性,property指的是映射到的实体的类型,oftype指的是集合内的对象类型
3.查询方法分为分段查询和关联查询,还可以封装DeptUserVo对象来查询省去了映射这么麻烦