Mybatis之基于XML的表之间映射
数据库表之间的关系有3种,一对一、一对多、多对多。既然是ORM,这肯定是必须有的。在学习EF的时候也有涉及,今天就是参考着EF的来学习下MyBatis的表关系映射。
一、准备工作
1.准备Model和Table
既然是要涉及表的一对一、一对多、多对多的关系,那肯定得先准备好实体关系,以及表。下面建了四个对象四个表。User<->Card是一对一关系,User<->Course一对多关系,User<->Role多对多关系。
User
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`status` varchar(20) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
package Cuiyw.MyBatis.Model;
import java.util.List;
public class User {
@Override
public String toString() {
// TODO Auto-generated method stub
return "User [id=" + Id + ", name=" + Name + ", age=" + Age + ",status="+Status+"]";
}
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
private int Id;
private String Name;
private int Age;
private UserState Status;
private Card card;
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
private List<Role> roles;
private List<Course> courses;
public List<Course> getCourses() {
return courses;
}
public void setCourses(List<Course> courses) {
this.courses = courses;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public UserState getStatus() {
return Status;
}
public void setStatus(UserState status) {
this.Status = status;
}
}
Card
CREATE TABLE `card` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cardNo` varchar(20) NOT NULL,
`city` varchar(45) NOT NULL,
`address` varchar(100) NOT NULL,
`userid` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
package Cuiyw.MyBatis.Model;
public class Card {
@Override
public String toString() {
// TODO Auto-generated method stub
return "Card [id=" + getId() + ", cardNo=" + cardNo + ", city=" + city + ",address="+address+",userid="+userid+"]";
}
private int id;
private String cardNo;
private String city;
private String address;
private int userid;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
Course
CREATE TABLE `course` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`userid` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
package Cuiyw.MyBatis.Model;
public class Course {
@Override
public String toString() {
// TODO Auto-generated method stub
return "Course [id=" + getId() + ", name=" + name +",userid="+userid+"]";
}
private int id;
private String name;
private int userid;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Role
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`desp` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
package Cuiyw.MyBatis.Model;
import java.util.List;
public class Role {
@Override
public String toString() {
// TODO Auto-generated method stub
return "Role [id=" + getId() + ", name=" + name +",desp="+desp+"]";
}
private int id;
private String name;
private String desp;
private List<User> users;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesp() {
return desp;
}
public void setDesp(String desp) {
this.desp = desp;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
User_Role
CREATE TABLE `user_role` (
`userid` int(11) NOT NULL,
`roleid` int(11) NOT NULL,
PRIMARY KEY (`userid`,`roleid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.准备映射
上一篇博客是单个表的映射关系,我们也先把但表的映射准备好。
<resultMap type="Card" id="cardResult">
<result column="id" property="id"/>
<result column="no" property="cardNo"/>
<result column="city" property="city"/>
<result column="address" property="address"/>
<result column="userid" property="userid"/>
</resultMap> <resultMap type="Course" id="courseResult">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="userid" property="userid"/>
</resultMap>
<resultMap type="Role" id="roleResult">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="desp" property="desp"/>
<result column="userid" property="userid"/>
</resultMap>
二、关系映射
加入我们需要执行下面的sql查询数据,那怎么映射到实体model上呢?
<select id="getuser" parameterType="int"
resultType="User" resultMap="userResult">
select a.id as user_id,a.name as user_name,a.age as user_age,a.status as user_status,
b.id as card_id,b.cardNo as card_cardNo,b.userid as card_userid,
b.city as card_city,b.address as card_address,c.id as course_id,c.name as course_name,
c.userid as course_userid,e.name as role_name,e.desp as role_desp
from user a left join card b on a.id=b.userid
left join course c on a.id=c.userid
left join user_role d on a.id=d.userid
left join role e on d.roleid=e.id where a.id=#{id}
</select>

我们可以这样写来映射User。
<resultMap type="User" id="userResult">
<result column="user_id" property="id"/>
<result column="user_name" property="name"/>
<result column="user_age" property="age"/>
<result column="user_status" property="status" typeHandler="Cuiyw.MyBatis.Model.ValuedEnumTypeHandler"/>
<association property="card" javaType="Card" columnPrefix="card_">
<result column="id" property="id"/>
<result column="no" property="cardNo"/>
<result column="city" property="city"/>
<result column="address" property="address"/>
<result column="userid" property="userid"/>
</association>
<collection property="courses" javaType="ArrayList" ofType="Course" columnPrefix="course_">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="userid" property="userid"/>
</collection>
<collection property="roles" javaType="ArrayList" ofType="Role" columnPrefix="role_">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="desp" property="desp"/>
<result column="userid" property="userid"/>
</collection>
</resultMap>
上面的xml种有两个重要的节点。
association关联:关联的结果查询,就是在查询出结果后,根据查询的列和resultMap定义的对应关系,来创建对象并写入值,例如user的card属性。
collection:用来映射class中的List列表类型的属性。
还有就是JavaType和ofType:JavaType和ofType都是用来指定对象类型的,但是JavaType是用来指定pojo中属性的类型,而ofType指定的是映射到list集合属性中pojo的类型。
三、优化
上面的xml配置确实可以映射User,但是在映射Card、Course和Role的时候把映射关系都放在的id=userResult的resultMap中,这样如果以后还有要映射Card、Course、Role的时候还要再写一遍,复用性不高。其实我们可以在association和collection节点增加属性resultMap。
<resultMap type="User" id="userResult">
<result column="user_id" property="id"/>
<result column="user_name" property="name"/>
<result column="user_age" property="age"/>
<result column="user_status" property="status" typeHandler="Cuiyw.MyBatis.Model.ValuedEnumTypeHandler"/>
<association property="card" javaType="Card" resultMap="cardResult" columnPrefix="card_"></association>
<collection property="courses" javaType="ArrayList" ofType="Course" resultMap="courseResult" columnPrefix="course_"></collection>
<collection property="roles" javaType="ArrayList" ofType="Role" resultMap="roleResult" columnPrefix="role_"></collection>
</resultMap>
而resultMap的值正是我们上面单表准备的映射resultMap。
四、验证
//mybatis的配置文件
String resource = "Config.xml";
//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession(true);
// System.out.println("新增");
String statement="Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
System.out.println("查询单个");
statement="Cuiyw.MyBatis.DBMapping.UserMapper.getuser";
User user=session.selectOne(statement, 2);
Card card=user.getCard(); List<Course>courses=user.getCourses();
List<Role>roles=user.getRoles();
session.close();
System.out.println(user.toString());
System.out.println(card.toString());
for(int i=0;i<courses.size();i++)
{
System.out.println(courses.get(i).toString());
}
for(int i=0;i<roles.size();i++)
{
System.out.println(roles.get(i).toString());
}

五、总结
这篇主要是学习表的关系映射,association、collection的使用,上面演示了一对一、一对多,对于多对多,可以把它当作两个一对多,这里只是演示了User对Role的一对多,Role对User的也是一样,这里就省了。具体可以参考官网:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html
Mybatis之基于XML的表之间映射的更多相关文章
- MyBatis之基于XML的属性与列名映射
上一博客主要是对单表的增删改查,比较简单,而且每个属性与table表的列都是一一对应名字也一样,今天主要学习属性与table表列名不一致的处理,主要有两种一是属性与列名不一致,二是枚举的情况,这里暂时 ...
- Mybatis之基于XML的增删改查
这里先吐槽下,写的半天的东西,IE浏览器弹出调试窗口导致写的东西全部没保存,搞得我还要重新用谷歌写,思路全没了,fuck. 前面学习了下spring的DAO层,说起DAO层,那ORM肯定是少不了的,O ...
- MyBatis框架基于XML的配置
什么是MyBatis? 答:它是一个持久层框架 说的太简单了吗?那让我们来看一下官方的文档描述: MyBatis有什么作用呢? 1.持久层的零实现 2.可以自动将数据封装到对象里面不需要手工编写映射的 ...
- MyBatis之基于XML的动态SQL
先说下我的梦想,大学的时候一直想着是能开店卖胡辣汤,到目前依然还是我的梦想,上周一家出版社联系我问我有没有时间可以合作出书,这也是我的梦想之一,想了想还是放弃了,至少觉得目前不行,毕竟工作还不到五年, ...
- Mybatis之基于XML的调用存储过程与手动回滚事务
一.调用存储过程 一.返回单个值 1.存储过程准备 这里先创建一个存储过程,传入参数为age,传出参数为count.然后先测试一下是否正确. CREATE DEFINER=`root`@`localh ...
- Mybatis基于接口注解配置SQL映射器(一)
上文已经讲解了基于XML配置的SQL映射器,在XML配置的基础上MyBatis提供了简单的Java注解,使得我们可以不配置XML格式的Mapper文件,也能方便的编写简单的数据库操作代码. Mybat ...
- Mybatis 联合查询XML与注解对比
由于是练习,故只做了感兴趣的一部分测试. 测试类容XML配置转注解方式 实体类为了测试请忽略设计是否合理… User.java @Alias("User")public class ...
- SpringBoot集成Mybatis实现多表查询的两种方式(基于xml)
下面将在用户和账户进行一对一查询的基础上进行介绍SpringBoot集成Mybatis实现多表查询的基于xml的两种方式. 首先我们先创建两个数据库表,分别是user用户表和account账户表 ...
- mybatis学习笔记(四)-- 为实体类定义别名两种方法(基于xml映射)
下面示例在mybatis学习笔记(二)-- 使用mybatisUtil工具类体验基于xml和注解实现 Demo的基础上进行优化 以新增一个用户为例子,原UserMapper.xml配置如下: < ...
随机推荐
- Tableau Desktop 10.4.2 的安装和激活
在安装之前,首先我们要弄清楚Tableau是个什么鬼东西,我们为什么需要安装这款软件? Tableau将数据运算与美观的图表完美地嫁接在一起.它的程序很容易上手,各公司可以用它将大量数据拖放到数字&q ...
- 一个两年java程序猿的2017个人总结
前言 又到了一年中最后的日子了,相信有不少公司要求员工写年度总结了,我也不例外.不过个人感觉在公司的写个年度总结来说,过于模板化了.其实很多没有必要.总之,本篇的个人总结,是按照个人的想法写的.简而言 ...
- Linux(CentOS6.5)下创建新用户和组,并制定用户和组ID
相关命令: groupadd -g 888 comexgroup useradd comex -d /comexHome -g comexgroup -u 888 cp /etc/skel/.* /c ...
- Linux(CentOS6.5_X86.64)编译libjpeg出现“checking host system type... Invalid configuration `x86_64-unknown-linux-gnu': machine `x86_64-unknown' not recognized”的解决
本文地址http://comexchan.cnblogs.com/,作者Comex Chan,尊重知识产权,转载请注明出处,谢谢! 今天在编译libjpeg 的时候,遇到下面的报错: checki ...
- 4.1 State Snapshot Transfer
摘要: 出处:黑洞中的奇点 的博客 http://www.cnblogs.com/kelvin19840813/ 您的支持是对博主最大的鼓励,感谢您的认真阅读.本文版权归作者所有,欢迎转载,但请保留该 ...
- vue-router源码学习(一)
因为v3.01版本中的 /src代码使用TypeScript进行书写,我这里仅仅用作模块学习, 具体学习的还是 /dist/vue-router.js 代码. (一)基本使用方式 JS代码 // ...
- Python学习_09_模块
模块 模块是python中的最高组织单元,在物理层面上,模块以文件存储,模块的文件名就是模块的名字.py,每个模块都有自己的名称空间. python按照路径搜索来查找模块文件,在PYTHONPATH环 ...
- grep命令及基本正则表达式
grep命令是Linux系统中一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来. grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功 ...
- Head First设计模式之观察者模式
一.定义 观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新. 有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多 ...
- Struts2思维导图
自己感觉自己的知识不是很扎实,所以昨天留时间复习知识,昨天边复习边画了一个思维导图.不知道自己画的对不对,还没有画完.有错的地方大家请和我说.希望自己能更加牢固的记住这些知识. 不说废话,开图.图有点 ...