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

              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依赖

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6     <groupId>cn.org.yinzhengjie</groupId>
 7     <artifactId>Mybatis</artifactId>
 8     <version>1.0-SNAPSHOT</version>
 9     <dependencies>
10         <dependency>
11             <groupId>junit</groupId>
12             <artifactId>junit</artifactId>
13             <version>4.11</version>
14         </dependency>
15         <dependency>
16             <groupId>mysql</groupId>
17             <artifactId>mysql-connector-java</artifactId>
18             <version>5.1.17</version>
19         </dependency>
20         <dependency>
21             <groupId>org.mybatis</groupId>
22             <artifactId>mybatis</artifactId>
23             <version>3.2.1</version>
24         </dependency>
25     </dependencies>
26 </project>

二.编写自定义类

1>.编写Customer类

 1 /*
 2 @author :yinzhengjie
 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
 4 EMAIL:y1053419035@qq.com
 5 */
 6 package cn.org.yinzhengjie.mybatis.domain.one2many;
 7 
 8 import java.util.ArrayList;
 9 import java.util.List;
10 
11 /**
12  *    客户
13  */
14 public class Customer {
15     private Integer id ;
16     private String name ;
17     private int age ;
18 
19     //建立从Customer到Order之间一对多关系,因为一个客户可能会有多个订单。我们将多个订单放在一个list中。
20     private List<Order> orders = new ArrayList<Order>() ;
21 
22     public List<Order> getOrders() {
23         return orders;
24     }
25 
26     public void setOrders(List<Order> orders) {
27         this.orders = orders;
28     }
29 
30     public Integer getId() {
31         return id;
32     }
33 
34     public void setId(Integer id) {
35         this.id = id;
36     }
37 
38     public String getName() {
39         return name;
40     }
41 
42     public void setName(String name) {
43         this.name = name;
44     }
45 
46     public int getAge() {
47         return age;
48     }
49 
50     public void setAge(int age) {
51         this.age = age;
52     }
53 }

2>.编写Order类

 1 /*
 2 @author :yinzhengjie
 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
 4 EMAIL:y1053419035@qq.com
 5 */
 6 package cn.org.yinzhengjie.mybatis.domain.one2many;
 7 
 8 /**
 9  * 订单
10  */
11 public class Order {
12     private Integer id ;
13     private String orderno ;
14     private float price  ;
15     //建立从Order到Customer之间多对一关联关系
16     private Customer customer ;
17 
18     public Integer getId() {
19         return id;
20     }
21 
22     public void setId(Integer id) {
23         this.id = id;
24     }
25 
26     public String getOrderno() {
27         return orderno;
28     }
29 
30     public void setOrderno(String orderno) {
31         this.orderno = orderno;
32     }
33 
34     public float getPrice() {
35         return price;
36     }
37 
38     public void setPrice(float price) {
39         this.price = price;
40     }
41 
42     public Customer getCustomer() {
43         return customer;
44     }
45 
46     public void setCustomer(Customer customer) {
47         this.customer = customer;
48     }
49 }

三.编写配置文件

1>.mybatis-config.xml 文件内容

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <properties>
 7         <property name="driver" value="com.mysql.jdbc.Driver"/>
 8         <property name="url" value="jdbc:mysql://localhost:5200/yinzhengjie"/>
 9         <property name="username" value="root"/>
10         <property name="password" value="yinzhengjie"/>
11     </properties>
12 
13     <!-- 我们使用typeAliases标签给我们自定义类起个别名。-->
14     <typeAliases>
15         <typeAlias type="cn.org.yinzhengjie.mybatis.domain.one2many.Customer" alias="_Customer" />
16         <typeAlias type="cn.org.yinzhengjie.mybatis.domain.one2many.Order" alias="_Order" />
17     </typeAliases>
18 
19     <environments default="development">
20         <environment id="development">
21             <transactionManager type="JDBC"/>
22             <dataSource type="POOLED">
23                 <property name="driver" value="${driver}"/>
24                 <property name="url" value="${url}"/>
25                 <property name="username" value="${username}"/>
26                 <property name="password" value="${password}"/>
27             </dataSource>
28         </environment>
29     </environments>
30     <mappers>
31         <!-- 我们使用mapper标签指定映射文件,使用resource指定具体的路径,如果没有写绝对路径,默认的根路径就在resources目录中-->
32         <mapper resource="CustomerMapper.xml"/>
33         <mapper resource="OrderMapper.xml"/>
34     </mappers>
35 </configuration>

