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的數據的時候,才會觸發它執行,這就是所謂的懶加載。
嗯,那什麽,就和單例模式的餓漢模式和懶漢模式類似。
mybatis一對一映射配置詳解