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 [[email protected]]
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 [[email protected]]
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 [[email protected]]
 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]

   

时间: 2024-10-29 10:47:44

mybatis中的关联对象查询的相关文章

mybatis中的关联查询

1>在实体映射层中引入关联对象 package com.jinglin.hotelsup.model; import java.io.Serializable; public class Goodsinfo implements Serializable{ private Integer goodsid; private Integer companyid; private Integer goodstypeid; private Integer unitid; private String c

第10条:在既有类中使用关联对象存放自定义数据

在对象中存放相关信息的方式: 1.从对象所属的类中继承一个子类,然后改用这个子类对象. 然而有时类的实例可能是由某种机制所创建的,无法使用这种机制创建自己所写的子类实例.所以采用第2种方式-----“关联对象” 2.关联对象 可以给某对象关联多个对象,这个对象用“键”来区分,存储对象值的时,可以指明“存储策略”.存储策略由名为objc_AssociationPolicy的枚举所定义. 对象的关联类型: OBJC_ASSOCIATION_ASSIGN     等价于  assign OBJC_AS

Effective-OC 10.在既有类中使用关联对象存储自定义数据

EOC中介绍与案例 有时候需要在对象中存放相关的信息 这时候我们通常会从对象所属的类中继承一个子类,然后改用这个子类对象.然而并非所有的情况都能这么做.有的时候 类的实例可能是由某种机制创建的,而开发者无法令这种机制创建出自己写的子类的实例,OC中有一强大的特性可以解决这个问题 就是"关联对象" 可以给某对象关联许多其他的对象 这些对象通过"键"来区分.存储对象值得实惠 可以指明"存储策略",用以维护相对应的"内存管理语义".

解决 mybatis 中相互关联的两种表数据在返回前端时一直循环查询,直到StackOverFlow报错

原代码设计: 一个用户有多个账户,是一对多的关系,用Collection集合关联:一个账户独属于一个用户,是一对一的关系,用association来关联: UserMapper.xml <mapper namespace="com.xuetu.springboot.mapper.UserMapper"> <!-- 定义User的resultMap--> <resultMap id="userMap" type="user&qu

MyBatis中使用RowBounds对查询结果集进行分页

MyBatis可以使用RowBounds逐页加载表数据.RowBounds对象可以使用offset和limit参数来构建.参数offset表示开始位置,而limit表示要取的记录的数目 映射文件: <select id="findAllUsers" resultType="User"> select id,name,gender from t_user </select> 映射接口中: public List<User> find

mybatis中的多表查询

1)无延迟加载的一对一关联 <resultMap type="Userbean" id="baseMap"> <id column="userid" property="userid"/> <result column="username" property="username"/> <collection property="dep&

Mybatis中的like模糊查询

1.  参数中直接加入%% param.setUsername("%CD%");      param.setPassword("%11%"); <select id="selectPersons" resultType="person" parameterType="person"> select id,sex,age,username,password from person where t

mybatis中的多条件查询

使用Map集合和索引号 接口: /** * 多条件查询Map集合 * @param map * @return */public List<Student> findByManyCondition(Map<String,Object> map); /** * 多参数查询使用索引 * @param name * @param age * @return */public List<Student> findStudentByCondition(String name,in

MyBatis一对多关联表查询 映射文件

<!--一对多--> <!--根据广告组编号获取广告项列表一--> <select id="getAdInfoByAdSysNo" resultType="ec.model.advertising.AdInfo" parameterType="int"> SELECT * FROM T_AD_ADINFO WHERE adSysNo = #{sysNo,jdbcType=INTEGER} </select