2>.OrderMapper.xml 文件内容

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <!-- 定义名字空间 -->
 5 <mapper namespace="orders">
 6     <insert id="insert">
 7         <!-- 注意,我们传递的参数 #{customer.id}是对象的属性,因此,这里千万别写cid,尽管我们在创建数据库中定义的有这个字段,但是我们在定义类的时候是把它定义为对象的一个属性! -->
 8         insert into orders(orderno, price , cid) values(#{orderno}, #{price} , #{customer.id}) ;
 9     </insert>
10 
11     <!--用resultMap标签定义数据库的查询结果映射,这个结果不能直接和我们自定义的类进行交互,需要通过resultMap标签定义结果映射才能使用我们自定义的类接收数据。-->
12     <select id="selectOne" resultMap="rm_Order">
13         SELECT
14         <!-- 定义需要查询的别名 -->
15           o.id oid ,
16           o.orderno oorderno ,
17           o.price oprice ,
18           o.cid ocid ,
19           c.id cid ,
20           c.name cname ,
21           c.age cage
22         FROM
23         <!-- 定义需要查询的字段 -->
24           orders o
25         <!-- 使用左外连接查询 -->
26           LEFT  OUTER JOIN  customers c on o.cid = c.id
27         where
28           o.id = #{id}
29     </select>
30     <select id="selectAll" resultMap="rm_Order">
31         SELECT
32           o.id oid ,
33           o.orderno oorderno ,
34           o.price oprice ,
35           o.cid ocid ,
36           c.id cid ,
37           c.name cname ,
38           c.age cage
39         FROM
40           orders o
41           LEFT  OUTER JOIN  customers c on o.cid = c.id
42     </select>
43 
44     <!-- 使用resultMap标签定义结果映射,即将id为"rm_Order"的查询结果和我们自定义的类做一个关联关系,否则直接拿查询出来的结果字段和我们自定义的字段是对应不上的!-->
45     <resultMap id="rm_Order" type="_Order">
46         <!--将查询结果“oid”字段对应为我们自定义别名类“_Order”的“id"字段-->
47         <id column="oid" property="id" />
48         <result column="oorderno" property="orderno"/>
49         <result column="oprice" property="price"/>
50 
51 
52         <!-- 多对一关联关系 -->
53         <!-- 使用association这个标签可以建立关联属性, property表示"_Order"的属性,column是通过上面定义的"ocid"别名来查询的,而javaType表示指定"customer"岁对应的属性为"_Customer" -->
54         <association property="customer" column="ocid" javaType="_Customer">
55             <!--下面就是具体的对应关系。-->
56             <id column="cid" property="id" />
57             <result column="cname" property="name" />
58             <result column="cage" property="age" />
59         </association>
60     </resultMap>
61 </mapper>

3>.CustomerMapper.xml 文件内容

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <!-- 定义名字空间 -->
 5 <mapper namespace="customers">
 6     <!-- useGeneratedKeys的值为true时,表示需要使用数据库深层的keys,同时我们需要指定使用哪个深层的key。而指定具体使用哪个key我们使用keyProperty来定义! -->
 7     <insert id="insert" useGeneratedKeys="true" keyProperty="id">
 8         <!-- 注意,#{name}, #{age}中的name和age字样必须和我们自定义类要一致哟! -->
 9         insert into customers(name, age) values(#{name}, #{age}) ;
10     </insert>
11 
12     <!--用resultMap标签定义数据库的查询结果映射,这个结果不能直接和我们自定义的类进行交互,需要通过resultMap标签定义结果映射才能使用我们自定义的类接收数据。-->
13     <select id="selectOne" resultMap="rm_Customer">
14         select
15           c.id cid ,
16           c.name cname ,
17           c.age cage ,
18           o.id oid ,
19           o.orderno oorderno ,
20           o.price oprice ,
21           o.cid ocid
22         from
23           customers c left outer join orders o on o.cid = c.id
24         where
25           c.id = #{id} ;
26     </select>
27 
28     <resultMap id="rm_Customer" type="_Customer">
29         <id column="cid" property="id"/>
30         <result column="cname" property="name"/>
31         <result column="cage" property="age"/>
32         <!--使用collection这个标签可以建立关联属性。多对一关系映射-->
33         <collection property="orders" ofType="_Order" column="ocid">
34             <id column="oid" property="id"/>
35             <result column="oorderno" property="orderno" />
36             <result column="oprice" property="price"/>
37         </collection>
38     </resultMap>
39 
40 </mapper>

四.编写测试代码

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

 1 /*
 2 @author :yinzhengjie
 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
 4 EMAIL:y1053419035@qq.com
 5 */
 6 package cn.org.yinzhengjie.mybatis.test;
 7 
 8 import cn.org.yinzhengjie.mybatis.domain.one2many.Customer;
 9 import cn.org.yinzhengjie.mybatis.domain.one2many.Order;
10 import org.apache.ibatis.io.Resources;
11 import org.apache.ibatis.session.SqlSession;
12 import org.apache.ibatis.session.SqlSessionFactory;
13 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
14 import org.junit.Test;
15 
16 import java.io.InputStream;
17 import java.util.List;
18 
19 
20 public class TestOne2Many {
21     /**
22      * 测试往Customer插入指定的数据
23      */
24     @Test
25     public void testInsertCustomer() throws Exception {
26         InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
27         SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
28         SqlSession sess = sf.openSession();
29         Customer c = new Customer();
30         c.setName("yinzhengjie");
31         c.setAge(18);
32         sess.insert("customers.insert", c);
33 
34         Order o = new Order();
35         o.setOrderno("no001");
36         o.setPrice(100);
37         //设置关联关系
38         o.setCustomer(c);
39 
40         sess.insert("orders.insert" , o) ;
41         sess.commit();
42         sess.close();
43     }
44 
45     /**
46      * 测试查询指定的order
47      */
48     @Test
49     public void testSelectOneOrder() throws Exception {
50         InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
51         SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
52         SqlSession sess = sf.openSession();
53         Order o = sess.selectOne("orders.selectOne" , 1);
54         System.out.println(o.getOrderno());
55         List<Order> orders = sess.selectList("orders.selectAll");
56         for(Order obj : orders){
57             System.out.print(obj.getOrderno());
58             Customer c = obj.getCustomer() ;
59             if(c != null){
60                 System.out.println(c.getName());
61             }
62             else{
63                 System.out.println();
64             }
65         }
66         sess.commit();
67         sess.close();
68     }
69 
70 
71     /**
72      * 测试查询指定的Customer
73      */
74     @Test
75     public void testSelectCustomer() throws Exception {
76         InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
77         SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
78         SqlSession sess = sf.openSession();
79         Customer c = sess.selectOne("customers.selectOne" , 1);
80         for(Order o : c.getOrders()){
81             System.out.println(o.getId() + "  " + o.getOrderno());
82         }
83         sess.commit();
84         sess.close();
85     }
86 }

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

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