SpringBoot练手小项目-基于SpringBoot+Mybatis+Spring技术实现商品模块的CRUD

spring boot 专栏收录该内容
2 篇文章 0 订阅

目录

业务描述

项目技术架构分析及设计

项目环境初始化

准备操作

数据库初始化

项目创建

项目基础配置

项目API架构设计

商品查询业务实现

 

Pojo类定义

Dao接口方法及映射定义

Service接口方法定义及实现

Controller对象方法定义及实现

Goods商品列表页面设计及实现

商品查询业务实现

业务描述

Dao接口方法及映射定义

Service接口方法定义及实现

Controller对象方法定义及实现

Goods商品查询按钮设计及实现

商品删除业务实现

业务描述

Dao接口方法及映射定义

Service接口方法定义及实现

Controller对象方法定义及实现

Goods页面上删除超链接定义

业务描述

Dao接口方法及映射定义

Service接口方法定义及实现

Controller对象方法定义及实现

Goods添加页面设计及实现

商品修改业务实现

业务描述

Dao接口方法及映射定义

Service接口方法定义及实现

Controller对象方法定义及实现

Goods修改页面设计及实现

总结(Summary)


业务描述

项目技术架构分析及设计

在商品模块实现过程,我们采用典型的C/S架构进行实现.客户端我们基于浏览器进行实现,服务端采用tomcat,数据库使用MySQL.具体应用层基于MVC分层架构进行实现商品模块的增删改查

项目技术栈应用分析及选型

  • 客户端技术:html,css,bootstrap
  • 服务端技术:hikaricp,mybatis,spring,springboot,thymeleaf
  • 数据库技术:mysql,sql
  • 开发工具集:jdk1.8,maven3.6.3,idea2020.2

项目环境初始化

准备操作

  • JDK 1.8
  • Maven 3.6.3
  • IDEA 2020.1
  • MySQL 5.7+

数据库初始化

打开mysql控制台,然后按如下步骤执行goods.sql文件。
第一步:登录mysql。

mysql –uroot –proot

第二步:设置控制台编码方式。

set names utf8;

第三步:执行goods.sql文件(切记不要打开文件复制到mysql客户端运行)。

source d:/goods.sql

其中goods.sql文件内容如下:

drop database if exists dbgoods;
create database dbgoods default character set utf8;
use dbgoods;
create table tb_goods(
     id bigint primary key auto_increment,
     name varchar(100) not null,
     remark text,
     createdTime datetime not null
)engine=InnoDB;
insert into tb_goods values (null,'java','very good',now());
insert into tb_goods values (null,'mysql','RDBMS',now());
insert into tb_goods values (null,'Oracle','RDBMS',now());
insert into tb_goods values (null,'java','very good',now());
insert into tb_goods values (null,'mysql','RDBMS',now());
insert into tb_goods values (null,'Oracle','RDBMS',now());
insert into tb_goods values (null,'java','very good',now());

项目创建

第一步:基于start.spring.io 创建项目并设置基本信息

image.png

image.png
第二步:创建项目module时指定项目核心依赖

image.png

手动添加项目依赖

  • MySQL 驱动
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>
  • Srping Jdbc 提供了HikariCP连接池
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
  • MyBatis 资源
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.1.3</version>
</dependency>
  • Spring Web 依赖 (内置一个tomcat服务)
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • Thymeleaf 依赖 (html模板引擎)
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

项目基础配置

打开项目配置文件application.properties,并添加如下内容:

#spring server

server.port=80

# spring datasource
spring.datasource.url=jdbc:mysql:///dbgoods?serverTimezone=GMT%2B8&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

# spring mybatis

