项目学习笔记

new-Bee-Mall项目学习

首先我们先了解项目的编写顺序

数据库表—>实体层—>DAO层写接口—>Mapper层写DAO层对应的映射规则,即编写SQL语句—>Service层—>ServiceImpl—>Controller层

Service层应该既调用DAO层的接口,接收DAO层返回的数据,又要提供接口给Controller层的类来进行调用。

项目框架

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzJnNqYf-1626693187290)(C:\Users\ZYH.LAPTOP-32L7159T\AppData\Roaming\Typora\typora-user-images\image-20210718193011019.png)]

项目的测试账户和管理员账户:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7WfL5I7s-1626693187302)(C:\Users\ZYH.LAPTOP-32L7159T\AppData\Roaming\Typora\typora-user-images\image-20210718193701370.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eUGFwZoJ-1626693187310)(C:\Users\ZYH.LAPTOP-32L7159T\AppData\Roaming\Typora\typora-user-images\image-20210718195148549.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hqvOL5Ze-1626693187315)(C:\Users\ZYH.LAPTOP-32L7159T\AppData\Roaming\Typora\typora-user-images\image-20210718195233661.png)]

启动类增加 Mapper 扫描

在启动类中添加对 Mapper 包扫描 @MapperScan,Spring Boot 启动的时候会自动加载包路径下的 Mapper 接口:

@SpringBootApplication
@MapperScan("ltd.newbee.mall.dao") //添加 @Mapper 注解
public class NewbeeMallApplication {
    public static void main(String[] args) {
        System.out.println("启动 Spring Boot...");
        SpringApplication.run(Application.class, args);
    }
}

当然也可以直接在每个 Mapper 接口上面添加 @Mapper 注解,但是如果 Mapper 接口数量较多,在每个 Mapper 加注解是挺繁琐的,建议使用扫描注解。

entity层代码分析

​ 在进行entity层代码编写之前,我们首先将数据库的表单创建好,我们在定义数据库字段名是应该使用:word1_word2_word3的命名方式进行命名:例如:admin_user_id,这样命名的好处就是:我们在编写实体层的代码时,我们只需要在application.xml中加入开启驼峰命名的指令

#开启驼峰命名
mybatis.configuration.mapUnderscoreToCamelCase=true

即可在entity层定义变量为word1Word2Word3,例如:adminUserId,此外:我们需要注意的是,一般数据库中的变量类型为int时,我们在实体层中使用Integer,例如:private Integer adminUserId;

一般在实体层定义的参数都是用对象类型:Long,Integer,Byte等,而不是用基本类型:long、int、byte。主要原因是:对象类型可以让对象为null,而基本类型的对象不能为null,一旦我们在数据库中选择了可以为null,使用基本类型定义的参数出现null时就会报错,为了避免这种情况,我们一般都会选择用对象类型去定义参数。

此外,当我们在数据库中用tinyint定义的类型参数并且进行了注释说明时时,在entity层中使用boolean类型或者Byte类型,一般如果我们定义的参数:例如sex:只有男女两种类型,那么就可以用boolean类型去定义,例如在数据库中我们用0表示女:用1表示:男,那么在entity层中我们就用fasle表示女,true表示男。但是当我们定义的参数不止两种方式时:如animals:0:rabbit 1:dog 2:pig 时,我们则使用Byte类型去定义,这个时候0:rabbit 1:dog 2:pig。

还有就是我们在数据库中定义一个create_time时使用的类型是datetime,在entity层使用Date createTime,并且我们可以定义这个日期格式:

使用注解JsonFormat

具体格式如下:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

此外,我们在使用toString方法时,可以利用字符串缓冲区StringBuilder进行优化。

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append(getClass().getSimpleName());
    sb.append(" [");
    sb.append("Hash = ").append(hashCode());
    sb.append(", adminUserId=").append(adminUserId);
    sb.append(", loginUserName=").append(loginUserName);
    sb.append(", loginPassword=").append(loginPassword);
    sb.append(", nickName=").append(nickName);
    sb.append(", locked=").append(locked);
    sb.append("]");
    return sb.toString();
}

主要是由于String在拼接时,尤其在含有常量值的时候会产生大量的对象垃圾。因此不使用下列方法:

@Override
    public String toString() {
        return "AdminUser{" +
                "adminUserId=" + adminUserId +
                ", loginUserName='" + loginUserName + '\'' +
                ", loginPassword='" + loginPassword + '\'' +
                ", nickName='" + nickName + '\'' +
                ", locked=" + locked +
                '}';
    }

dao层代码分析

