MyBatis框架一对一与一对多映射

情景实例

现有用户地址、信息两表如下

address

MyBatis框架一对一与一对多映射

user_info

MyBatis框架一对一与一对多映射

现在要实现使用mybatis实现查询某人的多个(收货)地址,或者查询某人的唯一收货地址

则需要通过MyBatis映射的方法去实现

情景一:一对多

为实现一个用户对应多条地址数据,需要创建自定义类Address同时在UserInfo类中添加List<Address>属性

UserInfo.java

package com.jd.vo;

import java.util.List;

public class UserInfo {

	private int id;
	private int age;
	private String userName;
	private String password;
	private String realName;
	private List<Address> list;
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	public List<Address> getList() {
		return list;
	}
	public void setList(List<Address> list) {
		this.list = list;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getRealName() {
		return realName;
	}
	public void setRealName(String realName) {
		this.realName = realName;
	}
}

Address.java

package com.jd.vo;

public class Address {

	private int id;
	private int userId;
	private String realName;
	private String mobile;
	private String address;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getUserId() {
		return userId;
	}
	public void setUserId(int userId) {
		this.userId = userId;
	}
	public String getRealName() {
		return realName;
	}
	public void setRealName(String realName) {
		this.realName = realName;
	}
	public String getMobile() {
		return mobile;
	}
	public void setMobile(String mobile) {
		this.mobile = mobile;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}	
}

创建mapper接口,接收UserInfo类型参数

public interface IUserInfoDao {

	//两个以上变量都需要添加param注解,否则mapper内需要使用arg0,arg1等来表示
	//如果传值是一个自定义对象,那么mapper的#{}内仅需写UserInfo类中对应的变量即可,且不需要注释
	UserInfo get(UserInfo  ui);
}

向mapper配置中添加映射

此时select标签中设定resultMap标签属性,resultMap标签可以自定义字段与成员变量之间的映射关系。注意:resultType和resultMap不能同时使用

由于返回的用户地址不止一个,按照自定义类UserInfo的属性

除userinfo表本身属性外,需要使用<collection>标签实现返回address的List集合

<?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.jd.userinfo.dao.IUserInfoDao">
	 <resultMap type="com.jd.vo.UserInfo" id="ui">
                <!-- column:指定列名 property:指定把当前列中的某个数据赋给Java类中的哪个属性-->
	 	<id column="ui_id" property="id"/>
	 	<result column="user_name" property="userName"/>
	 	<result column="password" property="password"/>
	 	<result column="ui_real_name" property="realName"/>
	 	<result column="age" property="age"/>
	 	<collection property="list" ofType="com.jd.vo.Address">
	 		<id column="address_id" property="id"/>
		 	<result column="addr_real_name" property="realName"/>
		 	<result column="mobile" property="mobile"/>
		 	<result column="address" property="address"/>
	 	</collection>
	 </resultMap>
	 <select id="get" resultMap="ui">
		select ui.id ui_id,user_name,password,ui.real_name ui_real_name,age,
		addr.id address_id,addr.real_name addr_real_name,mobile,address from user_info ui
		LEFT JOIN address addr on addr.user_id=ui.id
		where ui.id=#{id}
	</select>
</mapper>

测试如下:

public class Test {

	public static void main(String[] args) {
		try {
			InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
			SqlSession sqlSession = sqlSessionFactory.openSession();//注意此方式不会自动提交事务
			IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
			UserInfo ui = new UserInfo();
			ui.setId(2);
			UserInfo userInfo = userInfoDao.get(ui);
			System.out.println(userInfo.getList().size());
			sqlSession.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

MyBatis框架一对一与一对多映射

与预期吻合

情景二:一对一

若要一个用户对应一个地址,则需在UserInfo类中添加一个Address属性

MyBatis框架一对一与一对多映射

此时再使用<resultMap>标签时则需要使用<association>子标签来映射Address信息

<?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.jd.userinfo.dao.IUserInfoDao">
	 <resultMap type="com.jd.vo.UserInfo" id="ui">
	 	<id column="ui_id" property="id"/>
	 	<result column="user_name" property="userName"/>
	 	<result column="password" property="password"/>
	 	<result column="ui_real_name" property="realName"/>
	 	<result column="age" property="age"/>
	 	<association property="address" javaType="com.jd.vo.Address">
	 		<id column="address_id" property="id"/>
		 	<result column="addr_real_name" property="realName"/>
		 	<result column="mobile" property="mobile"/>
		 	<result column="address" property="address"/>
	 	</association>
	 </resultMap>
	 <select id="get" resultMap="ui">
		select ui.id ui_id,user_name,password,ui.real_name ui_real_name,age,
		addr.id address_id,addr.real_name addr_real_name,mobile,address from user_info ui
		LEFT JOIN address addr on addr.user_id=ui.id
		where ui.id=#{id}
	</select>
</mapper>

测试:

public class Test {

	public static void main(String[] args) {
		try {
			InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
			SqlSession sqlSession = sqlSessionFactory.openSession();
			IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
			UserInfo ui = new UserInfo();
			ui.setId(3);
			UserInfo userInfo = userInfoDao.get(ui);
			System.out.println(userInfo);
			sqlSession.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

MyBatis框架一对一与一对多映射

上一篇:【mybatis annotation】数据层框架应用--Mybatis(二) 基于注解实现数据的CRUD


下一篇:JAVA系列笔记十三之Mybatis