自己总结:
mybatis和hibernate都有对表与表的支持,对于hibernate有的一些关联方式,比如hibernate的红包吗hbm2ddl(自动更新表结构)对于mybatis是不支持该方式的,hibernate支持表与表的关联是通过(one-to-one,many-to-one,one-to-many。。。)等机制实现表与表的关联,而对于mybatis来说,他的关联只有两个一个是association标签来表示多的一端,一个是用collection来表示一得一端,mybatis认为所有的关联关系只有一和多,所以用这两个标签足够了。(纯属个人理解不带任何官方说明)
环境:
对象:
所有的对象名:应该是包名+类名;我用了别名:
<typeAliases>
<typeAlias type="com.bjsxt.lc.pojo.AUser" alias="user"/>
<typeAlias type="com.bjsxt.lc.pojo.ARole" alias="role"/>
</typeAliases>
表:
多对一的关联:
. 第一种多对一的关联(抓取策略是select)
说明:第一种抓取策略:发送两个sql语句,首先发送一个查询用户信息,然后在使用角色信息的时候在发送一条语句查询相关的角色信息(l懒加载)(注意:是在使用相关的角色信息的时候才会发送第二条sql语句,懒加载策略)
步骤:
l 第一步:改写pojo
l 第二步:配置文件
pojo
public class AUser
{
private int id;
private String name;
private int roleId;
private byte status;
private Date createTime;
//多的一端
private ARole role
get/set方法
映射文件:
<!--
设置关联的查询语句:
type:表示关联的sql返回的类型
id:表示这个关联查询链接的名字
association:是一个多的一端设置关联关系的标签
property:表示在pojo中,多的一端的属性名,
javaType表示关联的的类型,
column:表示你需要用user表的那个属性去关联:(roleId)通常指外键
select:表示你需要关联的查询语句是那个
-->
<resultMap type="user" id="userResultMap">
<id column="roleId" property="roleId"/>[Mybatis不会自动为外键赋值]
<association property="role" javaType="role" column="roleId"
select="findOneRole">
</association>
</resultMap>
<!--
关联查询多的一端
id:表示方法的名字
resultMap:表示返回的Map类型。需要在上面定义,返回User对象,然后在里面设置关联查询的要求
parameterType:表示参数接受的类型
-->
<select id="findOneUserRela" resultMap="userResultMap" parameterType="map">
select * from a_user where id = #{id}
</select>
<!--
关联的查询语句,
-->
<select id="findOneRole" resultType="role">
select * from a_role where id = #{id}
</select>
l 说明:
a.Mybatis默认采取的是select的抓取策略(懒加载)
b. 首先查询出一条数据,在关联查询出其他数据
c. 在关联查询的关系的时候必须添加关联的外键,否则外键不会赋值
第二种多对一的关联(抓取策略(join))
说明:第二种关联是利用join的子查询,一次性查出所有的信息,没有懒加载。且需要为相同的列名加别名,以区分开属性的值
l 第一步:改写pojo(与上一步一样)
l 第二步:书写配置文件
映射文件:
<!-- ==============第二种多对一关联策略(join)开始=================== -->
<!--
给每一列的属性赋值:
type:我起别名了====
-->
<resultMap type="user" id="myJionResult">
<!--
这个是给所需要查询的对象一一赋值,如果不赋值mybatis不会自动赋值
-->
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="status" property="status"/>
<result column="createTime" property="createTime"/>
<!--
property:为pojo的的属性名
javaType:为关联对象的包名加类名(我包名和类名起了个别名为role)
-->
<association property="role" javaType="role" >
<!--
这个是给所需要查询的对象的关联对象一一赋值,如果不赋值mybatis不会自动赋值
-->
<id column="arid" property="id"/>
<result column="arname" property="name"/>
<result column="arstatus" property="status"/>
<result column="arCreateTime" property="createTime"/>
</association>
</resultMap>
<select id="findOneUserJoin" parameterType="map" resultMap="myJionResult">
select au.*,ar.id as arid,ar.name as arname,
ar.status as arstatus,ar.createTime as arCreatetime
from a_user au,a_role ar where au.roleId = ar.id and au.id = #{id}
</select>
<!-- ==============第二种多对一关联策略(join)结束=================== -->
首先,join和关联方式必须满足使用一条sql语句,其中每一列都必须在对象中关联关系,否则就不会赋值
测试:
/**
* 关联查询(select)
*/
@Test
public void findOneUserRela()
{
SqlSession session = this.sqlSessionFactory.openSession();
Map<String,Object> condMap = new HashMap<String,Object>();
condMap.put("id", "4");
IUserDao userDao = session.getMapper(IUserDao.class);
AUser user = userDao.findOneUserRela(condMap);
logger.info("user=={},角色相关信息:{}",user);
logger.info("角色相关信息:{}",user.getRole());
}
/**
* 关联查询(Join)
*/
@Test
public void findOneUserJoin()
{
SqlSession session = this.sqlSessionFactory.openSession();
Map<String,Object> condMap = new HashMap<String,Object>();
condMap.put("id", "4");
IUserDao userDao = session.getMapper(IUserDao.class);
AUser user = userDao.findOneUserJoin(condMap);
logger.info("user=={},角色相关信息:{}",user);
logger.info("角色相关信息:{}",user.getRole());
}
结果:
user==AUser [id=4, name=李四, roleId=2, status=2, createTime=Mon Nov 21 19:06:09 GMT+08:00 2016]
user的角色==ARole [id=2, name=角色二, status=0, createTime=Wed Nov 23 16:34:36 GMT+08:00 2016]