Java基础-SSM之mybatis一对多和多对一关系映射

时间:2021-08-09 16:44:05

              Java基础-SSM之mybatis一对多和多对一关系映射

                                      作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.准备测试环境(创建数据库表)

 1>.创建customers表;

use yinzhengjie;

create table if not exists customers(id int primary key auto_increment,name varchar(20) , age int) ;

Java基础-SSM之mybatis一对多和多对一关系映射

2>.创建orders表

use yinzhengjie;

create table orders(id int primary key auto_increment , orderno varchar(20) , price float , cid int) ;

Java基础-SSM之mybatis一对多和多对一关系映射

 3>.创建指定的包名和文件,具体结构如下:

Java基础-SSM之mybatis一对多和多对一关系映射

4>.添加Maven依赖

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.org.yinzhengjie</groupId>
<artifactId>Mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.17</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
</project>

二.编写自定义类

1>.编写Customer类

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.mybatis.domain.one2many; import java.util.ArrayList;
import java.util.List; /**
* 客户
*/
public class Customer {
private Integer id ;
private String name ;
private int age ; //建立从Customer到Order之间一对多关系,因为一个客户可能会有多个订单。我们将多个订单放在一个list中。
private List<Order> orders = new ArrayList<Order>() ; public List<Order> getOrders() {
return orders;
} public void setOrders(List<Order> orders) {
this.orders = orders;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}

2>.编写Order类

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.mybatis.domain.one2many; /**
* 订单
*/
public class Order {
private Integer id ;
private String orderno ;
private float price ;
//建立从Order到Customer之间多对一关联关系
private Customer customer ; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getOrderno() {
return orderno;
} public void setOrderno(String orderno) {
this.orderno = orderno;
} public float getPrice() {
return price;
} public void setPrice(float price) {
this.price = price;
} public Customer getCustomer() {
return customer;
} public void setCustomer(Customer customer) {
this.customer = customer;
}
}

三.编写配置文件

1>.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>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:5200/yinzhengjie"/>
<property name="username" value="root"/>
<property name="password" value="yinzhengjie"/>
</properties> <!-- 我们使用typeAliases标签给我们自定义类起个别名。-->
<typeAliases>
<typeAlias type="cn.org.yinzhengjie.mybatis.domain.one2many.Customer" alias="_Customer" />
<typeAlias type="cn.org.yinzhengjie.mybatis.domain.one2many.Order" alias="_Order" />
</typeAliases> <environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 我们使用mapper标签指定映射文件,使用resource指定具体的路径,如果没有写绝对路径,默认的根路径就在resources目录中-->
<mapper resource="CustomerMapper.xml"/>
<mapper resource="OrderMapper.xml"/>
</mappers>
</configuration>

2>.OrderMapper.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="orders">
<insert id="insert">
<!-- 注意,我们传递的参数 #{customer.id}是对象的属性,因此,这里千万别写cid,尽管我们在创建数据库中定义的有这个字段,但是我们在定义类的时候是把它定义为对象的一个属性! -->
insert into orders(orderno, price , cid) values(#{orderno}, #{price} , #{customer.id}) ;
</insert> <!--用resultMap标签定义数据库的查询结果映射,这个结果不能直接和我们自定义的类进行交互,需要通过resultMap标签定义结果映射才能使用我们自定义的类接收数据。-->
<select id="selectOne" resultMap="rm_Order">
SELECT
<!-- 定义需要查询的别名 -->
o.id oid ,
o.orderno oorderno ,
o.price oprice ,
o.cid ocid ,
c.id cid ,
c.name cname ,
c.age cage
FROM
<!-- 定义需要查询的字段 -->
orders o
<!-- 使用左外连接查询 -->
LEFT OUTER JOIN customers c on o.cid = c.id
where
o.id = #{id}
</select>
<select id="selectAll" resultMap="rm_Order">
SELECT
o.id oid ,
o.orderno oorderno ,
o.price oprice ,
o.cid ocid ,
c.id cid ,
c.name cname ,
c.age cage
FROM
orders o
LEFT OUTER JOIN customers c on o.cid = c.id
</select> <!-- 使用resultMap标签定义结果映射,即将id为"rm_Order"的查询结果和我们自定义的类做一个关联关系,否则直接拿查询出来的结果字段和我们自定义的字段是对应不上的!-->
<resultMap id="rm_Order" type="_Order">
<!--将查询结果“oid”字段对应为我们自定义别名类“_Order”的“id"字段-->
<id column="oid" property="id" />
<result column="oorderno" property="orderno"/>
<result column="oprice" property="price"/> <!-- 多对一关联关系 -->
<!-- 使用association这个标签可以建立关联属性, property表示"_Order"的属性,column是通过上面定义的"ocid"别名来查询的,而javaType表示指定"customer"岁对应的属性为"_Customer" -->
<association property="customer" column="ocid" javaType="_Customer">
<!--下面就是具体的对应关系。-->
<id column="cid" property="id" />
<result column="cname" property="name" />
<result column="cage" property="age" />
</association>
</resultMap>
</mapper>

3>.CustomerMapper.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="customers">
<!-- useGeneratedKeys的值为true时,表示需要使用数据库深层的keys,同时我们需要指定使用哪个深层的key。而指定具体使用哪个key我们使用keyProperty来定义! -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
<!-- 注意,#{name}, #{age}中的name和age字样必须和我们自定义类要一致哟! -->
insert into customers(name, age) values(#{name}, #{age}) ;
</insert> <!--用resultMap标签定义数据库的查询结果映射,这个结果不能直接和我们自定义的类进行交互,需要通过resultMap标签定义结果映射才能使用我们自定义的类接收数据。-->
<select id="selectOne" resultMap="rm_Customer">
select
c.id cid ,
c.name cname ,
c.age cage ,
o.id oid ,
o.orderno oorderno ,
o.price oprice ,
o.cid ocid
from
customers c left outer join orders o on o.cid = c.id
where
c.id = #{id} ;
</select> <resultMap id="rm_Customer" type="_Customer">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
<result column="cage" property="age"/>
<!--使用collection这个标签可以建立关联属性。多对一关系映射-->
<collection property="orders" ofType="_Order" column="ocid">
<id column="oid" property="id"/>
<result column="oorderno" property="orderno" />
<result column="oprice" property="price"/>
</collection>
</resultMap> </mapper>

四.编写测试代码

1>.编写测试代码如下:

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.mybatis.test; import cn.org.yinzhengjie.mybatis.domain.one2many.Customer;
import cn.org.yinzhengjie.mybatis.domain.one2many.Order;
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.Test; import java.io.InputStream;
import java.util.List; public class TestOne2Many {
/**
* 测试往Customer插入指定的数据
*/
@Test
public void testInsertCustomer() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
SqlSession sess = sf.openSession();
Customer c = new Customer();
c.setName("yinzhengjie");
c.setAge(18);
sess.insert("customers.insert", c); Order o = new Order();
o.setOrderno("no001");
o.setPrice(100);
//设置关联关系
o.setCustomer(c); sess.insert("orders.insert" , o) ;
sess.commit();
sess.close();
} /**
* 测试查询指定的order
*/
@Test
public void testSelectOneOrder() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
SqlSession sess = sf.openSession();
Order o = sess.selectOne("orders.selectOne" , 1);
System.out.println(o.getOrderno());
List<Order> orders = sess.selectList("orders.selectAll");
for(Order obj : orders){
System.out.print(obj.getOrderno());
Customer c = obj.getCustomer() ;
if(c != null){
System.out.println(c.getName());
}
else{
System.out.println();
}
}
sess.commit();
sess.close();
} /**
* 测试查询指定的Customer
*/
@Test
public void testSelectCustomer() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
SqlSession sess = sf.openSession();
Customer c = sess.selectOne("customers.selectOne" , 1);
for(Order o : c.getOrders()){
System.out.println(o.getId() + " " + o.getOrderno());
}
sess.commit();
sess.close();
}
}

2>.查询数据库执行结果如下:

Java基础-SSM之mybatis一对多和多对一关系映射