mybatis.mapper-locations=classpath:/mapper/*/*.xml

# spring log

logging.level.com.cy=debug

#spring thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/module/
spring.thymeleaf.suffix=.html

 

 

项目API架构设计

其API架构设计,如图所示:

image.png

商品查询业务实现

 

从商品库查询商品信息,并将商品信息呈现在页面上,如图所示:

Pojo类定义

定义Goods对象,用于封装从数据库查询到的商品信息。

package com.cy.goods.pojo;
import java.util.Date;
public class Goods {
    private Long id;//id bigint primary key auto_increment
    private String name;//name varchar(100) not null
    private String remark;//remark text
    private Date createdTime;//createdTime datetime
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
    public Date getCreatedTime() {
        return createdTime;
    }
    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime;
    }
    @Override
    public String toString() {
        return "Goods [id=" + id + ", name=" + name + ",   
        remark=" + remark + ", createdTime=" + createdTime + "]";
    }
}

Dao接口方法及映射定义

在GoodsDao接口中定义商品查询方法以及SQL映射,基于此方法及SQL映射获取所有商品信息。代码如下:

package com.cy.goods.dao;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import com.cy.goods.pojo.Goods;

@Mapper
public interface GoodsDao {
      @Select("select * from tb_goods")
      List<Goods> findGoods();
}

编写单元测试类进行测试分析:

package com.cy.goods.dao;
import com.cy.goods.pojo.Goods;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class GoodsDaoTests {
    @Autowired
 private GoodsDao goodsDao;
    @Test
 void testFindGoods(){
        List<Goods> goodsList=goodsDao.findGoods();
        for(Goods g:goodsList){
            System.out.println(g);
        }
    }
}

Service接口方法定义及实现

GoodsService接口及商品查询方法定义

package com.cy.goods.service;
import java.util.List;
import com.cy.goods.pojo.Goods;
public interface GoodsService {
      List<Goods> findGoods();
}

GoodsService接口实现类GoodsServiceImpl定义及方法实现

package com.cy.goods.service;
import java.util.List;
import com.cy.goods.pojo.Goods;
@Service
public class GoodsServiceImpl implements GoodsService {
     @Autowired
     private GoodsDao goodsDao;
     @Override
     public List<Goods> findGoods(){
         return goodsDao.findGoods();
     }
}

编写单元测试类进行测试分析

package com.cy.goods.service;
import com.cy.goods.pojo.Goods;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class GoodsServiceTests {
    @Autowired
 private GoodsService goodsService;
    @Test
 void testFindGoods(){
        List<Goods> goods=goodsService.findGoods();
        goods.forEach(System.out::println);//lmbda表达式
         
    }
}

Controller对象方法定义及实现

定义GoodsController类,并添加doGoodsUI方法,添加查询商品信息代码,并将查询到的商品信息存储到model,并返回goods页面。

package com.cy.goods.controller;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import com.cy.goods.pojo.Goods;
import com.cy.goods.service.GoodsService;
@Controller //@Service,@Component
public class GoodsController {
  
    @Autowired
    private GoodsService goodsService;
    @RequestMapping("/doFindGoods")
    public String doFindGoods(Model model){
        long t1=System.currentTimeMillis();
        List<Goods> list = goodsService.findGoods();
        long t2=System.currentTimeMillis();

        model.addAttribute("goods", list);//把查询到的数据放在model中
        model.addAttribute("time", t2-t1);//实现在页面上显示执行时长
        return "goods";
    }
    
}

Goods商品列表页面设计及实现

在templates/pages目录中添加goods.html页面,并在body中添加html元素,在运行内部使用thymeleaf标签属性获取数据,主要代码如下:

<table class="table table-striped">
       <thead>
               <tr>
                      <th>编号</th>
                      <th>产品</th>
                      <th>描述</th>
                      <th>创建时间</th>
                      <th colspan="2">&nbsp;&nbsp;&nbsp;操作</th>
               </tr>
       </thead>
       <tbody>
               <tr th:each="g:${goods}">
                       <td th:text="${g.id}">1</td>
                       <td th:text="${g.name}">AAAAAAA</td>
                       <td th:text="${g.remark}">aaa</td>
                       <td th:text="${#dates.format(g.createdTime, 'yyyy/MM/dd HH:mm')}">aa</td>
                       <!-- @{ } 表示 http://localhost/ -->
                       <td>
                            <a  th:href="@{/doDeleteById/{id}(id=${g.id})}" >删除</a>
                            <a type="button" class="btn btn-info" th:href="@{/doFindById/{id}(id=${g.id})}">修改</a>
                       </td>
               </tr>
        </tbody>
</table>
thymeleaf 是一种模板引擎,此引擎以html为模板,可以添加自定义标签属性,可以将服务端model中数据填充在页面上,然后实现与用于交互。其官网为thymeleaf.org

全代码如下

<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
    <style type="text/css">
        #a{
            text-decoration: none;
        }
        h1{
            text-align: center;
        }

        .first{
            display: inline-block;

        }
        .form-search{
            float: right;
            display: inline-block;

        }
        h6{
            text-align: right;
        }
    </style>

</head>

<body>
        <div class="container">
            <div class="row ">
                <div class="span12">
                    <h1 >
                        <small >商品信息</small>
                    </h1>

                    <div class="first">
                        <a type="button" class="btn btn-primary" th:href="@{/jump}" >新增商品</a>
                    </div>

                    <form class="form-search" action="/doFindGoodsByName" method="get" >
                        <input class="input-medium search-query" type="text"  placeholder="请输入商品名" name="name"/>
                        <button type="submit" class="btn"  >查找</button>
                    </form>
                    <table class="table table-striped">
                        <thead>
                            <tr>
                                <th>编号</th>
                                <th>产品</th>
                                <th>描述</th>
                                <th>创建时间</th>
                                <th colspan="2">&nbsp;&nbsp;&nbsp;操作</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr th:each="g:${goods}">
                                <td th:text="${g.id}">1</td>
                                <td th:text="${g.name}">AAAAAAA</td>
                                <td th:text="${g.remark}">aaa</td>
                                <td th:text="${#dates.format(g.createdTime, 'yyyy/MM/dd HH:mm')}">aa</td>
                                <!-- @{ } 表示 http://localhost/ -->
                                <td>
                                   <a  th:href="@{/doDeleteById/{id}(id=${g.id})}" >删除</a>
                                   <a type="button" class="btn btn-info" th:href="@{/doFindById/{id}(id=${g.id})}">修改</a>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <!-- 在页面上显示执行时长 -->
                        <h6>执行时长:[[${time}]]ms</h6>
                    </div>
                </div>
            </div>
</body>
</html>

基于bootstrap实现页面,官网https://v3.bootcss.com/

商品查询业务实现

业务描述

在商品查询所有信息后,在搜索框输入名字,点击按钮,实现模糊查询

Dao接口方法及映射定义

在Dao接口中添加方法

List<Goods> findGoodsByName(String name);

在项目的resource目录下创建mapper目录在mapper目录下创建GoodsMapper.xml文件

在GoodsMapper.xml文件中添加sql代码如下:

<?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.cy.goods.dao.GoodsDao">
    <!-- 根据名字查询信息 -->
    <select id="findGoodsByName" resultType="com.cy.goods.pojo.Goods">
        select id,name,remark,createdTime
        from tb_goods
        <if test="name!=null and name!=''">
            where name like concat("%",#{name},"%")
        </if>
    </select>
</mapper>

注意mapper标签的namespace属性为dao接口的全类名(包名加类名),不能有空格 ,resuleType属性为实体类用于封装字段的,也是需要全类名

Service接口方法定义及实现

在GoodsService接口中添加查询方法,代码如下:

List<Goods> findGoodsByName(String name);

在GoodsService的实现类GoodsServiceImpl中添加findGoodsByName方法实现。代码如下

@Override
    public List<Goods> findGoodsByName(String name) {
        return goodsDao.findGoodsByName(name);
    }

Controller对象方法定义及实现

在GoodsController中的添加doFindGoodsByName方法,代码如下:

 @RequestMapping("/doFindGoodsByName")
    public String doFindGoodsByName(String name,Model model){
        long t1=System.currentTimeMillis();
        List<Goods> goods = goodsService.findGoodsByName(name);
        long t2=System.currentTimeMillis();
        model.addAttribute("goods", goods);
        model.addAttribute("time", t2-t1);//在页面上显示运行时长
        return "goods";
    }

Goods商品查询按钮设计及实现

主要代码如下:

<form class="form-search" action="/doFindGoodsByName" method="get" >
              <input class="input-medium search-query" type="text"  placeholder="请输入商品名" name="name"/>
              <button type="submit" class="btn"  >查找</button>
 </form>

 input 里边的name属性必须和controller层的参数相同,也必须写

商品删除业务实现

业务描述

从商品库查询商品信息后,点击页面上删除超链接,基于id删除当前行记录

Dao接口方法及映射定义

在GoodsDao接口中定义商品删除方法以及SQL映射,代码如下:

@Delete("delete from tb_goods where id=#{id}")

 int deleteById(Integer id);

Service接口方法定义及实现

在GoodsService接口中添加删除方法,代码如下:

int deleteById(Integer id);


在GoodsService的实现类GoodsServiceImpl中添加deleteById方法实现。代码如下。

@Override
    public int deleteById(Integer id) {
        return goodsDao.deleteById(id);
    }

 

Controller对象方法定义及实现

在GoodsController中的添加doDeleteById方法,代码如下:

@RequestMapping("/doDeleteById/{id}")//基于rest风格传参
    public String doDeleteById(@PathVariable Integer id){//@PathVariable 表示参数来自URL
        goodsService.deleteById(id);
        return "redirect:/doFindGoods";
    }

说明:Restful 风格为一种软件架构编码风格,定义了一种url的格式,其url语法为/a/b/{c}/{d},在这样的语法结构中{}为一个变量表达式。假如我们希望在方法参数中获取rest url中变量表达式的值,可以使用@PathVariable注解对参数进行描述

Goods页面上删除超链接定义

主要代码如下:

<a  th:href="@{/doDeleteById/{id}(id=${g.id})}" >删除</a>

业务描述

在Goods列表页面,添加添加按钮,进行添加页面,然后在添加页面输入商品相关信息,然后保存到数据库,商品添加页面,设计如图所示:

Dao接口方法及映射定义

在GoodsDao中添加用于保存商品信息的接口方法以及SQL映射,代码如下:

@Insert("insert into tb_goods value(null,#{name},#{remark},now())")
void insertGoods(Goods goods);

说明:当SQL语句比较复杂时,也可以将SQL定义到映射文件(xml文件)中。

Service接口方法定义及实现

在GoodsService接口中添加业务方法,用于实现商品信息添加,代码如下:

void insertGoods(Goods goods);

在GoodsSerivceImpl类中添加接口方法实现,代码如下:

    @Override
    public void insertGoods(Goods goods) {
        goodsDao.insertGoods(goods);
    }

Controller对象方法定义及实现

在GoodsController类中添加用于处理商品添加请求的方法,代码如下:


    @RequestMapping("/doInsertGoods")
    public String doInsertGoods(Goods goods){
        goodsService.insertGoods(goods);
        return "redirect:/doFindGoods";//重定向,使新增数据后执行查询操作
    }

在GoodsController类中添加用于跳转到商品添加页面的方法,代码如下:

   @RequestMapping("/jump")
    public String jump(){
        return"add-goods";//跳转到新增页面
    }

Goods添加页面设计及实现

在templates的pages目录中添加goods-add.html页面,代码如下

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>新增商品</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>

<div class="container">
    <h3 style="text-align: center">新增商品</h3>
    <form th:action="@{/doInsertGoods}" method="post">
        <div class="form-group">
            <label >Name:</label>
            <input type="text" class="form-control" placeholder="Enter name" name="name"  >
        </div>
        <div class="form-group">
            <label >Remark:</label>
            <textarea  class="form-control" placeholder="Enter remark" name="remark" ></textarea>
        </div>
        <a href="/doFindGoods" class="btn btn-primary " role="button">return</a>
        <button type="submit" class="btn btn-primary" style="float:right">提交</button>
    </form>
</div>

</body>
</html>

基于表单提交数据到服务端,表单上的name属性必须和服务端的数据相同,底层会默认调用set方法赋值,所以在pojo类中得提供对应set方法

在goods.html页面中添加,超链接可以跳转到添加页面,关键代码如下:

<a type="button" class="btn btn-primary" th:href="@{/jump}" >新增商品</a>

商品修改业务实现

业务描述

在商品列表页面,点击修改选项,基于商品id查询当前行记录然后将其更新到update-goods页面,在update页面选中,修改商品信息,然后点击 update goods 将表单数据提交到服务端进行更新如图所示:

Dao接口方法及映射定义

在GoodsDao中添加基于id查询商品信息的方法及SQL映射,代码如下:

@Select("select * from tb_goods where id=#{id}")
Goods findById(Integer id);

在GoodsDao中添加基于id执行Goods商品更新的方法及SQL映射,代码如下:

 @Update("update tb_goods set name=#{name},remark=#{remark} where id=#{id}")
 void updateGoods(Goods goods);

Service接口方法定义及实现

在GoodsService 中添加基于id查询商品信息和更新商品信息的方法,代码如下:

Goods findById(Integer id);
void updateGoods(Goods goods);

在GoodsServiceImpl中基于id查询商品信息和更新商品信息的方法,代码如下:

    @Override
    public Goods findById(Integer id) {
        //.....
        return goodsDao.findById(id);
    }
    @Override
    public void updateGoods(Goods goods) {
        return goodsDao.updateGoods(goods);
    }

Controller对象方法定义及实现

在GoodsController中添加基于id查询商品信息的方法,代码如下:

    @RequestMapping("/doFindById/{id}")
    public String doFindById(@PathVariable Integer id,Model model){
        Goods goods = goodsService.findById(id);
        model.addAttribute("goods", goods);
        return "update-goods";
    }

在GoodsController中添加更新商品信息的方法,代码如下:

    @RequestMapping("/doUpdateById")
    public String doUpdateById(Goods goods){
        goodsService.updateGoods(goods);
        return "redirect:/doFindGoods";
    }

Goods修改页面设计及实现

在templates目录中添加goods-update.html页面,代码设计如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>修改商品</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>

<div class="container">

    <h3 style="text-align: center">修改商品</h3>
    <form th:action="@{/doUpdateById}" method="post">
        <input type="hidden" name="id" th:value="${goods.id}">
        <div class="form-group">
            <label >Name:</label>
            <input type="text" class="form-control" placeholder="Enter name" name="name" th:value="${goods.name}" >
        </div>
        <div class="form-group">
            <label >Remark:</label>
            <textarea  class="form-control" placeholder="Enter remark" name="remark" th:text="${goods.remark}"></textarea>
        </div>
        <a href="/doFindGoods" class="btn btn-primary " role="button">return</a>
        <button type="submit" class="btn btn-primary" style="float:right">修改</button>
    </form>
</div>

</body>
</html>

总结(Summary)

本篇讲解了SpringBoot工程下MyBatis,SpringMVC,Thymeleaf技术的综合应用,在编写的过程中记得在每完成一个模块需要开启服务器进行测试是否成功,对于前端页面展示主要使用的bootstrap可以参考官网查看就行,对于后端学习来说前端展示效果是次要的会Ctrl +C/V即可,本篇只是简单入门,在后边会启用异步加载,在service层也会需要添加日志记录,权限管理等业务。。

  • 2
    点赞
  • 5
    评论
  • 11
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值