1. 程式人生 > >mybatis一對一映射配置詳解

mybatis一對一映射配置詳解

技術分享 iat rom cti 加載 文件中 src 裏的 new

聽說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的數據的時候,才會觸發它執行,這就是所謂的懶加載。

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

mybatis一對一映射配置詳解