Mybatis和hibernate比起来,笔者认为hibernate比较适合懒人用,mybatis比较灵活易学,要自己写sql语句,适合喜欢写sql的用。不过个人还是喜欢hibernate多一点,毕竟先入为主。。

下午有空,写了一个关于用强大的ResultMap来进行一对多,多对一的关系映射。详细如下:

1.数据库表(User、Menu)

假设一个用户(User)对应多个菜单(Menu)。在设计数据库表的时候在menu表里加一个user_id的外键。

menu表脚本:

-- --------------------------------------------------------
-- 主机:                           127.0.0.1
-- 服务器版本:                        5.1.32-community - MySQL Community Server (GPL)
-- 服务器操作系统:                      Win32
-- HeidiSQL 版本:                  8.0.0.4396
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-- 正在导出表  test.menu 的数据:~4 rows (大约)
/*!40000 ALTER TABLE `menu` DISABLE KEYS */;
INSERT INTO `menu` (`mid`, `menu_name`, `uid`) VALUES
(1, '菜单1', 2),
(2, '菜单2', 2),
(3, '菜单3', 3),
(4, '用户管理', 3);
/*!40000 ALTER TABLE `menu` ENABLE KEYS */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

user表脚本:

-- --------------------------------------------------------
-- 主机:                           127.0.0.1
-- 服务器版本:                        5.1.32-community - MySQL Community Server (GPL)
-- 服务器操作系统:                      Win32
-- HeidiSQL 版本:                  8.0.0.4396
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-- 正在导出表  test.user 的数据:~3 rows (大约)
/*!40000 ALTER TABLE `user` DISABLE KEYS */;
INSERT INTO `user` (`uid`, `user_name`) VALUES
(1, '用户1'),
(2, '用户2'),
(3, '用户3');
/*!40000 ALTER TABLE `user` ENABLE KEYS */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

2.文件主目录:

【Mybatis】一对多、多对一关系映射_数据库表

3.Main.java  程序入口

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.test.bean.Menu;
import com.test.bean.MenuMapper;
import com.test.bean.User;
import com.test.bean.UserMapper;
public class Main {
private SqlSession session = null;
private UserMapper userMapper = null;
private MenuMapper menuMapper = null;
public static void main(String[] args) {
new Main();
}
public Main(){
//获得session
session = initSession();
userMapper = session.getMapper(UserMapper.class);
menuMapper = session.getMapper(MenuMapper.class);
getUserMenus();
if(null != session){
session.commit();
session.close();
}
}
//测试一对多
private void  getUserMenus() {
System.out.println(menuMapper.getMenu(2).getUser().getUserName());
List<Menu> menus =userMapper.getUser(3).getMenus();
for (Menu menu : menus) {
System.out.println(menu.getMenuName());
}
}
private SqlSession initSession(){
//获取配置文件的输入流
InputStream is;
try {
is = Resources.getResourceAsStream("mybatis-config.xml");
//获取我们的SqlSessionFactory(相当于Hibernate的SessionFactory);SqlSessionFactoryBuilder有点类似于Hibernate的Configuration。
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//获取一个Session
return sqlSessionFactory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

4.Menu和User两个POJO就不在这里废话了。

5.MenuMapper

package com.test.bean;
import java.util.List;
public interface MenuMapper {
//查找所有菜单
public List<Menu> getMenus(int uid);
//查找某个菜单
public Menu getMenu(int mid);
}

6.UserMapper

package com.test.bean;
import java.util.List;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
public interface UserMapper {
//个人认为sql语句用注解写在这里会更好
public User getUser(int uid);
}

7.UserMapper.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.test.bean.UserMapper">
<resultMap id="UserResult" type="User">
<id property="uid" column="uid"></id>
<result property="userName" column="user_name"></result>
<collection property="menus" column="uid" select="com.test.bean.MenuMapper.getMenus"></collection>
</resultMap>
<!-- 查询 -->
<select id="getUser" parameterType="int" resultType="User" resultMap="UserResult">
select * from user where uid = #{uid};
</select>
</mapper>

8.MenuMapper.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.test.bean.MenuMapper">
<resultMap id="MenuResult" type="Menu">
<result property="mid" column="mid"></result>
<result property="menuName" column="menu_name"></result>
<association property="user" javaType="User" column="uid" select="com.test.bean.UserMapper.getUser"/>
</resultMap>
<select id="getMenus" parameterType="int" resultType="Menu" resultMap="MenuResult">
select * from menu where uid=#{uid}
</select>
<select id="getMenu" parameterType="int" resultType="Menu" resultMap="MenuResult">
select * from menu where mid=#{mid}
</select>
</mapper>

9.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>
<!-- 引入配置信息文件 -->
<properties resource="mysql.properties" />
<!-- 必须放在environments和properties之间,不然解析xml会发生错误 -->
<typeAliases>
<typeAlias alias="User" type="com.test.bean.User" />
<typeAlias alias="Menu" type="com.test.bean.Menu" />
</typeAliases>
<environments default="demo">
<environment id="demo">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property value="${driver}" name="driver" />
<property value="${url}" name="url" />
<property value="${username}" name="username" />
<property value="${password}" name="password" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/test/bean/UserMapper.xml" />
<mapper resource="com/test/bean/MenuMapper.xml" />
</mappers>
</configuration>

//

10.mysql.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username=root
password=root

总结:易错点还是ResultMaper.xml里面的ResultMap属性设置。其中Collection是多方,Association是一方。返回一定要按ResultMap返回。