zoukankan      html  css  js  c++  java
  • 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) ;

    2>.创建orders表

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

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

    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>.查询数据库执行结果如下:

  • 相关阅读:
    在博客园里给图片加水印(canvas + drag)
    Chrome开发者工具使用指南
    《古剑奇谭3》千秋戏辅助工具(前端React制作)
    React中useEffect的源码解读
    关于为什么使用React新特性Hook的一些实践与浅见
    使用@babel/preset-typescript取代awesome-typescript-loader和ts-loader
    使用dva改造React旧项目的数据流方案
    在React旧项目中安装并使用TypeScript的实践
    安利一个绘制指引线的JS库leader-line
    微信小程序中悬浮窗功能的实现(主要探讨和解决在原生组件上的拖动)
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/9287306.html
Copyright © 2011-2022 走看看