mybatis中的关联对象查询

方式1(嵌套查询):

    在本类的mapper映射配置文件中的ResultMap标签中使用association子标签,对关联对象的属性进行关联

    例如:User中关联Department(多对一)

复制代码
----------User的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.tabchanj.mybatis.domain.UserMapper">
    <resultMap type="com.tabchanj.mybatis.domain.User" id="User">
        <!--
         property:表示本类中关联的对象属性 
         dept_id:表示本类的表中哪一列的值将传入select语句中作为参数进行查询
         select:表示查询出关联对象的语句,,
                              其格式为该关联对象的类所配置的mapper映射文件的sql语句地址,为其文件中的namespace+sql语句的id
        -->
        <association property="dept" column="dept_id" select="com.tabchanj.mybatis.domain.DepartmentMapper.get" />
    </resultMap>
    <select id="get" parameterType="Long" resultMap="User">
        select * from t_user where id = #{id}
    </select>

    <select id="list" resultMap="User">
        select * from t_user
    </select>
</mapper>
复制代码
复制代码
-----------Department的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.tabchanj.mybatis.domain.DepartmentMapper">
    <resultMap type="Department" id="DepartmentMap"/>
    <select id="get" parameterType="Long" resultMap="DepartmentMap">
        select * from t_department where id = #{id}
    </select>
    <select id="list" resultMap="DepartmentMap">
        select * from t_department
    </select>
</mapper>
复制代码

 

复制代码
//--------测试类-----------
    @Test
    public void testName1() throws Exception {
        //通过sqlsession获得代理对象(Mapper)
        UserMapper mapper = MyBatisUtil.openSession().getMapper(UserMapper.class);
        //mapper调用接口中方法,相当于执行了mapper映射文件中的id为get的sql语句
        User u = mapper.get(1L);
    }
复制代码

 

复制代码

---------结果发出了2条sql,即在未使用department的情况下依然发出了sql将其查询了出来-----------

DEBUG [com.tabchanj.mybatis.domain.UserMapper.get] - ==> Preparing: select * from t_user where id = ? 
DEBUG [com.tabchanj.mybatis.domain.UserMapper.get] - ==> Parameters: 1(Long)
DEBUG [com.tabchanj.mybatis.domain.DepartmentMapper.get] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@2b62c243]
DEBUG [com.tabchanj.mybatis.domain.DepartmentMapper.get] - ==> Preparing: select * from t_department where id = ? 
DEBUG [com.tabchanj.mybatis.domain.DepartmentMapper.get] - ==> Parameters: 1(Long)

--------------------------------------------------------------------------------------------------------------------------

解决办法是,在mabtatis-config.xml中配置延迟加载属性,此时可以解决在查询user时不会查询department对象,

  但是问题依然存在,,就是在查询User的任意一个属性时还是会发送额外的sql去查询department,

   <settings>
        <setting name="lazyLoadingEnabled" value="true" />
    </settings>

-----------------------------------------------------------------------------------------------------------------------

  查询User的任意一个属性时还是会发送额外的sql去查询department,的解决方法

  在mabtatis-config.xml中配置另一个延迟加载属性,

    <setting name="aggressiveLazyLoading" value="false" />

-------------------------------------------------------------------------------------------------------------------------

复制代码
---------------详细的mybatis-config.xml配置----------------
复制代码
<?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">
<configuration>
    <settings>
        <setting name="lazyLoadingEnabled" value="true" />
        <setting name="aggressiveLazyLoading" value="false" />
    </settings>
    <typeAliases>
        <package name="com.tabchanj.mybatis.domain" />
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="org.gjt.mm.mysql.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
                <property name="username" value="root" />
                <property name="password" value="4230" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/tabchanj/mybatis/domain/UserMapper.xml" />
        <mapper resource="com/tabchanj/mybatis/domain/DepartmentMapper.xml" />
    </mappers>
</configuration>
复制代码
复制代码
复制代码

方式1的改进(嵌套结果):

        不再在进行resultMap配置时使用sql语句进行二次查询,,此时直接先将department的所有属性全部查询出来,

         和User的所有属性查在一张表中,当然此处需对department查询处的列名进行自定义别名,使列名更加有意义,,

         是针对User和department中有同名属性造成查询出来的列名被标记为xxx1,xx2的清况.

 

复制代码
-----------------------改进后的User的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.tabchanj.mybatis.domain.UserMapper">

    <resultMap type="com.tabchanj.mybatis.domain.User" id="UserMap">
        <!-- User的基本属性 -->
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <!--
           property:表示本类中关联的对象属性 
        并将关联对象的列名的别名与关联对象的属性做对应
        -->
        <association property="dept" javaType="Department">
            <id column="dept_id" property="id" />
            <result column="dept_name" property="name" />
            <result column="dept_sn" property="sn" />
        </association>
    </resultMap>
    <select id="get" parameterType="Long" resultMap="UserMap">
        <!-- 此时先将department的数据一并查询出来 -->
        select u.*,d.name dept_name,d.sn dept_sn from t_user u LEFT JOIN t_department d on u.dept_id=d.id where u.id = #{cc}
    </select>

    <select id="list" resultMap="UserMap">
        select u.*,d.name dept_name,d.sn dept_sn from t_user u LEFT JOIN t_department d on u.dept_id=d.id
    </select>
</mapper>
复制代码

 

 

 

