上一章节中我们已经完成了对单表的CRUD操作,接下来今天这一讲讲述的是关于Mybatis在多表查询时候的应用,毕竟实际业务中也是多表的联合查询比较多嘛~
还记得最一开始我们新建过一张Website表吗,在那张表里有个VisitorId字段,表示访问者访问过哪些网站,现在我们先按照上一张中的要求把关于Website的JavaBean实体先建立出来。还是在com.yy.model包下面新建一个Website类,用来持久化数据之用,重写下相应toString()方法,方便测试程序之用。
在com.yy.demo下面分别新建相应的操作接口:
package david.mybatis.demo;
import java.util.List;
import david.mybatis.model.Website;
public interface IWebsiteOperation {
public int add(Website website);
public int delete(int id);
public int update(Website website);
public Website query(int id);
public List<Website> getList();
}
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yy.demo.IWebsiteOperation">
<sql id="getListSql">
select id,name,VisitorId,status,createTime from Website
</sql>
<insert id="add" parameterType="Website" >
insert into Website (Id,Name, VisitorId, Status, CreateTime)
values (#{id},#{name}, #{visitorId}, #{status}, #{createTime})
</insert>
<delete id="delete" parameterType="int">
delete from website where
status>0 and id = #{id}
</delete>
<update id="update" parameterType="Website">
update website set
name=#{name} where status>0 and id=#{id}
</update>
<select id="query" parameterType="int" resultMap="websiteRs">
select
Website.id siteId, Website.name siteName, Visitor.Id visitorId,
Visitor.name visitorName,
Website.status siteStatus, Website.createtime
siteCreateTime from Website
inner join Visitor on Website.visitorid =
Visitor.id where Website.status>0 and
Website.id=#{id}
</select>
<resultMap type="Website" id="websiteRs">
<id column="siteId" property="id" />
<result column="siteName" property="name" />
<result column="siteStatus" property="status" />
<result column="siteCreateTime" property="createTime" />
<!--
主要要注意的是,Website实体与Visit的实体里面Id与Name这2个属性都是一样的,
所以为了避免映射出现出错现象,把相应的查询结果列起上不一样的别名,
这样绑定的时候就可以避免错误。
-->
<association property="visitor" javaType="Visitor" resultMap="visitorRs" />
</resultMap>
<resultMap type="Visitor" id="visitorRs">
<id column="visitorId" property="id" />
<result column="visitorName" property="name" />
</resultMap>
<select id="getList" resultMap="websiteByVisitorIdRs">
<include refid="getListSql" />
</select>
<resultMap type="Website" id="websiteByVisitorIdRs">
<id column="Id" property="id" />
<result column="Name" property="name" />
<result column="VisitorId" property="visitorId" />
<result column="Status" property="status" />
<result column="CreateTime" property="createTime" />
</resultMap>
</mapper>
大家可以看到其实多表处理resultMap的方式和单表是一致的,也无非是吧列明与Javabean属性名成对应上去,可以看到在Website 的<resultMap>节点里面前台另外一个resultMap,他就是代表Visit实体所需要映射的实体,可以使用以下方式进行关联
<association property="visitor" javaType="Visitor" resultMap="visitorRs" />
其中的visitor就是Website实体中的visit字段名,必须保证名称一致,否则就会抛出There is no getter for property named 'XXX' in 'class david.mybatis.model.Website'的异常,这在上几章已经讲述了,当 然如果你觉得不用嵌套resultMap也行,嵌套也是出于其他地方可以还要用到这个配置那就提炼出来的过程,也是抽象出来的一种思想。具体使 用<resultMap>中的ID与Result可以从官网查找相应区别说明:http://mybatis.github.io/mybatis-3/sqlmap-xml.html#Result_Maps
这样,一个简单的多表联合查询就出来啦~,如果还有更加复杂的查询业务费是在这个基础上些许的变通修改。
这章就到此为止啦,下一章会继续跟讲下,如果弄一个简单的Mybatis下的分页效果~^0^
问题:接口未在映射中注册
Type interface com.yy.demo.IWebsiteOperation is not known to the MapperRegistry.
at org.apache.ibatis.binding.MapperRegistry.getMapper(MapperRegistry.java:42)
at org.apache.ibatis.session.Configuration.getMapper(Configuration.java:639)
at org.apache.ibatis.session.defaults.DefaultSqlSession.getMapper(DefaultSqlSession.java:218)
at com.yy.test.TestWebsite.testBasicQueryByInterfaceWay(TestWebsite.java:25)
at com.yy.test.TestWebsite.main(TestWebsite.java:17)
解决:在总配置文件(TestMyBatis_config.xml)中注册网站类的映射,如下所示:
<mappers>
<mapper resource="com/yy/mapper/VisitorMapper.xml" />
<mapper resource="com/yy/mapper/WebsiteMapper.xml" />
</mappers>