zoukankan      html  css  js  c++  java
  • Mybatis的一对多、多对一、多对多关系详解(案例)

    为什么需要关联关系?

    在实际世界中,我们的单一实体不可能与其他实体毫无关系,事实上每个个体之间都有千丝万缕的联系。而在程序设计中就必须要考虑实体之间的关联,我们通过数据库表与表之间的链接来体现这种关联关系,比如外键引用等,而多对多是比较复杂的情况,也是最能体现现实业务逻辑的一种情况,数据库没办法直接体现多对多的关联关系,所以我们设计两个表的中间表来替代这种复杂的引用,这就是现今普遍的解决方案。

    一对多和多对一

    现在我有两个表,客户表(t_customer)和订单表(t_order),订单表保存了客户表的外键引用,通过外键可以表示一对多和多对一的映射关系,文末将会提供sql脚本代码,可以直接通过左侧索引跳转。

    1) 实体类映射

    package com.star.model;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.List;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public class Customer {
        private Integer customerId;
    
        private String customerName;
        //实体层面的一对多映射
        private List<Order> orders;
    }
    Customer
    package com.star.model;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public class Order {
        private Integer orderId;
    
        private String orderNo;
    
        private Integer cid;
    
        //建立实体层面的映射关系
        private Customer customer;
    
    
    }
    Order

    2)mapper映射

    接口代码:

    package com.star.mapper;
    
    import com.star.model.Customer;
    import com.star.model.Order;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface CustomerMapper {
    
        int deleteByPrimaryKey(Integer customerId);
    
        int insert(Customer record);
    
        int insertSelective(Customer record);
    
        Customer selectByPrimaryKey(Integer customerId);
    
        int updateByPrimaryKeySelective(Customer record);
    
        int updateByPrimaryKey(Customer record);
    
        //通过客户id找到客户对应的订单
        List<Order> queryOrderByCustomer(Customer customer);
    
    }
    CustomerMapper
    package com.star.mapper;
    
    import com.star.model.Customer;
    import com.star.model.Order;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface OrderMapper {
        int deleteByPrimaryKey(Integer orderId);
    
        int insert(Order record);
    
        int insertSelective(Order record);
    
        Order selectByPrimaryKey(Integer orderId);
    
        int updateByPrimaryKeySelective(Order record);
    
        int updateByPrimaryKey(Order record);
    
        /*通过订单查询用户多对一*/
        Order queryCustomerByOrder(Order order);
    }
    OrderMapper

    xml映射:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd" >
    <!--客户映射-->
    <mapper namespace="com.star.mapper.CustomerMapper" >
      <resultMap id="BaseResultMap" type="com.star.model.Customer" >
        <constructor >
          <idArg column="customer_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
          <arg column="customer_name" jdbcType="VARCHAR" javaType="java.lang.String" />
        </constructor>
      </resultMap>
    
      <!-- 要返回的订单结果集(一对多) -->
      <resultMap id="baseOneToMany" type="com.star.model.Customer" >
        <!--定义主键-->
        <id column="customer_id" property="customerId" javaType="java.lang.Integer"/>
        <result column="customer_name" property="customerName" javaType="java.lang.String"/>
        <!-- 一对多的关系 -->
        <!-- property: 指的是集合属性的值, ofType:指的是集合中元素的类型 -->
        <collection property="orders" ofType="com.star.model.Order">
          <id column="order_id" property="orderId"/>
          <result column="order_no" property="orderNo"/>
          <result column="cid" property="cid"/>
        </collection>
      </resultMap>
    
      <sql id="Base_Column_List" >
        customer_id, customer_name
      </sql>
    
      <sql id="base_query_list">
        select <include refid="Base_Column_List"/> from t_customer where 1=1
      </sql>
    
      <!--找到客户对应订单映射sql-->
      <select id="queryOrderByCustomer" resultMap="baseOneToMany">
        select * from t_customer ct left join  t_order od on ct.customer_id=od.cid where 1=1
        <if test="customerId!=null">
          and customer_id = #{customerId}
        </if>
      </select>
    
      <insert id="insert" parameterType="com.star.model.Customer" >
        insert into t_customer (customer_id, customer_name)
        values (#{customerId,jdbcType=INTEGER}, #{customerName,jdbcType=VARCHAR})
      </insert>
      <insert id="insertSelective" parameterType="com.star.model.Customer" >
        insert into t_customer
        <trim prefix="(" suffix=")" suffixOverrides="," >
          <if test="customerId != null" >
            customer_id,
          </if>
          <if test="customerName != null" >
            customer_name,
          </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides="," >
          <if test="customerId != null" >
            #{customerId,jdbcType=INTEGER},
          </if>
          <if test="customerName != null" >
            #{customerName,jdbcType=VARCHAR},
          </if>
        </trim>
      </insert>
    
      <update id="updateByPrimaryKeySelective" parameterType="com.star.model.Customer" >
        update t_customer
        <set >
          <if test="customerName != null" >
            customer_name = #{customerName,jdbcType=VARCHAR},
          </if>
        </set>
        where customer_id = #{customerId,jdbcType=INTEGER}
      </update>
      <update id="updateByPrimaryKey" parameterType="com.star.model.Customer" >
        update t_customer
        set customer_name = #{customerName,jdbcType=VARCHAR}
        where customer_id = #{customerId,jdbcType=INTEGER}
      </update>
      <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
        delete from t_customer
        where customer_id = #{customerId,jdbcType=INTEGER}
      </delete>
    
      <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
        select
        <include refid="Base_Column_List" />
        from t_customer
        where customer_id = #{customerId,jdbcType=INTEGER}
      </select>
    </mapper>
    Customer.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.star.mapper.OrderMapper">
        <resultMap id="BaseResultMap" type="com.star.model.Order">
            <constructor>
                <idArg column="order_id" jdbcType="INTEGER" javaType="java.lang.Integer"/>
                <arg column="order_no" jdbcType="VARCHAR" javaType="java.lang.String"/>
                <arg column="cid" jdbcType="INTEGER" javaType="java.lang.Integer"/>
            </constructor>
        </resultMap>
        <!--对应关系结果集(多对一)-->
        <resultMap id="baseManyToOne" type="com.star.model.Order">
            <id column="order_id" property="orderId"/>
            <result column="order_no" property="orderNo"/>
            <result column="cid" property="cid"/>
            <!-- 多对一的关系 -->
            <!-- property: 指的是属性的值, javaType:指的是属性的类型-->
            <association property="customer" javaType="com.star.model.Customer">
                <id column="customer_id" property="customerId"/>
                <result column="customer_name" property="customerName"/>
            </association>
        </resultMap>
        <sql id="Base_Column_List">
        order_id, order_no, cid
      </sql>
        <select id="queryCustomerByOrder" resultMap="baseManyToOne">
          select  * from t_order od inner join t_customer cu on cu.customer_id=od.cid where 1=1
          and order_id = #{orderId}
      </select>
        <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
            select
            <include refid="Base_Column_List"/>
            from t_order
            where order_id = #{orderId,jdbcType=INTEGER}
        </select>
        <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
        delete from t_order
        where order_id = #{orderId,jdbcType=INTEGER}
      </delete>
        <insert id="insert" parameterType="com.star.model.Order">
        insert into t_order (order_id, order_no, cid
          )
        values (#{orderId,jdbcType=INTEGER}, #{orderNo,jdbcType=VARCHAR}, #{cid,jdbcType=INTEGER}
          )
      </insert>
        <insert id="insertSelective" parameterType="com.star.model.Order">
            insert into t_order
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="orderId != null">
                    order_id,
                </if>
                <if test="orderNo != null">
                    order_no,
                </if>
                <if test="cid != null">
                    cid,
                </if>
            </trim>
            <trim prefix="values (" suffix=")" suffixOverrides=",">
                <if test="orderId != null">
                    #{orderId,jdbcType=INTEGER},
                </if>
                <if test="orderNo != null">
                    #{orderNo,jdbcType=VARCHAR},
                </if>
                <if test="cid != null">
                    #{cid,jdbcType=INTEGER},
                </if>
            </trim>
        </insert>
        <update id="updateByPrimaryKeySelective" parameterType="com.star.model.Order">
            update t_order
            <set>
                <if test="orderNo != null">
                    order_no = #{orderNo,jdbcType=VARCHAR},
                </if>
                <if test="cid != null">
                    cid = #{cid,jdbcType=INTEGER},
                </if>
            </set>
            where order_id = #{orderId,jdbcType=INTEGER}
        </update>
        <update id="updateByPrimaryKey" parameterType="com.star.model.Order">
        update t_order
        set order_no = #{orderNo,jdbcType=VARCHAR},
          cid = #{cid,jdbcType=INTEGER}
        where order_id = #{orderId,jdbcType=INTEGER}
      </update>
    </mapper>
    Order.xml

    3)junit测试

    service代码我就不贴了,注意注入mapper接口就OK。

    baseTest:

    package com.star.service.impl;
    
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
    public class BaseTest {
    
    
    }
    View Code

    测试结果:

    1)测试通过客户id查询对应的订单(一对多)

    2020-11-12 10:28:26.674 [main-135] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
    2020-11-12 10:28:27.190 [main-109] DEBUG org.apache.ibatis.io.VFS - Class not found: org.jboss.vfs.VFS
    2020-11-12 10:28:27.191 [main-142] DEBUG org.apache.ibatis.io.JBoss6VFS - JBoss 6 VFS API is not available in this environment.
    2020-11-12 10:28:27.192 [main-109] DEBUG org.apache.ibatis.io.VFS - Class not found: org.jboss.vfs.VirtualFile
    2020-11-12 10:28:27.193 [main-70] DEBUG org.apache.ibatis.io.VFS - VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
    2020-11-12 10:28:27.195 [main-84] DEBUG org.apache.ibatis.io.VFS - Using VFS adapter org.apache.ibatis.io.DefaultVFS
    2020-11-12 10:28:29.294 [main-159] DEBUG com.star.mapper.CustomerMapper.queryOrderByCustomer - ==>  Preparing: select * from t_customer ct left join t_order od on ct.customer_id=od.cid where 1=1 and customer_id = ? 
    2020-11-12 10:28:29.329 [main-159] DEBUG com.star.mapper.CustomerMapper.queryOrderByCustomer - ==> Parameters: 1(Integer)
    2020-11-12 10:28:29.357 [main-165] TRACE com.star.mapper.CustomerMapper.queryOrderByCustomer - <==    Columns: customer_id, customer_name, order_id, order_no, cid
    2020-11-12 10:28:29.359 [main-165] TRACE com.star.mapper.CustomerMapper.queryOrderByCustomer - <==        Row: 1, zs, 1, P01, 1
    2020-11-12 10:28:29.363 [main-165] TRACE com.star.mapper.CustomerMapper.queryOrderByCustomer - <==        Row: 1, zs, 2, P02, 1
    2020-11-12 10:28:29.364 [main-165] TRACE com.star.mapper.CustomerMapper.queryOrderByCustomer - <==        Row: 1, zs, 3, P03, 1
    2020-11-12 10:28:29.365 [main-165] TRACE com.star.mapper.CustomerMapper.queryOrderByCustomer - <==        Row: 1, zs, 4, P04, 1
    2020-11-12 10:28:29.367 [main-165] TRACE com.star.mapper.CustomerMapper.queryOrderByCustomer - <==        Row: 1, zs, 5, P05, 1
    2020-11-12 10:28:29.367 [main-159] DEBUG com.star.mapper.CustomerMapper.queryOrderByCustomer - <==      Total: 5
    Customer(customerId=1, customerName=zs, orders=[Order(orderId=1, orderNo=P01, cid=1, customer=null), Order(orderId=2, orderNo=P02, cid=1, customer=null), Order(orderId=3, orderNo=P03, cid=1, customer=null), Order(orderId=4, orderNo=P04, cid=1, customer=null), Order(orderId=5, orderNo=P05, cid=1, customer=null)])

    2)测试通过订单id查询对应的客户(多对一)

    2020-11-12 10:31:38.681 [main-135] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
    2020-11-12 10:31:39.064 [main-109] DEBUG org.apache.ibatis.io.VFS - Class not found: org.jboss.vfs.VFS
    2020-11-12 10:31:39.068 [main-142] DEBUG org.apache.ibatis.io.JBoss6VFS - JBoss 6 VFS API is not available in this environment.
    2020-11-12 10:31:39.070 [main-109] DEBUG org.apache.ibatis.io.VFS - Class not found: org.jboss.vfs.VirtualFile
    2020-11-12 10:31:39.072 [main-70] DEBUG org.apache.ibatis.io.VFS - VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
    2020-11-12 10:31:39.075 [main-84] DEBUG org.apache.ibatis.io.VFS - Using VFS adapter org.apache.ibatis.io.DefaultVFS
    2020-11-12 10:31:41.563 [main-159] DEBUG com.star.mapper.OrderMapper.queryCustomerByOrder - ==>  Preparing: select * from t_order od inner join t_customer cu on cu.customer_id=od.cid where 1=1 and order_id = ? 
    2020-11-12 10:31:41.601 [main-159] DEBUG com.star.mapper.OrderMapper.queryCustomerByOrder - ==> Parameters: 1(Integer)
    2020-11-12 10:31:41.625 [main-165] TRACE com.star.mapper.OrderMapper.queryCustomerByOrder - <==    Columns: order_id, order_no, cid, customer_id, customer_name
    2020-11-12 10:31:41.625 [main-165] TRACE com.star.mapper.OrderMapper.queryCustomerByOrder - <==        Row: 1, P01, 1, 1, zs
    2020-11-12 10:31:41.628 [main-159] DEBUG com.star.mapper.OrderMapper.queryCustomerByOrder - <==      Total: 1
    Order(orderId=1, orderNo=P01, cid=1, customer=Customer(customerId=1, customerName=zs, orders=null))

    多对多

    表结构,新闻和类型标签之间的多对多关系(一个标签可以对应多个新闻,一个新闻可以有多个标签):

    -- 多对多
    -- 主表
    create table t_news
    (
        news_id int primary key auto_increment,          -- 新闻ID:主鍵
        title varchar(50) not null                       -- 标题
    );
    
    -- 主表
    create table t_category
    (
        category_id int primary key auto_increment,      -- 类别编号:主鍵
        category_name varchar(50) not null               -- 类别名称
    );
    -- 中间表
    create table t_news_category
    (
        id int primary key not null auto_increment,
        nid int not null,
        cid int not null,
        foreign key(nid) references t_news(news_id),
        foreign key(cid) references t_category(category_id)
    );

    1)实体层

    使用了lombok插件,可以快速提供无参和有参的构造函数。

    package com.star.model;
    
    import lombok.*;
    
    import java.util.List;
    
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class News {
        private Integer newsId;
    
        private String title;
    
        private List<Category> categories;
    
        //后面会用到
        public News(Integer newsId, String title) {
            this.newsId = newsId;
            this.title = title;
        }
    }
    package com.star.model;
    
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.List;
    
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class Category {
        private Integer categoryId;
    
        private String categoryName;
    
        private List<News> news;
    
        //后面会用到
        public Category(Integer categoryId, String categoryName) {
            this.categoryId = categoryId;
            this.categoryName = categoryName;
        }
    }

    2)mapper层

    接口代码:

    package com.star.mapper;
    
    import com.star.model.Category;
    import com.star.model.News;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface NewsMapper {
        int deleteByPrimaryKey(Integer newsId);
    
        int insert(News record);
    
        int insertSelective(News record);
    
        News selectByPrimaryKey(Integer newsId);
    
        int updateByPrimaryKeySelective(News record);
    
        int updateByPrimaryKey(News record);
    
        //通过新闻id查找到新闻对应的类型标签
        News queryCategoryByNewId(News news);
    
    }
    news
    package com.star.mapper;
    
    import com.star.model.Category;
    import com.star.model.News;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface CategoryMapper {
        int deleteByPrimaryKey(Integer categoryId);
    
        int insert(Category record);
    
        int insertSelective(Category record);
    
        Category selectByPrimaryKey(Integer categoryId);
    
        int updateByPrimaryKeySelective(Category record);
    
        int updateByPrimaryKey(Category record);
    
        //通过类型id找到对应的新闻集合
        Category queryNewsByCategoryId(Category category);
    }
    category

    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.star.mapper.NewsMapper">
        <resultMap id="BaseResultMap" type="com.star.model.News">
            <constructor>
                <idArg column="news_id" jdbcType="INTEGER" javaType="java.lang.Integer"/>
                <arg column="title" jdbcType="VARCHAR" javaType="java.lang.String"/>
            </constructor>
        </resultMap>
        <!--实际也可以不用单独写出来而是包含在collection标签内,但是为了好区分-->
        <resultMap id="base_categories" type="com.star.model.Category">
            <id column="category_id" property="categoryId"/>
            <result column="category_name" property="categoryName"/>
        </resultMap>
        
        <!-- 新闻对应多个类型标签:一对多关系 -->
        <resultMap id="newsManyToMany" type="com.star.model.News" extends="BaseResultMap">
    <!--        <id column="news_id" property="newsId"/>-->
    <!--        <result column="title" property="title"/>-->
            <collection property="categories" resultMap="base_categories">
            </collection>
        </resultMap>
        <sql id="Base_Column_List">
        news_id, title
        </sql>
        <!--为了方便用*代替,实际开发禁用,这里的外键引用字段都是不同的,所以可以用*
            通过新闻查找类型
        -->
        <select id="queryCategoryByNewId" resultMap="newsManyToMany">
            select * from t_news nws
            left join t_news_category nct on nws.news_id = nct.nid
            left join t_category ctg on ctg.category_id = nct.cid
            where nws.news_id = #{newsId}
        </select>
        <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
            select
            <include refid="Base_Column_List"/>
            from t_news
            where news_id = #{newsId,jdbcType=INTEGER}
        </select>
        <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
        delete from t_news
        where news_id = #{newsId,jdbcType=INTEGER}
      </delete>
        <insert id="insert" parameterType="com.star.model.News">
        insert into t_news (news_id, title)
        values (#{newsId,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR})
      </insert>
        <insert id="insertSelective" parameterType="com.star.model.News">
            insert into t_news
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="newsId != null">
                    news_id,
                </if>
                <if test="title != null">
                    title,
                </if>
            </trim>
            <trim prefix="values (" suffix=")" suffixOverrides=",">
                <if test="newsId != null">
                    #{newsId,jdbcType=INTEGER},
                </if>
                <if test="title != null">
                    #{title,jdbcType=VARCHAR},
                </if>
            </trim>
        </insert>
        <update id="updateByPrimaryKeySelective" parameterType="com.star.model.News">
            update t_news
            <set>
                <if test="title != null">
                    title = #{title,jdbcType=VARCHAR},
                </if>
            </set>
            where news_id = #{newsId,jdbcType=INTEGER}
        </update>
        <update id="updateByPrimaryKey" parameterType="com.star.model.News">
        update t_news
        set title = #{title,jdbcType=VARCHAR}
        where news_id = #{newsId,jdbcType=INTEGER}
      </update>
    </mapper>
    news
    <?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.star.mapper.CategoryMapper">
        <resultMap id="BaseResultMap" type="com.star.model.Category">
            <constructor>
                <idArg column="category_id" jdbcType="INTEGER" javaType="java.lang.Integer"/>
                <arg column="category_name" jdbcType="VARCHAR" javaType="java.lang.String"/>
            </constructor>
        </resultMap>
    
        <resultMap id="baseNews" type="com.star.model.News">
            <id column="news_id" property="newsId"/>
            <result column="title" property="title"/>
            <collection property="categories" resultMap="BaseResultMap"/>
        </resultMap>
    
      <!-- 新闻对应多个类型标签:一对多关系 -->
      <resultMap id="categoryManyToMany" type="com.star.model.Category">
        <id column="category_id" property="categoryId"/>
        <result column="category_name" property="categoryName"/>
        <collection property="news" resultMap="baseNews">
        </collection>
      </resultMap>
        <sql id="Base_Column_List">
        category_id, category_name
      </sql>
        <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
            select
            <include refid="Base_Column_List"/>
            from t_category
            where category_id = #{categoryId,jdbcType=INTEGER}
        </select>
        <!--要注意的是主从关系,类型应该是主表,新闻是从表-->
        <select id="queryNewsByCategoryId" resultMap="categoryManyToMany">
            select * from t_category ctg
            left join t_news_category nct on ctg.category_id = nct.cid
            left join t_news nws on nws.news_id = nct.nid
            where ctg.category_id = #{categoryId}
        </select>
        <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
        delete from t_category
        where category_id = #{categoryId,jdbcType=INTEGER}
      </delete>
        <insert id="insert" parameterType="com.star.model.Category">
        insert into t_category (category_id, category_name)
        values (#{categoryId,jdbcType=INTEGER}, #{categoryName,jdbcType=VARCHAR})
      </insert>
        <insert id="insertSelective" parameterType="com.star.model.Category">
            insert into t_category
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="categoryId != null">
                    category_id,
                </if>
                <if test="categoryName != null">
                    category_name,
                </if>
            </trim>
            <trim prefix="values (" suffix=")" suffixOverrides=",">
                <if test="categoryId != null">
                    #{categoryId,jdbcType=INTEGER},
                </if>
                <if test="categoryName != null">
                    #{categoryName,jdbcType=VARCHAR},
                </if>
            </trim>
        </insert>
        <update id="updateByPrimaryKeySelective" parameterType="com.star.model.Category">
            update t_category
            <set>
                <if test="categoryName != null">
                    category_name = #{categoryName,jdbcType=VARCHAR},
                </if>
            </set>
            where category_id = #{categoryId,jdbcType=INTEGER}
        </update>
        <update id="updateByPrimaryKey" parameterType="com.star.model.Category">
        update t_category
        set category_name = #{categoryName,jdbcType=VARCHAR}
        where category_id = #{categoryId,jdbcType=INTEGER}
      </update>
    </mapper>
    category

    3)测试

    同样的我就不贴Service了,测试代码:

    package com.star.service.impl;
    
    import com.star.model.Category;
    import com.star.model.News;
    import com.star.service.ICategoryService;
    import com.star.service.INewsService;
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import static org.junit.Assert.*;
    
    public class NewsServiceImplTest extends BaseTest{
    
        @Autowired
        private INewsService newsService;
    
        @Autowired
        private ICategoryService categoryService;
    
        @Test
        public void queryCategoryByNewId() {
            //测试查询新闻对应的标签类型
            System.out.println(newsService.queryCategoryByNewId(News.builder().newsId(4).build()));
            //测试标签类型对应的新闻
            System.out.println(categoryService.queryNewsByCategoryId(Category.builder().categoryId(2).build()));
        }
    }

    测试结果:

    2020-11-12 10:51:57.725 [main-135] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
    2020-11-12 10:51:58.185 [main-109] DEBUG org.apache.ibatis.io.VFS - Class not found: org.jboss.vfs.VFS
    2020-11-12 10:51:58.186 [main-142] DEBUG org.apache.ibatis.io.JBoss6VFS - JBoss 6 VFS API is not available in this environment.
    2020-11-12 10:51:58.189 [main-109] DEBUG org.apache.ibatis.io.VFS - Class not found: org.jboss.vfs.VirtualFile
    2020-11-12 10:51:58.190 [main-70] DEBUG org.apache.ibatis.io.VFS - VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
    2020-11-12 10:51:58.192 [main-84] DEBUG org.apache.ibatis.io.VFS - Using VFS adapter org.apache.ibatis.io.DefaultVFS
    2020-11-12 10:52:00.854 [main-159] DEBUG com.star.mapper.NewsMapper.queryCategoryByNewId - ==>  Preparing: select * from t_news nws left join t_news_category nct on nws.news_id = nct.nid left join t_category ctg on ctg.category_id = nct.cid where nws.news_id = ? 
    2020-11-12 10:52:00.892 [main-159] DEBUG com.star.mapper.NewsMapper.queryCategoryByNewId - ==> Parameters: 4(Integer)
    2020-11-12 10:52:00.919 [main-165] TRACE com.star.mapper.NewsMapper.queryCategoryByNewId - <==    Columns: news_id, title, id, nid, cid, category_id, category_name
    2020-11-12 10:52:00.921 [main-165] TRACE com.star.mapper.NewsMapper.queryCategoryByNewId - <==        Row: 4, 113, 8, 4, 1, 1, 焦点
    2020-11-12 10:52:00.926 [main-165] TRACE com.star.mapper.NewsMapper.queryCategoryByNewId - <==        Row: 4, 113, 9, 4, 2, 2, 国际
    2020-11-12 10:52:00.927 [main-165] TRACE com.star.mapper.NewsMapper.queryCategoryByNewId - <==        Row: 4, 113, 10, 4, 3, 3, 社会
    2020-11-12 10:52:00.927 [main-165] TRACE com.star.mapper.NewsMapper.queryCategoryByNewId - <==        Row: 4, 113, 11, 4, 4, 4, 房产
    2020-11-12 10:52:00.929 [main-159] DEBUG com.star.mapper.NewsMapper.queryCategoryByNewId - <==      Total: 4
    News(newsId=4, title=113, categories=[Category(categoryId=1, categoryName=焦点, news=null), Category(categoryId=2, categoryName=国际, news=null), Category(categoryId=3, categoryName=社会, news=null), Category(categoryId=4, categoryName=房产, news=null)])
    2020-11-12 10:52:00.938 [main-159] DEBUG com.star.mapper.CategoryMapper.queryNewsByCategoryId - ==>  Preparing: select * from t_category ctg left join t_news_category nct on ctg.category_id = nct.cid left join t_news nws on nws.news_id = nct.nid where ctg.category_id = ? 
    2020-11-12 10:52:00.939 [main-159] DEBUG com.star.mapper.CategoryMapper.queryNewsByCategoryId - ==> Parameters: 2(Integer)
    2020-11-12 10:52:00.941 [main-165] TRACE com.star.mapper.CategoryMapper.queryNewsByCategoryId - <==    Columns: category_id, category_name, id, nid, cid, news_id, title
    2020-11-12 10:52:00.941 [main-165] TRACE com.star.mapper.CategoryMapper.queryNewsByCategoryId - <==        Row: 2, 国际, 2, 1, 2, 1, 110
    2020-11-12 10:52:00.943 [main-165] TRACE com.star.mapper.CategoryMapper.queryNewsByCategoryId - <==        Row: 2, 国际, 4, 2, 2, 2, 111
    2020-11-12 10:52:00.944 [main-165] TRACE com.star.mapper.CategoryMapper.queryNewsByCategoryId - <==        Row: 2, 国际, 6, 3, 2, 3, 112
    2020-11-12 10:52:00.945 [main-165] TRACE com.star.mapper.CategoryMapper.queryNewsByCategoryId - <==        Row: 2, 国际, 9, 4, 2, 4, 113
    2020-11-12 10:52:00.946 [main-159] DEBUG com.star.mapper.CategoryMapper.queryNewsByCategoryId - <==      Total: 4
    Category(categoryId=2, categoryName=国际, news=[News(newsId=1, title=110, categories=null), News(newsId=2, title=111, categories=null), News(newsId=3, title=112, categories=null), News(newsId=4, title=113, categories=null)])

    可以看到已经获取到我们想要的数据。

    数据库脚本

    -- 一对多
    -- 客户表(主表)
    create table t_customer
    (
        customer_id int primary key not null auto_increment,
        customer_name varchar(50) not null
    );
    
    -- 多对一
    -- 订单表(从表)
    create table t_order
    (
        order_id int primary key not null auto_increment,
        order_no varchar(50) not null unique,
        cid int not null,
        foreign key(cid) references t_customer(customer_id)
    );
    
    -- 与mssql不一样,自动增长是可以赋值,也可以不赋值
    insert into t_customer(customer_id,customer_name) values(1, 'zs');
    insert into t_customer(customer_id,customer_name) values(2, 'ls');
    insert into t_customer(customer_id,customer_name) values(3, 'ww');
    insert into t_customer(customer_id,customer_name) values(4, 'xm');
    
    insert into t_order(order_no,cid) values('P01',1);
    insert into t_order(order_no,cid) values('P02',1);
    insert into t_order(order_no,cid) values('P03',1);
    insert into t_order(order_no,cid) values('P04',1);
    insert into t_order(order_no,cid) values('P05',1);
    insert into t_order(order_no,cid) values('P06',2);
    insert into t_order(order_no,cid) values('P07',2);
    insert into t_order(order_no,cid) values('P08',2);
    insert into t_order(order_no,cid) values('P09',3);
    insert into t_order(order_no,cid) values('P10',3);
    
    SELECT * FROM t_customer;
    SELECT * FROM t_order;
    select * from t_customer ct left join  t_order od on ct.customer_id=od.cid where 1=1;
    
    
    -- 多对多
    -- 主表
    create table t_news
    (
        news_id int primary key auto_increment,          -- 新闻ID:主鍵
        title varchar(50) not null                       -- 标题
    );
    
    -- 主表
    create table t_category
    (
        category_id int primary key auto_increment,      -- 类别编号:主鍵
        category_name varchar(50) not null               -- 类别名称
    );
    
    -- 中间表
    create table t_news_category
    (
        id int primary key not null auto_increment,
        nid int not null,
        cid int not null,
        foreign key(nid) references t_news(news_id),
        foreign key(cid) references t_category(category_id)
    );
    insert into t_news(news_id,title) values(1,'110');
    insert into t_news(news_id,title) values(2,'111');
    insert into t_news(news_id,title) values(3,'112');
    insert into t_news(news_id,title) values(4,'113');
    insert into t_news(news_id,title) values(5,'114');
    insert into t_news(news_id,title) values(6,'115');
    insert into t_news(news_id,title) values(7,'116');
    insert into t_news(news_id,title) values(8,'117');
    insert into t_news(news_id,title) values(9,'118');
    
    
    insert into t_category(category_id,category_name) values(1,'焦点');
    insert into t_category(category_id,category_name) values(2,'国际');
    insert into t_category(category_id,category_name) values(3,'社会');
    insert into t_category(category_id,category_name) values(4,'房产');
    insert into t_category(category_id,category_name) values(5,'财经');
    insert into t_category(category_id,category_name) values(6,'娱乐');
    
    
    insert into t_news_category(nid,cid) values(1,1);
    insert into t_news_category(nid,cid) values(1,2);
    
    insert into t_news_category(nid,cid) values(2,1);
    insert into t_news_category(nid,cid) values(2,2);
    
    insert into t_news_category(nid,cid) values(3,1);
    insert into t_news_category(nid,cid) values(3,2);
    insert into t_news_category(nid,cid) values(3,3);
    
    insert into t_news_category(nid,cid) values(4,1);
    insert into t_news_category(nid,cid) values(4,2);
    insert into t_news_category(nid,cid) values(4,3);
    insert into t_news_category(nid,cid) values(4,4);
    
    
    
    SELECT * FROM t_news;
    SELECT * FROM t_category;
    SELECT * FROM t_news_category;
    
    select *
    FROM t_news nws
             LEFT JOIN t_news_category nct
                       ON nws.news_id = nct.nid
             LEFT JOIN t_category ctg
                       ON ctg.category_id = nct.cid
    WHERE nws.news_id = 4;
  • 相关阅读:
    eclipse中打断点debug无效
    Jenkins构建部署Maven项目
    自动生成实体类和xml
    session 控制单点登录
    eclipse team 没有svn
    easyui combobox 设置滚动条
    unkow jdbc driver : http://maven.apache.org
    easyui datagrid列显示图片
    mysql中计算日期整数差
    Map<String, Object>转Object,Object转 Map<String, Object>
  • 原文地址:https://www.cnblogs.com/StarChen20/p/13962775.html
Copyright © 2011-2022 走看看