MyBatis一对多和多对一

在MyBatis3的过程中,文档上面一直在强调一个id的东西!在做这个实验的时候,也因为没有理解清楚id含义而导致一对多的“多”中也只有一条数据。id和result的唯一不同是id表示的结果将是当比较对象实例时用到的标识属性。这帮助来改进整体表现,特别是缓存和嵌入结果映射。所以不同数据的id应该唯一区别,不然导致数据结果集只有一条数据。

一、表

orders

建表语句:

CREATE TABLE `orders` (
`o_id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) DEFAULT NULL,
`price` decimal(11,0) DEFAULT NULL,
PRIMARY KEY (`o_id`),
UNIQUE KEY `o_id` (`o_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

persons

建表语句:

CREATE TABLE `person` (
`p_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`p_id`),
UNIQUE KEY `p_id` (`p_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二、实体

1.person

package com.kerwin.mybatis.pojo;

import java.util.List;

public class Person {

private int id;
private String name;
private List<Orders> orderList;

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 List<Orders> getOrderList() {
return orderList;
}

public void setOrderList(List<Orders> orderList) {
this.orderList = orderList;
}

@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}

public Person() {
super();
// TODO Auto-generated constructor stub
}

public Person(int id, String name, List<Orders> orderList) {
super();
this.id = id;
this.name = name;
this.orderList = orderList;
}

}

2.order

package com.kerwin.mybatis.pojo;public class Orders {
private int id;
private double price;
private Person person;public Person getPerson() {
return person;
}public void setPerson(Person person) {
this.person = person;
}public int getId() {
return id;
}public void setId(int id) {
this.id = id;
}public double getPrice() {
return price;
}public void setPrice(double price) {
this.price = price;
}

@Override
public String toString() {
return "Orders [id=" + id + ", price=" + price + "]";
}

public Orders() {
super();
// TODO Auto-generated constructor stub
}

}

三、映射mapper文件

1. PersonMapper.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.sinosig.xb.db.demo.dao.PersonMapper">
<resultMap id="BaseResultMap" type="com.sinosig.xb.db.demo.dao.model.Person">
<id column="p_id" property="pId" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
</resultMap><resultMap type="com.sinosig.xb.db.demo.dao.model.Person" id="personreSultMap">
<id column="p_id" property="pId" />
<result column="name" property="name" />
<collection property="orderList"
ofType="com.sinosig.xb.db.demo.dao.model.Orders" column="pid">
<id column="o_id" property="oId" />
<result column="price" property="price" />
</collection>
</resultMap>

<select id="selectPersonFetchOrder" parameterType="int"
resultMap="personreSultMap">
select p.*,o.* from person p,orders o where o.pid=p.p_id and
p.p_id=#{id}
</select>

<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" suffix=")" prefixOverrides="and">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value}
and
#{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem"
open="(" close=")" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<where>
<foreach collection="example.oredCriteria" item="criteria"
separator="or">
<if test="criteria.valid">
<trim prefix="(" suffix=")" prefixOverrides="and">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value}
and
#{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem"
open="(" close=")" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
p_id, name
</sql>
<select id="selectByExample" resultMap="BaseResultMap"
parameterType="com.sinosig.xb.db.demo.dao.model.PersonExample">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from person
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" resultMap="BaseResultMap"
parameterType="java.lang.Integer">
select
<include refid="Base_Column_List" />
from person
where p_id = #{pId,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from person
where p_id = #{pId,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="com.sinosig.xb.db.demo.dao.model.PersonExample">
delete from person
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="com.sinosig.xb.db.demo.dao.model.Person">
insert into person (p_id,
name)
values (#{pId,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.sinosig.xb.db.demo.dao.model.Person">
insert into person
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="pId != null">
p_id,
</if>
<if test="name != null">
name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="pId != null">
#{pId,jdbcType=INTEGER},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.sinosig.xb.db.demo.dao.model.PersonExample"
resultType="java.lang.Integer">
select count(*) from person
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update person
<set>
<if test="record.pId != null">
p_id = #{record.pId,jdbcType=INTEGER},
</if>
<if test="record.name != null">
name = #{record.name,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
update person
set p_id = #{record.pId,jdbcType=INTEGER},
name =
#{record.name,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="com.sinosig.xb.db.demo.dao.model.Person">
update person
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
</set>
where p_id = #{pId,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.sinosig.xb.db.demo.dao.model.Person">
update person
set
name = #{name,jdbcType=VARCHAR}
where p_id = #{pId,jdbcType=INTEGER}
</update>
</mapper>

2. OrdersMapper.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.kerwin.mybatis.pojo.Orders">
<resultMap type="com.kerwin.mybatis.pojo.Orders" id="OrdersResultMap">
<id column="o_id" property="id"/>
<result column="price" property="price"/>
<association property="person" javaType="com.kerwin.mybatis.pojo.Person">
<id column="p_id" property="id"/>
<result column="name" property="name"/>
</association>
</resultMap><select id="selectOrdersFetchPerson" resultMap="OrdersResultMap">
select p.*,o.* from person p,orders o where o.pid=p.p_id and o.o_id=#{id}
</select></mapper>

3.sqlMapConfig.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><typeAliases>
<typeAlias type="com.kerwin.mybatis.pojo.Author" alias="Author"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/kerwin/mybatis/pojo/AuthorMapper.xml"/>
<mapper resource="com/kerwin/mybatis/pojo/PostMapper.xml"/>
<mapper resource="com/kerwin/mybatis/pojo/PersonMapper.xml"/>
<mapper resource="com/kerwin/mybatis/pojo/OrdersMapper.xml"/>
</mappers>
</configuration>

四。测试类

/**
*
*/
package com.kerwin.mybatis.test;import java.io.InputStream;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 org.junit.BeforeClass;
import org.junit.Test;import com.kerwin.mybatis.pojo.Orders;
import com.kerwin.mybatis.pojo.Person;/**
* @author Administrator
*
*/
public class PersonAndOrderTest {private static SqlSessionFactory sessionFactory;/**
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
sessionFactory = factoryBuilder.build(inputStream);}

//一对多,查询person(一)级联查询订单order(多)
@Test
public void testSelectPersonFetchOrder() throws Exception {
SqlSession session = sessionFactory.openSession();
Person person = session.selectOne("com.kerwin.mybatis.pojo.Person.selectPersonFetchOrder", 1);
System.out.println(person);
System.out.println(person.getOrderList().size());
for(Orders orders : person.getOrderList()){
System.out.println(orders);
}
session.close();
}

//多对一,查询订单order(多)级联查询person(一)
@Test
public void testSelectOrdersFetchPerson() throws Exception{
SqlSession session = sessionFactory.openSession();
Orders orders = session.selectOne("com.kerwin.mybatis.pojo.Orders.selectOrdersFetchPerson", 1);
System.out.println(orders);
System.out.println(orders.getPerson());
session.close();
}

}

五、测试结果

1.一对多,查询person(一)级联查询订单order(多)

2.多对一,查询订单order(多)级联查询person(一)

注意:两张表中的主键id字段名要唯一,例如不能都写id,不然的话,在一对多查询的时候就会出现:级联出来的订单项只有一条记录。我之前就是将两张表的主键id字段名都写为id,导致测试结果级联出来的多一直只有一条数据,具体如下:

发表评论