复制代码
   -------------------------测试------------------

  @Test
    public void testName1() throws Exception {
        //通过sqlsession获得代理对象(Mapper)
        UserMapper mapper = MyBatisUtil.openSession().getMapper(UserMapper.class);
        //mapper调用接口中方法,相当于执行了mapper映射文件中的id为get的sql语句
        User u = mapper.get(2L);
        System.out.println(u.getDept());
    }

  结果:只有一条sql,当然也只能有一条sql,因为一条sql就已经查出了本类和关联对象的所有信息
  
ybatis.domain.UserMapper.get] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@43cfc1ef]
ybatis.domain.UserMapper.get] -  Preparing: select u.*,d.name dept_name,d.sn dept_sn from t_user u LEFT JOIN t_department d on u.dept_id=d.id where u.id = ? 
ybatis.domain.UserMapper.get] -  Parameters: 2(Long)
Department [id=2, name=武装部, sn=FDSS]
复制代码

 

方式2的该进(加前缀):

  由于我们在自定义关联对象的列别名时都加了dept_的前缀,因此配置user的mapper时,可以在方式2中的association标签上添加columnPrefix="dept_"这一属性,

  而内部就不再配置列名和属性名的对应了.但前提是,在Department的mapper映射配置文件中已经配置类简单的列名和属性相同的一一对应的resultMap标签.

  并且,在user中的assosiation标签中还要引入该resultMap,详见下面的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.tabchanj.mybatis.domain.UserMapper">

    <resultMap type="com.tabchanj.mybatis.domain.User" id="UserMap">
        <!-- User的基本属性 -->
        <id property="id" column="id" />
        <result property="name" column="name" />
        <!-- 
             property:表示本类中关联的对象属性
             columnPrefix:表示关联对象的列名前都有
             dept_ resultMap:指明返回的类型时department类型,之一resultMap路径department的mapper映射配置文件中的resultMap的路径
          -->
        <association property="dept" javaType="Department"
            columnPrefix="dept_"
            resultMap="com.tabchanj.mybatis.domain.DepartmentMapper.DepartmentMap">
            <!-- <id column="dept_id" property="id" /> -->
            <!-- <result column="dept_name" property="name" /> -->
            <!-- <result column="dept_sn" property="sn" /> -->
        </association>
    </resultMap>
    <select id="get" parameterType="Long" resultMap="UserMap">
        <!-- 此时先将department的数据一并查询出来 -->
        select u.*,d.name dept_name,d.sn dept_sn from t_user u LEFT JOIN
        t_department d on u.dept_id=d.id where u.id = #{cc}
    </select>

    <select id="list" resultMap="UserMap">
        select u.*,d.name dept_name,d.sn
        dept_sn from t_user u LEFT JOIN t_department d on u.dept_id=d.id
    </select>
</mapper>
复制代码

 

 

 方式3:关联集合的查询

    此时,时department中关联了User,此时为一对多的情况

    此时,在department的mapper映射文件中的resultMap标签中采用<collection>子标签来关联User

复制代码
-----------------department的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.tabchanj.mybatis.domain.DepartmentMapper">
    <resultMap type="Department" id="DepartmentMap">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="sn" property="sn" />
        <!-- 
        property:指明本类users属性
        ofType:指明users集合中装的时User类型的数据
        select:该查询语句还是使用的是user的mapper映射配置文件中的查询语句,从路径就可以看出
        column:指明该查询语句中的参数时本类中的id列的值
         -->
        <collection property="users" ofType="User"
            select="com.tabchanj.mybatis.domain.UserMapper.getByDeptId" column="id">
        </collection>
    </resultMap>
    <select id="get" parameterType="Long" resultMap="DepartmentMap">
        select * from
        t_department where id = #{id}
    </select>
    <select id="list" resultMap="DepartmentMap">
        select * from t_department
    </select>
</mapper>
复制代码

 

复制代码
-------User的mapper映射配置文件(只保留了
id="getByDeptId"的sql查询语句
)--------------------
<?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.tabchanj.mybatis.domain.UserMapper">

    <resultMap type="com.tabchanj.mybatis.domain.User" id="UserMap">
        <!-- User的基本属性 -->
        <id property="id" column="id" />
        <result property="name" column="name" />
       </resultMap>
<!-- 该语句在department的mapper映射配置文件中被引用-->
 <select id="getByDeptId" parameterType="Long" resultMap="UserMap">
        select * from t_user where dept_id=#{id}
    </select>
</mapper>
复制代码
复制代码
// --------测试类-----------
    @Test
    public void testName2() throws Exception {
        // 通过sqlsession获得代理对象(Mapper)
        DepartmentMapper demapper = MyBatisUtil.openSession().getMapper(DepartmentMapper.class);
        // mapper调用接口中方法,相当于执行了mapper映射文件中的id为get的sql语句
        Department d = demapper.get(1L);
        System.out.println(d);
    }
结果:出现了2条sql语句,,并且是在已经配置了延迟加载的情况下出现的2条语句,说明该种方式不支持延迟加载
复制代码
 [com.tabchanj.mybatis.domain.DepartmentMapper.get] - ==>  Preparing: select * from t_department where id = ? 
 [com.tabchanj.mybatis.domain.DepartmentMapper.get] - ==> Parameters: 1(Long)
 [com.tabchanj.mybatis.domain.UserMapper.getByDeptId] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@71e80e4d]
 DEBUG [com.tabchanj.mybatis.domain.UserMapper.getByDeptId] - ==>  Preparing: select * from t_user where dept_id=? 
 DEBUG [com.tabchanj.mybatis.domain.UserMapper.getByDeptId] - ==> Parameters: 1(Long)
Department [id=1, name=财务部, sn=DFSD]
复制代码

发布了11 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/LYW_lyw/article/details/79851632
今日推荐