Spring系列框架的项目

1. 关于CSMall项目

CSMall项目:酷鲨商城,是一个定位为自营性质的电商平台项目。

CSMall Product项目:是整个项目的一部分,主要处理后台商品的数据管理。

商品相关的数据主要有:

  • 品牌

  • 类别

  • 图片与相册

  • 属性属性模板

  • SPU与SKU

  • 以上数据的关联数据

2. 创建项目

在IntelliJ IDEA中,使用Spring Boot项目的创建向导来创建项目,相关参数:

  • 项目名称jsd2205-csmall-product-teacher
  • Groupcn.tedu
  • Artifactcsmall-product
  • Packagecn.tedu.csmall.product
  • Java版本:8

在创建过程中,可以无视Spring Boot版本,且可以不勾选任何依赖项。

当创建成功后,在pom.xml中将版本指定为2.5.9

3. 数据库与数据表

在终端下,登录MysqL控制台,创建mall_pms数据库

CREATE DATABASE mall_pms;

接下来,在IntelliJ IDEA打开项目,并配置Database面板,连接到mall_pms数据库,并通过mall_pms.sql(老师下发的文件)中的代码来创建所需的数据表(将mall_pms.sql中的所有代码全部复制到Database面板的Console中,全选并执行)。

至此,本项目所需的数据库和数据表创建完成!

关于配置Database面板的视频教程:http://doc.canglaoshi.org/doc/idea_database/index.html

作业

编写以下需求对应的sql语句(使用记事本保存):

  • pms_brand表中插入数据
  • 根据id删除pms_brand表中的某1条数据
  • 根据若干个id批量删除pms_brand表中的数据
    • 如果没有足够多的测试数据,可以事先添加
  • 根据id修改pms_brand表中的name字段的值
  • 统计pms_brand表中的数据的数量
  • 根据name查询pms_brand表中的数据
  • 根据id查询pms_brand表中的数据
  • 查询pms_brand表中所有的数据

前次作业

编写以下需求对应的sql语句(使用记事本保存):

  • pms_brand表中插入数据

    • INSERT INTO pms_brand (name, pinyin, logo, description, keywords, sort, sales, product_count, comment_count, positive_comment_count, enable, gmt_create, gmt_modified) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
      
  • 根据id删除pms_brand表中的某1条数据

    • DELETE FROM pms_brand WHERE id=?;
      
  • 根据若干个id批量删除pms_brand表中的数据

    • DELETE FROM pms_brand WHERE id=? OR id=? …… OR id=?;
      
    • DELETE FROM pms_brand WHERE id IN (?, ?, .... ?);
      
  • 根据id修改pms_brand表中的name字段的值

    • UPDATE pms_brand SET name=? WHERE id=?;
      
  • 统计pms_brand表中的数据的数量

    • SELECT count(*) FROM pms_brand;
      
    • 阿里巴巴Java开发手册:
      【强制】不要使用 count(列名)或 count(常量)来替代 count(*),count(*)是 sql92 定义的
      标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。
      说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。
      
  • 根据name查询pms_brand表中的数据

    • SELECT id, name, pinyin, logo, description, keywords, sort, sales, product_count, comment_count, positive_comment_count, enable, gmt_create, gmt_modified FROM pms_brand WHERE name=?;
      
    • 阿里巴巴Java开发手册:
      【强制】在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。
      说明:1)增加查询分析器解析成本。2)增减字段容易与 resultMap 配置不一致。
      
  • 根据id查询pms_brand表中的数据

    • SELECT id, name, pinyin, logo, description, keywords, sort, sales, product_count, comment_count, positive_comment_count, enable, gmt_create, gmt_modified FROM pms_brand WHERE id=?;
      
  • 查询pms_brand表中所有的数据

    • SELECT id, name, pinyin, logo, description, keywords, sort, sales, product_count, comment_count, positive_comment_count, enable, gmt_create, gmt_modified FROM pms_brand ORDER BY id
      

2. 添加数据库编程的相关依赖

首先,在pom.xml添加数据库编程的必要依赖项:

<!-- Mybatis整合Spring Boot的依赖项 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
<!-- MysqL的依赖项 -->
<dependency>
    <groupId>MysqL</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

在Spring Boot项目中,一旦添加以上依赖项,项目将不可以正常启动!

Spring Boot项目认是开启了自动配置的,当添加了以上数据库编程的依赖项时,就会自动配置文件中读取连接数据库的URL参数值,如果当前尚未配置此参数,就会启动失败!

***************************
APPLICATION Failed TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource Could be configured.

Reason: Failed to determine a suitable driver class

