mybatis一對一映射配置詳解


 

聽說mybatis一對一有三種寫法,今天我試了一下。

數據庫表准備

為了偷懶,我直接就拿用戶權限菜單里的菜單表和菜單與權限的中間表做實現,他們原來是多對多的關系,這邊我假設這兩張表是一對一。

表  gl_role_men:id,role_id,menu_id     --------->  實體類 GlrolemenuModel  private String id;private String roleId;private String menuId;private MenuModel menu;

表  menu:id,menu_name,url         --------->  實體類 MenuModel private String id;private String menuName;private String url;

一對一第一種寫法

glrolemenuMapper.xml

這個映射文件里的寫法有幾個要注意的地方,因為是GlrolemenuModel里放了MenuModel的信息,所以我稱GlrolemenuModel是維護關系的一方,那么resultMap的type就是GlrolemenuModel

property對應是實體類的屬性,column對應的是數據庫里表字段名
<resultMap type="com.tieasy.model.GlrolemenuModel" id="glrolemenu_menu_map">
        <id property="id" column="id" />
        <result property="roleId" column="role_id" />
        <result property="menuId" column="menu_id" />
        
        <!-- 上面是GlrolemenuModel表里的信息,下面是MenuModel表里的信息,應該很清楚了吧,注意下面的property的寫法,同時實體類GlrolemenuModel
里也要加上private MenuModel menu
--> <result property="menu.menuName" column="menu_name" /> <result property="menu.url" column="url" /> </resultMap> <select id="glrolemenu_getAllGlrolemenuAndMenu" resultMap="glrolemenu_menu_map"> select gl_role_menu.id, gl_role_menu.role_id, gl_role_menu.menu_id, menu.menu_name, menu.url from gl_role_menu left join menu on gl_role_menu.menu_id = menu.id;<!-- 一個簡單的關聯查詢 --> </select>

GlrolemenuDao

List<GlrolemenuModel> getAllGlrolemenuAndMenu();

GlrolemenuDaoImpl

public List<GlrolemenuModel> getAllGlrolemenuAndMenu() {
        return baseDao.selectList("com.tieasy.model.mapper.glrolemenu_getAllGlrolemenuAndMenu", null);
    }

Action里調用接口實現方法

List<GlrolemenuModel> list = glrolemenuDao.getAllGlrolemenuAndMenu();

返回list的json

[{"id":"02ce54203c514b3ca176a3203957c222-1484040384-510","roleId":"02ce54203c514b3ca176a3203957ce0e-1484040384-581","menuId":"00dfcf127f4b4ba1bc8a891938519be0-1484040323-960","menu":{"menuName":"權限管理","url":"/quanxianguanli"}}]

一對一第二種寫法

這邊使用到了association,這個真的很神奇,原諒我很土鱉,和第一種的寫法區別不大,主要就是把被維護的哪一方MenuModel換成用<association>來寫

glrolemenuMapper.xml

淡黃色背景的就是改動的部分

<resultMap type="com.tieasy.model.MenuModel" id="menuResultMap">   
        <id property="id" column="id" />  
        <result property="menuName" column="menu_name" />   
        <result property="url" column="url" />       
    </resultMap>
    <resultMap type="com.tieasy.model.GlrolemenuModel" id="glrolemenu_menu_map">
        <id property="id" column="id" />
        <result property="roleId" column="role_id" />
        <result property="menuId" column="menu_id" />
        
        <association property="menu" resultMap="menuResultMap" />      
</resultMap>
<select id="glrolemenu_getAllGlrolemenuAndMenu" resultMap="glrolemenu_menu_map">
     select 
     gl_role_menu.id,
     gl_role_menu.role_id,
     gl_role_menu.menu_id,
     menu.menu_name,
     menu.url
     from gl_role_menu left join menu on gl_role_menu.menu_id = menu.id;
</select>

其它文件都不需要動

元素<association>被用來導入“有一個”(has-one)類型的關聯。在上述的例子中,我們使用了<association>元素引用了另外的在同一個XML文件中定義的<resultMap>。
同時我們也可以使用<association> 定義內聯的resultMap。

<resultMap type="com.tieasy.model.GlrolemenuModel" id="glrolemenu_menu_map">
        <id property="id" column="id" />
        <result property="roleId" column="role_id" />
        <result property="menuId" column="menu_id" />
        
        <association property="menu" javaType="com.tieasy.model.MenuModel" >
            <id property="id" column="id" />  
            <result property="menuName" column="menu_name" />   
            <result property="url" column="url" />  
        </association>      
</resultMap>
<select id="glrolemenu_getAllGlrolemenuAndMenu" resultMap="glrolemenu_menu_map">
     select 
     gl_role_menu.id,
     gl_role_menu.role_id,
     gl_role_menu.menu_id,
     menu.menu_name,
     menu.url
     from gl_role_menu left join menu on gl_role_menu.menu_id = menu.id;
</select>

一對一第三種寫法

glrolemenuMapper.xml

還是只有映射文件有改變,但是我這邊是因為數據庫里每張表只有一條數據,所以其實實際id="glrolemenu_getAllGlrolemenuAndMenu"的這個select是要有個查詢條件parameterType,哎,我是有多懶。不過反正是查出來了。

在此方式中,<association>元素的select屬性被設置成了id為glrolemenu_getMenuById的語句。這里,兩個分開的SQL語句將會在數據庫中分別執行。

看看mybatis打印的信息,確定是分兩次查詢的

 

<resultMap type="com.tieasy.model.MenuModel" id="menuResultMap">   
        <id property="id" column="id" />  
        <result property="menuName" column="menu_name" />   
        <result property="url" column="url" />       
</resultMap>
<select id="glrolemenu_getMenuById" parameterType="String" resultMap="menuResultMap"> select id, menu_name, url from menu where id = #{id}; </select>
    
<resultMap type="com.tieasy.model.GlrolemenuModel" id="glrolemenu_menu_map">
        <id property="id" column="id" />
        <result property="roleId" column="role_id" />
        <!-- <result property="menuId" column="menu_id" /> -->
        
        <association property="menu" column="menu_id" select="glrolemenu_getMenuById" />
</resultMap>
<select id="glrolemenu_getAllGlrolemenuAndMenu" resultMap="glrolemenu_menu_map">
     select 
     id,
     role_id,
     menu_id
     from gl_role_menu;
</select>

 總結

這個mybatis一對一配置,對於我這種懶人我選的話可能會選第一二種寫法,但是需要強調的是第三種方法可以實現懶加載,因為它是分兩個sql先后執行的,當選擇懶加載的時候,只會執行第一個sql,只有當我們需要訪問到第二條sql的數據的時候,才會觸發它執行,這就是所謂的懶加載。

嗯,那什么,就和單例模式的餓漢模式和懶漢模式類似。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM