请老师解惑

请老师解惑

老师你好:

问题描述:

对着视频校对,消耗了几个小时,仍然找不到错误。请老师解惑


https://img1.sycdn.imooc.com//climg/6315faf9098252db13390366.jpg


相关代码:



4.2 OneToMany对象关联查询

在商品详情实体类GoodsDetail.java中:

package com.imooc.mybatis.entity;

import java.util.zip.ZipInputStream;

public class GoodsDetail {
    private Integer gdId;
    private Integer goodsId;
    private String gdPicUrl;
    private Integer gdOrder;

    public Integer getGdId() {
        return gdId;
    }

    public void setGdId(Integer gdId) {
        this.gdId = gdId;
    }

    public Integer getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Integer goodsId) {
        this.goodsId = goodsId;
    }

    public String getGdPicUrl() {
        return gdPicUrl;
    }

    public void setGdPicUrl(String gdPicUrl) {
        this.gdPicUrl = gdPicUrl;
    }

    public Integer getGdOrder() {
        return gdOrder;
    }

    public void setGdOrder(Integer gdOrder) {
        this.gdOrder = gdOrder;
    }
}

相对应的,增加对应的mappers文件:

goods_detail.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="goodsDetail">
    <select id="selectByGoodsId" parameterType="Integer"
            resultType="com.imooc.mybatis.entity.GoodsDetail">
        select * from t_goods_detail where goods_id = #{value}
    </select>
    
</mapper>

进行对象关联:

package com.imooc.mybatis.entity;

import java.util.List;

public class Goods {

    private Integer goodsId;            // 商品编号     // 包装类
    private String title;               // 标题
    private String subTitle;            // 子标题
    private Float originalCost;         // 原始价格
    private Float currentPrice;         // 当前价格
    private Float discount;             // 折扣率
    private Integer isFreeDelivery;     // 是否包邮:1-包邮;0-不包邮
    private Integer categoryId;         // 分类编号

    private List<GoodsDetail> goodsDetails;      // 将Many设为One的属性集合,这样一个One对象下面,就有多个Many对象


    public Integer getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Integer goodsId) {
        this.goodsId = goodsId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getSubTitle() {
        return subTitle;
    }

    public void setSubTitle(String subTitle) {
        this.subTitle = subTitle;
    }

    public Float getOriginalCost() {
        return originalCost;
    }

    public void setOriginalCost(Float originalCost) {
        this.originalCost = originalCost;
    }

    public Float getCurrentPrice() {
        return currentPrice;
    }

    public void setCurrentPrice(Float currentPrice) {
        this.currentPrice = currentPrice;
    }

    public Float getDiscount() {
        return discount;
    }

    public void setDiscount(Float discount) {
        this.discount = discount;
    }

    public Integer getIsFreeDelivery() {
        return isFreeDelivery;
    }

    public void setIsFreeDelivery(Integer isFreeDelivery) {
        this.isFreeDelivery = isFreeDelivery;
    }

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }


    public List<GoodsDetail> getGoodsDetails() {
        return goodsDetails;
    }

    public void setGoodsDetails(List<GoodsDetail> goodsDetails) {
        this.goodsDetails = goodsDetails;
    }
}


上述已进行关联,但是list集合中的数据仍然是空的:

在`goods.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="goods">
    <!--开启了二级缓存-->
    <cache eviction="LRU" flushInterval="600000" size="512" readOnly="true"/>

    <select id="selectAll" resultType="com.imooc.mybatis.entity.Goods" useCache="">
        select * from t_goods order by goods_id desc limit 10
    </select>

    <select id="selectById" parameterType="Integer" resultType="com.imooc.mybatis.entity.Goods">
        select *
        from t_goods
        where goods_id = #{value};
    </select>

    <!--注意标点符号!是英文句号,不是英文逗号-->
    <select id="selectByPriceRange" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
        select *
        from t_goods
        where current_price between #{min} and #{max}
        order by current_price limit 0,#{limt}
    </select>

    <select id="selectGoodsMap" resultType="java.util.LinkedHashMap" >
        select g.*,c.category_name,'1' as test from t_goods g,t_category c
        where g.category_id=c.category_id
    </select>


    <!--先结果映射-->
    <resultMap id="rmGoods" type="com.imooc.mybatis.dto.GoodsDTO">
        <!--设置主键字段与属性映射-->
        <id property="goods.goodsId" column="goods_id"></id>
        <!--设置非主键字段与属性约束-->
        <result property="goods.title" column="title"></result>
        <result property="goods.originalCost" column="original_cost"></result>
        <result property="goods.currentPrice" column="current_price"></result>
        <result property="goods.discount" column="discount"></result>
        <result property="goods.isFreeDelivery" column="is_free_delivery"></result>
        <result property="goods.categoryId" column="category_id"></result>

        <result property="category.categoryId" column="category_id"></result>
        <result property="category.categoryName" column="category_name"></result>
        <result property="category.parentId" column="parent_id"></result>
        <result property="category.categoryLevel" column="category_level"></result>
        <result property="category.categoryOrder" column="category_order"></result>

        <result property="test" column="test"></result>
    </resultMap>

    <!---将上面的映射规则,放进来-->
    <select id="selectGoodsDTO" resultMap="rmGoods">
        select g.*,c.*,'1' as test from t_goods g,t_category c
        where g.category_id=c.category_id
    </select>

    <insert id="insert" parameterType="com.imooc.mybatis.entity.Goods"
            useGeneratedKeys="true"
            keyProperty="goodsId"
            keyColumn="goods_id">                                                                <!--不用加主键id字段,因为是自动生成的编号-->
        insert into t_goods(title,sub_title,original_cost,current_price,discount,is_free_delivery,category_id)
        values (#{title},#{subTitle},#{originalCost},#{currentPrice},#{discount},#{isFreeDelivery},#{categoryId});
    </insert>


    <insert id="insert2" parameterType="com.imooc.mybatis.entity.Goods" flushCache="true">  <!--不用加主键id字段,因为是自动生成的编号-->
        insert into t_goods(title,sub_title,original_cost,current_price,discount,is_free_delivery,category_id)
        values (#{title},#{subTitle},#{originalCost},#{currentPrice},#{discount},#{isFreeDelivery},#{categoryId});
        <!--帮助主键回填-->                 <!--代表上面insert语句执行完后,再执行这个主键回填-->
        <selectKey resultType="Integer" keyProperty="goodsId" order="AFTER">
            select last_insert_id()
        </selectKey>
    </insert>


    <update id="update" parameterType="com.imooc.mybatis.entity.Goods">
        update t_goods
        set title=#{title},
            sub_title=#{subTitle},
            original_cost=#{originalCost},
            current_price=#{currentPrice},
            discount=#{discount},
            is_free_delivery=#{isFreeDelivery},
            category_id=#{categoryId}
        where goods_id = #{goodsId};
    </update>

    <delete id="delete" parameterType="Integer">
        delete from t_goods where goods_id=#{value}
    </delete>

    <select id="selectByTitle" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
        select * from t_goods where title=#{title} ${order}
    </select>

    <!---->
    <select id="dynamicSQL" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
        select * from t_goods
        <where>
            <if test="categoryId!=null">                <!--表示在参数的Map中,存在categoryId这个key-->
                and category_id=#{categoryId}           <!--SQL子句1-->
            </if>
            <if test="currentPrice!=null">
                and current_price&lt;#{currentPrice}    <!--SQL子句2-->
            </if>
        </where>
    </select>


    <!--type:执行One的实体-->
    <resultMap id="rmGoods1" type="com.imooc.mybatis.entity.Goods">
        <id column="goods_id" property="goodsId"></id><!--映射:goods对象的主键到goods_id字段-->
            <!--对集合list进行说明,说明从哪里取值-->
        <collection property="goodsDetails" select="goodsDetail.selectByGoodsId"
                    column="goods_id"/>
    </resultMap>

    <select id="selectOneToMany" resultMap="rmGoods1">
        select * from t_goods limit 0,1
    </select>


</mapper>


在测试用例中:

package com.imooc.mybatis;

import com.imooc.mybatis.dto.GoodsDTO;
import com.imooc.mybatis.entity.Goods;
import com.imooc.mybatis.utils.MyBatisUtils;
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.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 单元测试类
public class MyBatisTestor {

    // 单元测试用例
    @Test
    public void testOneToMany() throws Exception {
        SqlSession session = null;
        try {
            session = MyBatisUtils.openSession();
            List<Goods> list = session.selectList("goods.selectOneToMany");

            for (Goods goods : list) {
                System.out.println(goods.getTitle() + ":" + goods.getGoodsDetails().size());
            }
        } catch(Exception e){
            throw e;
        } finally{
            MyBatisUtils.closeSession(session);
        }

    }


}

在核心配置文件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>
    <settings>
        <!--比如数据表的字段名goods_id转换为goodsId,实现驼峰命名转换-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>


    <!--设置默认指向的数据库,便捷切换-->
    <environments default="dev">
        <!--开发环境-->
        <environment id="dev">
            <!--采用JDBC方式对数据库事务进行commit/rollback-->
            <transactionManager type="JDBC"></transactionManager>
            <!--采用连接池方式管理数据库连接-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/babytun?useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="1234abcd"/>
            </dataSource>
        </environment>

        <!--(线上)生产环境-->
        <environment id="prd">
            <!--采用JDBC方式对数据库事务进行commit/rollback-->
            <transactionManager type="JDBC"></transactionManager>
            <!--采用连接池方式管理数据库连接-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://192.168.1.155:3306/babytun?useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="1234abcd"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mappers/goods.xml"/>
        <mapper resource="mappers/goods_detail.xml"/>
    </mappers>
</configuration>




正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学你好,错误的位置在good.xml中的selectAll标签中,同学书写的useCache属性中没有具体的值,此处应当书写“true”或者“false”,不能使用空串。

祝学习愉快~

  • Jerry_Zheng24 提问者 #1

    谢谢!

    但是,在testOneToMany() 测试用例仍然出现以下报错:

    https://img1.sycdn.imooc.com//climg/6316bb1c090da3e017760875.jpg

    https://img1.sycdn.imooc.com//climg/6316bb3809919a0e17840851.jpg

    在测试testManyToOne时,也出现了上述报错。

    2022-09-06 11:15:25
  • 好帮手慕小蓝 回复 提问者 Jerry_Zheng24 #2

    同学你好,老师这里将useCache属性补充之后,配合课程源码并没有报错。

    建议同学将finally中的关闭连接的代码注释掉,这样就能看到完整的报错信息了。

    如果同学在报错信息中不能找到问题原因,建议同学将注释关闭连接之后的完整报错信息提供一下。

    祝学习愉快~

    2022-09-06 11:24:38
  • Jerry_Zheng24 提问者 回复 好帮手慕小蓝 #3

    老师好:

    我发现是c3p0连接池的原因:

    因为dev2是可以的单元测试成功的。在第五章中。

    但是,连接池具体哪里错了呢?

    于是,我将finally中的关闭连接的代码注释掉,通过查看完整的报错信息,找到了错误:


    https://img1.sycdn.imooc.com//climg/6316eaf9082ecf9108620482.jpg


    成功运行

    感谢!


    2022-09-06 14:40:32
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师