src/main/resources下的application.properties是Spring Boot项目的认主配置文件,当启动项目时,会自动从此文件中读取相关配置,为保证能够正常的使用数据库编程,需要在此文件添加配置:

spring.datasource.url=jdbc:MysqL://localhost:3306/mall_pms?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

完成后,首先,在src/test/java认的包中,找到认的测试类,先执行认的contextLoads()测试方法,此测试应该能够通过,如果不能,则表示IDEA出错、依赖项出错。

contextLoads()通过后,在此测试类中补充:

@Autowired
DataSource dataSource;

@Test
void testGetConnection() throws Exception {
    dataSource.getConnection();
}

注意:以上使用到的DataSourcejavax.sql包中的!

执行以上新测试时,会发生与数据库MysqL)的连接,可以借此检验在application.properties中的配置是否正确!

如果配置的spring.datasource.url中的主机名(localhost)或端口号(3306错误,或者,MysqL / MariaDB的服务根本没有启动,则会出现以下错误

com.MysqL.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

如果在spring.datasource.url中指定的数据库名称有误,或MysqL / MariaDB中确实无此数据库,则会出现以下错误

java.sql.sqlSyntaxErrorException: UnkNown database 'mall_qms'

如果在spring.datasource.url中指定的serverTimezone有误,则会出现以下错误

java.sql.sqlNonTransientConnectionException: Could not create connection to database server.

Caused by: java.time.zone.ZoneRulesException: UnkNown time-zone ID: Asia/ShangHai

如果在spring.datasource.usernamespring.datasource.password中配置的MysqL / MariaDB的用户名或密码错误,则会出现以下某种错误

java.sql.sqlException: Access denied for user 'rootx'@'localhost' (using password: YES)
java.sql.sqlException: Access denied for user 'root'@'localhost' (using password: YES)
java.sql.sqlException: Access denied for user 'root'@'localhost' (using password: NO)

3. 创建实体类

关于数据表中的字段的数据类型,与java类中的属性的数据类型的对应关系:

数据表的字段的数据类型 java类中的属性的数据类型
tinyint / smallint / int Integer
bigint Long
char / varchar / text系列 String
date_time LocalDateTime(Java 8)
decimal BigDecimal(Java 8)

关于POJO的设计规范

  • 具有无参数的构造方法
  • 属性均声明为private的;
  • 生成所有属性对应的规范的Setter和Getter;
  • 生成规范的hashCode()equals()方法
    • 如果2个对象的hashCode()值相同,则必须保证它们equals()对比的结果为true;如果2个对象的hashCode()值不同,则必须保证它们equals()对比的结果为false
    • 通常,可以使用专业的开发工具生成这2个方法,不必关心这个方法方法代码
  • 【建议,不强制要求】生成(重写)toString()方法
  • 实现Serializable接口。

使用Lombok可以简化POJO类的编写,在使用之前,需要在项目中添加依赖:

<!-- Lombok的依赖项,主要用于简化实体类的编写 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
    <scope>provided</scope>
</dependency>

添加以上依赖项后,在各POJO类上,只需要添加@Data注解,即可使得Lombok框架在编译期生成属性对应的Setter & Getter、hashCode()equals()toString()方法

注意:使用Lombok时,应该(强烈推荐)在开发工具中安装lombok插件(在IntelliJ IDEA中,点击File > Settings,在Plugins搜索Lombok并安装),如果未安装,在调用由Lombok生成方法,或使用相关变量时会提示错误,但不影响运行!

src/main/java根包下,创建pojo.entity子包,并在此子包下创建Brand类:

package cn.tedu.csmall.product.pojo.entity;

import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

@Data
public class Brand implements Serializable {

    private Long id;
    private String name;
    private String pinyin;
    private String logo;
    private String description;
    private String keywords;
    private Integer sort;
    private Integer sales;
    private Integer productCount;
    private Integer commentCount;
    private Integer positiveCommentCount;
    private Integer enable;
    private LocalDateTime gmtCreate;
    private LocalDateTime gmtModified;
    
}

4. 关于Mybatis框架

Mybatis框架的主要作用是简化数据库编程。

5. Mybatis的用法

使用Mybatis主要需要:

  • 编写处理数据的抽象方法
    • 抽象方法必须声明在接口中,因为Mybatis框架的底层实现是基于接口的代理模式
    • 接口通常以Mapper作为名称的最后一个单词
  • 配置抽象方法对应的sql语句

关于接口,必须使得Mybatis框架能够明确这些Mapper接口的位置,或者说,使得Mybatis知道有哪些Mapper接口,可以采取的做法有(二选一):

  • 【不推荐】在每一个Mapper接口上添加@Mapper注解
  • 【推荐】在配置类上添加@MapperScan注解,并在此注解中配置参数,参数值就是Mapper接口所在的根包,并且,确保各Mapper接口在此包下
    • 配置类:在项目的根包下(包含根包下的子孙包下),添加@Configuration注解的类,就是配置类

关于抽象方法的声明原则:

  • 返回值类型:如果要执行的sql是增、删、改类型的,推荐使用int作为返回值类型,表示“受影响的行数”,其实,也可以使用void,并不推荐这样使用;

  • 方法名称自定义,但不要重载

  • 参数列表:如果需要执行的sql语句有多个参数,并且具有相关性,则应该将这些参数进行封装,并使用封装的类型作为抽象方法的参数

关于配置抽象方法对应的sql语句,可以(二选一):

  • 【不推荐】使用@Insert等注解配置sql语句,并使用相关注解(例如@Result等)完成相关配置
  • 【推荐】使用专门的XML文件配置sql语句及相关配置
    • sql语句更加直观,易于阅读
    • 相关配置更加直观,易于复用
    • 易于实现与DBA(Database Administrator)协同工作

关于配置sql语句的XML文件

  • 标签必须是<mapper>
  • 必须配置<mapper>标签namespace属性,此属性的值是对应的Mapper接口的全限定名
  • <mapper>标签的子级,使用<insert> / <delete> / <update> / <select>标签配置sql语句
  • 关于<insert>标签,都必须配置id属性,取值为对应的抽象方法名称(不包括抽象方法的签名的其它部分,例如,不需要括号等)
  • <insert>标签的内部,编写sql语句,注意:在<insert>标签内容不要写任何注释,因为写在此处的注释都会被视为sql语句的一部分

6. 使用Mybatis实现:插入品牌数据

src/main/java下的根包下,创建config子包,并在此子包下创建MybatisConfiguration类,在此类上通过注解配置Mapper接口的根包:

@Configuration
@MapperScan("cn.tedu.csmall.product.mapper")
public class MybatisConfiguration {
}

src/main/java下的根包下,创建mapper子包,并在此子包下创建BrandMapper接口,在接口中添加抽象方法

public interface BrandMapper {
    int insert(Brand brand);
}

从 http://doc.canglaoshi.org/config/Mapper.xml.zip 下载压缩包,解压得到SomeMapper.xml文件

src/main/resources下,创建mapper文件夹(文件名称自定义的),并将SomeMapper.xml复制到此文件夹中,此XML文件就是用于配置抽象方法对应的sql语句的文件

然后,在application.properties添加配置,以指定这些XML文件的位置:

# 配置sql的XML文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml

并且,在SomeMapper.xml重命名BrandMapper.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="cn.tedu.csmall.product.mapper.BrandMapper">

    <insert id="insert">
        INSERT INTO pms_brand (
            name, pinyin, logo, description, keywords,
            sort, sales, product_count, comment_count, positive_comment_count,
            enable
        ) VALUES (
            #{name}, #{pinyin}, #{logo}, #{description}, #{keywords},
            #{sort}, #{sales}, #{productCount}, #{commentCount}, #{positiveCommentCount},
            #{enable}
        )
    </insert>

</mapper>

至此,“插入品牌数据”的功能已经完成!

接下来,应该及时测试以上功能是否可以正常运行!

src/test/java下的根包下,创建mapper子包,在此子包中创建BrandMapperTests测试类。

注意:所有的测试类必须在根包下!

注意:测试类的类名,不可以与被测试的类名/接口名相同!

测试代码如下:

package cn.tedu.csmall.product.mapper;

import cn.tedu.csmall.product.pojo.entity.Brand;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBoottest;

@SpringBoottest
public class BrandMapperTests {

    @Autowired
    BrandMapper mapper;
    
    @Test
    void testInsert() {
        Brand brand = new Brand();
        brand.setName("测试品牌998");

        int rows = mapper.insert(brand);
        System.out.printf("插入品牌完成,受影响的行数=" + rows);
    }

}

如果此前没有在配置类中正确的使用@MapperScan配置Mapper接口的根包,将出现以下错误

org.springframework.beans.factory.NoSuchBeanDeFinitionException: No qualifying bean of type 'cn.tedu.csmall.product.mapper.BrandMapper' available: expected at least 1 bean which qualifies as autowire candidate.

如果:

  • 此前没有在application.properties中正确的配置XML文件的位置
  • 在XML中的<mapper>标签上配置的namespace值有误
  • 在XML中的<insert>标签上配置的id值有误

将出现以下错误

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.tedu.csmall.product.mapper.BrandMapper.insert

作业

  1. 写出所有数据表的实体类
  2. 创建新的接口、新的XML文件,实现:插入类别数据、插入相册数据,完成后,使用新的测试类进行测试

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...