一條sql查出樹形結構數據

當前的問題:同一張表中存放省市區縣的數據,如何經過一條SQL語句將省市區縣都查詢出來,
且省級包含全部的市級列表,市級中又包含縣級的數據。java

想法:利用mybatis集合的嵌套查詢(collection)git

數據格式以下:web

Java實體類以下:spring

public class Area implements Serializable{

	private static final long serialVersionUID = 1L;

	/**
	 * 主鍵id
	 */
	private Integer id;
	/**
	 * 地區名稱
	 */
    private String name;
    /**
     * 地區編碼
     */
    private Integer areaId;
    /**
     * 上一級地區編碼
     */
    private Integer parentId;
    /**
    * 下一級地區列表
    */
    private List<Area> subAreas;

    ...getter 和 setter 方法...
}

xml:sql

支持兩層嵌套的例子websocket

<!-- 同表級聯查詢(支持兩層嵌套查詢) -->
  <resultMap type="cn.edu.ntu.entity.Area" id="areasOther">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="area_id" jdbcType="INTEGER" property="areaId" />
    <result column="parent_id" jdbcType="INTEGER" property="parentId" />
    <collection property="subAreas" ofType="cn.edu.ntu.entity.Area" columnPrefix="b">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
        <result column="area_id" jdbcType="INTEGER" property="areaId" />
        <result column="parent_id" jdbcType="INTEGER" property="parentId" />
    </collection>
    <!-- 使用columnPrefix簡化書寫,不然須要寫成
    	<collection property="subAreas" ofType="cn.edu.ntu.entity.Area" >
	        <id column="bid" jdbcType="INTEGER" property="id" />
	        <result column="bname" jdbcType="VARCHAR" property="name" />
	        <result column="barea_id" jdbcType="INTEGER" property="areaId" />
	        <result column="bparent_id" jdbcType="INTEGER" property="parentId" />
	    </collection>
	     column的值與sql語句中的命名對應
     -->
  </resultMap>

  <!--由於是一對多的關係,用collection-->
  <select id="queryAllCity" resultMap="areasOther">
    select     
	    a.id, a.name, a.area_id, 
	    b.id bid, b.name bname, b.area_id barea_id
    from area a 
    left join area b on b.parent_id = a.area_id
    where a.parent_id is null
  </select>

測試方法:mybatis

public class MybatisTest {

	@Test
	public void test(){
		ApplicationContext application = 
            new ClassPathXmlApplicationContext("classpath*:spring/applicationContext.xml");
		
		AreaMapper areaMapper = application.getBean(AreaMapper.class);
		List<Area> areaList = areaMapper.queryAllCity();
		System.out.println(areaList.size());
		System.out.println(areaList.get(0).getSubAreas().size());
		System.out.println(JsonUtils.objectToJson(areaList));
		
	}
}

運行結果:app

結論:socket

    從上面的的測試數據能夠看出已經支持兩層嵌套,可是若是還要往id爲「areasOther」的<resultMap>的<collection>中再嵌套一層<collection>,目的是支持三層嵌套,暫時不知道如何操做???測試

嘗試失敗的案例:

<!-- 同表級聯查詢(支持三層嵌套查詢的測試) -->
  <resultMap type="cn.edu.ntu.entity.Area" id="areasOther">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="area_id" jdbcType="INTEGER" property="areaId" />
    <result column="parent_id" jdbcType="INTEGER" property="parentId" />
    <collection property="subAreas" ofType="cn.edu.ntu.entity.Area" columnPrefix="b">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
        <result column="area_id" jdbcType="INTEGER" property="areaId" />
        <result column="parent_id" jdbcType="INTEGER" property="parentId" />
        <collection property="subAreas" ofType="cn.edu.ntu.entity.Area" columnPrefix="c">
            <id column="id" jdbcType="INTEGER" property="id" />
            <result column="name" jdbcType="VARCHAR" property="name" />
            <result column="area_id" jdbcType="INTEGER" property="areaId" />
            <result column="parent_id" jdbcType="INTEGER" property="parentId" />
        </collection>
    </collection>
    <!-- 使用columnPrefix簡化書寫,不然須要寫成
    	<collection property="subAreas" ofType="cn.edu.ntu.entity.Area" >
	        <id column="bid" jdbcType="INTEGER" property="id" />
	        <result column="bname" jdbcType="VARCHAR" property="name" />
	        <result column="barea_id" jdbcType="INTEGER" property="areaId" />
	        <result column="bparent_id" jdbcType="INTEGER" property="parentId" />
	    </collection>
	     column的值與sql語句中的命名對應
     -->
  </resultMap>

  <!--由於是一對多的關係,用collection-->
  <select id="queryAllCity" resultMap="areasOther">
    select     
	    a.id, a.name, a.area_id, 
	    b.id bid, b.name bname, b.area_id barea_id,
        c.id cid, c.name cname, c.area_id carea_id
    from area a 
    left join area b on b.parent_id = a.area_id
    left join area c on c.parent_id = b.area_id
    where a.parent_id is null
  </select>

以上案例並無成功,不知道是否是queryAllCity的sql語句書寫問題,請大牛指點!

 

另外一種支持多層嵌套的方式:

<!-- 同表級聯查詢 (支持多層嵌套) -->
  <resultMap type="cn.edu.ntu.entity.Area" id="areas">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="area_id" jdbcType="INTEGER" property="areaId" />
    <result column="parent_id" jdbcType="INTEGER" property="parentId" />
    <collection property="subAreas" ofType="cn.edu.ntu.entity.Area" column="area_id" 
        select="queryCityByParentId">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
        <result column="area_id" jdbcType="INTEGER" property="areaId" />
        <result column="parent_id" jdbcType="INTEGER" property="parentId" />
    </collection>
  </resultMap>

  <!--由於是一對多的關係,用collection-->
  <select id="queryCityByParentId" parameterType="java.lang.Integer" resultMap="areas">
    select
    	a.id, a.name, a.area_id, a.parent_id 
    from area a where a.parent_id = #{area_id}
  </select>
  
  <!--由於是一對多的關係,用collection-->
  <select id="queryCity" resultMap="areas">
    select
    	a.id, a.name, a.area_id, a.parent_id  
    from area a where a.parent_id is null 
  </select>

以上方式在collection中將select指定的查詢語句循環調用,查詢條件爲column的數據,最終將查詢的結果放到property指定的屬性中

執行結果:

 

源碼路徑:https://gitee.com/wpfc/websocket/blob/master/src/test/java/cn/dq/MybatisTest.java

參考:http://blog.csdn.net/u012485016/article/details/64500972

相關文章
相關標籤/搜索