dao层对应为entity层的接口,主要定义一些接口方法,

@Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中(一般通过#{}的方式,${}会有sql注入的问题)。

使用@Param注解

@Param(“orId”) String orId 这里orId是前端传过来的参数名,不加@Param(“orId”) 默认就是找orId, 也可以@Param(“orId”) String nb,前端传入的orId参数的值就赋值到nb中。

如果接口方法的参数只有一个,并且没有使用@Parma注解sql语句直接使用任何名称均可。

如果接口的方法有多个参数,并且没有使用@Parma注解,sql语句使用param1…paramn是不会错的。但是为了规范写法,当接口方法中有多个参数时,我们一般都会使用@Param注解

一般我们在写增删改时在dao层定义的返回类型一般为int,

例如:

int deleteByPrimaryKey(Integer carouselId);

int insert(Carousel record);

int updateByPrimaryKey(Carousel record);

用查询时,如果是查询的结果只有一个就返回类型为该类,如果查询的结果为多个返回类型就为一个List集合

例如:

Carousel selectByPrimaryKey(Integer carouselId);

AdminUser selectByPrimaryKey(Integer adminUserId);

mapper层代码分析

首先,mapper层主要对应dao层接口的xml配置文件,通过sql语句实现dao层的增删改查,select、insert、delete、update。

其中id对应dao层接口的方法名,parameterType对应dao层接口方法中传的参数的类型,resultType对应dao层接口返回参数的类型。resultMap是返回集合映射。

传给后端的的参数一般用**#{参数}**

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6OU6ESHV-1626693187320)(C:\Users\ZYH.LAPTOP-32L7159T\AppData\Roaming\Typora\typora-user-images\image-20210718101117946.png)]

<resultMap id="BaseResultMap" type="ltd.newbee.mall.entity.NewBeeMallGoods">
    <id column="goods_id" jdbcType="BIGINT" property="goodsId"/>
    <result column="goods_name" jdbcType="VARCHAR" property="goodsName"/>
    <result column="goods_intro" jdbcType="VARCHAR" property="goodsIntro"/>
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
</resultMap>

如果你搜索只是返回一个值,比如说String ,或者是int,那你直接用resultType就行了。
但是你如果是返回一个复杂的对象,就必须定义好这个对象的resultMap的result map。

1.你要获取id为123的nameString name = (String) queryForObject("getUserNameByID", id); <select id="getUserNameByID" resultType="java.lang.String"> Select name from User where id =#id# </select> 2.你要获取整个User对象User user = (User) queryForObject("getUserByID", id); <resultMap class="包.User" id="User">  <result property="id" column="ID" />  <result property="name" column="NAME" /> </resultMap> <select id="getUserByID" resultMap="User"> Select ID,NAME from User where id =#id# </select>追问但是,resultType 也可以返回一个对象 <select id="getUserNameByID" resultType="com.bean.User">Select * from User where id =#id#</select>也可以返回一个封装的对象啊这个跟resultMap是一样的效果那什么时候是用resultType解决不了的呢?只能用resultMap追答你要是反回这个对象用result type,就必须返回这个对象所有信息了,而且没有任何设置,适用用普通的完整返回。 但你用resultmap,因为resultmap,因为resultmap那段是我们自己指定的,可能指定的属性只是User的一部分,而且还可以设置默认值,这是result type做不到的:resultMap里面只定义 name<resultMap class="包.User" id="User">  <result property="name" column="NAME" /> </resultMap> <select id="getUserByID" resultMap="User"> Select NAME from User where id =#id# </select>

此外,还有一个sql标签做映射效果,

<sql id="Base_Column_List">  category_id, category_level, parent_id, category_name, category_rank, is_deleted,   create_time, create_user, update_time, update_user</sql>

将里面的参数映射为Base_Column_List,

<select id="findGoodsCategoryList" parameterType="Map" resultMap="BaseResultMap">    select    <include refid="Base_Column_List"/>    from tb_newbee_mall_goods_category    <where>        <if test="categoryLevel!=null and categoryLevel!=''">            and category_level = #{categoryLevel}        </if>        <if test="parentId!=null and parentId!=''">            and parent_id = #{parentId}        </if>        and is_deleted = 0    </where>    order by category_rank desc    <if test="start!=null and limit!=null">        limit #{start},#{limit}    </if></select>

例如其中的

<include refid="Base_Column_List"/>

就等价于

category_id, category_level, parent_id, category_name, category_rank, is_deleted, create_time, create_user, update_time, update_user

这个sql标签就是做了一个映射效果,简化了代码量。

service层代码分析

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值