day01_springboot综合案例

springboot项目

课程目标

1. 【掌握】SSM整合
2. 【掌握】使用SSM完成查询
3. 【理解】AdminLTE
4. 【理解】理解SSM综合案例表的结构

springboot环境搭建

搭建工程

在这里插入图片描述在这里插入图片描述在这里插入图片描述

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>cn.yanqi</groupId>
	<artifactId>springboot-crud</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<name>springboot-crud</name>
	<description>springboot-crud</description>

	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
	</properties>

	<dependencies>

		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper-spring-boot-starter</artifactId>
			<version>1.2.10</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.47</version>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>${spring-boot.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>${spring-boot.version}</version>
				<configuration>
					<mainClass>cn.yanqi.SpringbootCrudApplication</mainClass>
					<skip>true</skip>
				</configuration>
				<executions>
					<execution>
						<id>repackage</id>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

</project>

数据库

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(25) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `nickname` varchar(25) DEFAULT NULL,
  `createdtime` datetime DEFAULT NULL,
  `updatedtime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;


INSERT INTO `test`.`user`(`id`, `username`, `password`, `nickname`, `createdtime`, `updatedtime`) VALUES (6, 'jack', '123', '杰克', '2022-10-15 18:15:05', '2022-10-15 18:15:09');
INSERT INTO `test`.`user`(`id`, `username`, `password`, `nickname`, `createdtime`, `updatedtime`) VALUES (7, 'rose', '123', '肉丝', '2022-10-15 18:15:28', '2022-10-15 18:15:31');

application.yml

# 端口
server:
  port: 8080
  servlet:
    context-path: /

# mybatis
mybatis:
  type-aliases-package: cn.yanqi.pojo
  mapper-locations: classpath:mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true #驼峰


# 数据源
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql:///ssm_crud?useSSL=true
    username: root
    password: root
  thymeleaf:
    cache: false #避免改了模板还要重启服务器
    mode: HTML5
    encoding: UTF-8
    servlet:
      content-type: text/html
    prefix: classpath:/templates/
    suffix: .html

 # 分页插件
pagehelper:
  helper-dialect: mysql

代码实现

pojo实体类

@Data
public class User {

    private Integer id;
    private String username;
    private String password;
    private String nickname;

}

controller层

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 后台请求,转发到 templates 模版下 取值显示
     * @param model
     * @return
     */
    @RequestMapping("queryAllUser")
    public String queryAllUser(Model model){
        List<User> userList=userService.queryAllUser();
        model.addAttribute("userList",userList);
        return "user";
    }
}

service层

public interface UserService {

    List<User> queryAllUser();
}
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> queryAllUser() {
        return this.userMapper.queryAllUser();
    }
}

mapper层

@Repository
public interface UserMapper {
    List<User> queryAllUser();
}

mapper.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.yanqi.mapper.UserMapper">
    <select id="queryAllUser" resultType="User">
		select * from user
	</select>
</mapper>

启动类

@SpringBootApplication
@MapperScan("cn.yanqi.mapper")//扫描mapper接口
public class SpringbootthymeleafApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootthymeleafApplication.class, args);
    }
}

页面

<!DOCTYPE html>
<!--引入thymeleaf-->
<html xmlns:th = "http://www.thymeleaf.org">

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table border="1px" cellpadding="1px" cellspacing="0px">
        <tr>
            <th>序号</th>
            <th>姓名</th>
            <th>密码</th>
            <th>昵称</th>
        </tr>
        <tr th:each="user:${userList}">
            <td th:text="${user.id}"></td>
            <td th:text="${user.username}"></td>
            <td th:text="${user.password}"></td>
            <td th:text="${user.nickname}"></td>
        </tr>
    </table>
</body>
</html>

测试

在这里插入图片描述

页面导入

导入相关文件

在这里插入图片描述

@Controller
@RequestMapping("to")
public class pageController {

    @GetMapping("index")
    public String toPageant(){
        return "index";
    }
}

页面效果如下:

在这里插入图片描述

springboot综合案例

数据库搭建

产品表(product)

  • product信息描述

在这里插入图片描述

  • 创建product表

    CREATE TABLE `product` (
      `id` VARCHAR(32) NOT NULL,
      `productNum` VARCHAR(50) NOT NULL,
      `productName` VARCHAR(50) DEFAULT NULL,
      `cityName` VARCHAR(50) DEFAULT NULL,
      `departureTime` DATETIME DEFAULT NULL,
      `productPrice` INT(11) DEFAULT NULL,
      `productDesc` VARCHAR(500) DEFAULT NULL,
      `productStatus` INT(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    
    
    INSERT  INTO `product`(`id`,`productNum`,`productName`,`cityName`,`DepartureTime`,`productPrice`,`productDesc`,`productStatus`) VALUES 
    ('12B7ABF2A4C544568B0A7C69F36BF8B7','yunhe-003','上海五日游','上海','2018-06-13 23:21:21',1800,'魔都我来了',0),
    ('676C5BD1D35E429A8C2E114939C5685A','yunhe-002','北京三日游','北京','2020-01-16 19:21:25',1200,'不错的旅行',1),
    ('9F71F01CB448476DAFB309AA6DF9497F','yunhe-001','北京三日游','北京','2019-06-04 09:21:21',1200,'不错的旅行',1);
    
    

会员表(member)

订单与会员之间是多对一关系,我们在订单表中创建一个外键来进行关联。

订单表 (orders)

旅客表( traveller)

中间表 (order_traveller)

旅客与订单之间是多对多关系,所以我们需要一张中间表(order_traveller)来描述。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qeywgnpD-1690118686237)(assets/image-20201014064431518.png)]

  • order_traveller表sql

    CREATE TABLE order_traveller(
      orderId VARCHAR(32),
      travellerId VARCHAR(32),
      PRIMARY KEY (orderId,travellerId),
      FOREIGN KEY (orderId) REFERENCES orders(id),
      FOREIGN KEY (travellerId) REFERENCES traveller(id)
    );
    
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('0E7231DC797C486290E8713CA3C6ECCC', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E');
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('2FF351C4AC744E2092DCF08CFD314420', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E');
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('3081770BC3984EF092D9E99760FDABDE', 'EE7A71FB6945483FBF91543DBE851960');
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('55F9AF582D5A4DB28FB4EC3199385762', 'EE7A71FB6945483FBF91543DBE851960');
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('5DC6A48DD4E94592AE904930EA866AFA', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E');
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('96CC8BD43C734CC2ACBFF09501B4DD5D', 'EE7A71FB6945483FBF91543DBE851960');
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('A0657832D93E4B10AE88A2D4B70B1A28', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E');
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('CA005CF1BE3C4EF68F88ABC7DF30E976', 'EE7A71FB6945483FBF91543DBE851960');
    INSERT INTO ORDER_TRAVELLER (orderid, travellerid)
    VALUES ('E4DD4C45EED84870ABA83574A801083E', 'EE7A71FB6945483FBF91543DBE851960');
    

实体类

Product类

package cn.yanqi.ssm.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

@Data
public class Product {
    private String id;
    private String productNum;
    private String productName;
    private String cityName;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date departureTime;
    private String departureTimeStr;
    private Integer productPrice;
    private String productDesc;
    private Integer productStatus;
    private String productStatusStr;

    public String getDepartureTimeStr() {
        // 对日期格式化
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        if (null != departureTime) {
            departureTimeStr = dateFormat.format(departureTime);
        }
        return departureTimeStr;
    }

    public String getProductStatusStr() {

        if (productStatus == null) {
            return "";
        }

        if (productStatus == 0){
            productStatusStr = "关闭";
        } else if(productStatus == 1){
            productStatusStr = "开启";
        }

        return productStatusStr;
    }
}


Member类

package cn.yanqi.ssm.pojo;
import lombok.Data;
@Data
public class Member {
    private String id;
    private String name;
    private String nickname;
    private String phoneNum;
    private String email;
}

Orders类

package cn.yanqi.ssm.pojo;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Data
public class Orders {
    private String id;
    private String orderNum;
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
    private Date orderTime;
    private String orderTimeStr;
    private int orderStatus;
    private String orderStatusStr;
    private int peopleCount;
    private Product product;
    private List<Traveller> travellers;
    private Member member;
    private Integer payType;
    private String payTypeStr;
    private String orderDesc;
    //用于添加订单时,添加产品,会员
    private Integer productId;
    private Integer memberId;

    public String getOrderTimeStr() {
        // 对日期格式化
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        orderTimeStr =  dateFormat.format(orderTime);

        return orderTimeStr;
    }

    public String getPayTypeStr() {
        if (payType == 0){
            payTypeStr = "支付宝";
        } else if(payType == 1){
            payTypeStr = "微信";
        }else if(payType == 2){
            payTypeStr = "其他";
        }

        return payTypeStr;
    }


    public String getOrderStatusStr() {
        if (orderStatus == 0){
            orderStatusStr = "未支付";
        } else if(orderStatus == 1){
            orderStatusStr = "已支付";
        }
        return orderStatusStr;
    }
}

Traveller类

package cn.yanqi.ssm.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
public class Traveller {
    private String id;
    private String name;
    private String sex;
    private String phoneNum;
    private Integer credentialsType;
    private String credentialsTypeStr;
    private String credentialsNum;
    private Integer travellerType;
    private String travellerTypeStr;


    public String getCredentialsTypeStr() {
        // 证件类型 0:身份证 1:护照 2:军官证
        if (credentialsType == 0) {
            credentialsTypeStr = "身份证";
        } else if (credentialsType == 1) {
            credentialsTypeStr = "护照";
        } else if (credentialsType == 2) {
            credentialsTypeStr = "军官证";
        }
        return credentialsTypeStr;
    }

    public String getTravellerTypeStr() {
        // 证件类型 0:成人 1:儿童
        if (travellerType == 0) {
            travellerTypeStr = "成人";
        } else if (travellerType == 1) {
            travellerTypeStr = "儿童";
        }

        return travellerTypeStr;
    }
}

产品操作

查询所有产品信息

Product实体类

package cn.yanqi.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Product {
    private String id;
    private String productNum;
    private String productName;
    private String cityName;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date departureTime;
    private String departureTimeStr;
    private Integer productPrice;
    private String productDesc;
    private Integer productStatus;
    private String productStatusStr;

    public void setDepartureTimeStr(String departureTimeStr) {

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date date = null;
        try {
            date = dateFormat.parse(departureTimeStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        this.departureTime = date;
    }

    public String getDepartureTimeStr() {
        // 对日期格式化
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        if (null != departureTime) {
            departureTimeStr = dateFormat.format(departureTime);
        }
        return departureTimeStr;
    }

    public void setProductStatusStr(String productStatusStr) {
        if (productStatusStr.equals("关闭")){
            this.productStatus = 0;
        } else if(productStatusStr.equals("开启")){
            this.productStatus = 1;
        }
    }

    public String getProductStatusStr() {

        if (productStatus == null) {
            return "";
        }

        if (productStatus == 0){
            productStatusStr = "关闭";
        } else if(productStatus == 1){
            productStatusStr = "开启";
        }

        return productStatusStr;
    }
}

编写ProductController

/**
 * @Author: yanqi
 * @Date: 12:00
 * @Desc:
 */
@Controller
@RequestMapping("product")
public class ProductController {

    @Autowired
    private ProductService productService;


    @GetMapping("findAll")
    public String findAll(@RequestParam(value = "page", defaultValue = "1") Integer age ,
                          @RequestParam(value = "size",defaultValue = "5") Integer size,
                          Model model){

        PageHelper.startPage(age,size);

        List<Product> list =  this.productService.findAll();

        PageInfo pageInfo = new PageInfo(list);

        model.addAttribute("pageInfo",pageInfo);

        return "product-list";
    }

}

编写ProductService

public interface ProductService {
    /**
     * 查询所有产品
     * @return
     */
    List<Product> findAll(Integer page, Integer size);
 }   
@Service("productService")
public class ProductServiceImpl implements ProductService {


    @Autowired
    private ProductMapper productMapper;

    /**
     * 查询所有产品
     * @return
     */
    @Override
    public List<Product> findAll(Integer page, Integer size) {
        PageHelper.startPage(page,size);
        return this.productMapper.findAll();
    }

编写ProductMapper

public interface ProductMapper {
    /**
     * 查询所有产品
     * @return
     */
    List<Product> findAll();
    }

编写ProductMapper.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.yanqi.ssm.mapper.ProductMapper">
    
    <!--查询所有产品-->
    <select id="findAll" resultType="Product">
        select * from product order by id desc
    </select>
    
</mapper>

注意事项

在产品添加时,出发时间是一个日期格式,我们需要对日期进行格式化。日期格式化有两种方式:

  • 使用@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  • 使用Converter接口来实现日期格式化。

在这里我们使用@DateTimeFormat来进行日期格式化。我们需要在Product类中的departureTime加上该注解

@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date departureTime;

添加产品

编写ProductController

    /**
     * 新增产品
     * @param product
     * @return
     */
    @PostMapping("save")
    public String save(Product product){
        this.productService.save(product);
        return "redirect:findAll";
    }

编写ProductService

/**
 * 添加产品
 * @param product
 */
void save(Product product);
/**
 * 添加产品
 * @param product
 */
@Override
public void save(Product product) {
    this.productMapper.save(product);
}

编写ProductMapper

/**
 * 添加产品
 * @param product
 */
void save(Product product);

编写ProductMapper.xml

<!--添加产品-->
<insert id="save">
    insert into product(productNum,
                        productName,
                        cityName,
                        departureTime,
                        productPrice,
                        productDesc,
                        productStatus)
                values(#{productNum},
                    #{productName},
                    #{cityName},
                    #{departureTime},
                    #{productPrice},
                    #{productDesc},
                    #{productStatus})
</insert>

产品修改

编写ProductController

    /**
     * 修改产品
     * @return
     */
    @PostMapping("edit")
    public String edit(
            @RequestParam("id") String id,
            @RequestParam("productNum") String productNum,
            @RequestParam("productName") String productName,
            @RequestParam("departureTime") String departureTime,
            @RequestParam("cityName") String cityName,
            @RequestParam("productPrice") Integer productPrice,
            @RequestParam("productStatus") String productStatus,
            @RequestParam("productDesc") String productDesc){

        Product product = new Product();
        product.setId(id);
        product.setProductNum(productNum);
        product.setProductName(productName);
        product.setDepartureTimeStr(departureTime);
        product.setCityName(cityName);
        product.setProductPrice(productPrice);
        product.setProductStatusStr(productStatus);
        product.setProductDesc(productDesc);

        this.productService.edit(product);

        return "redirect:findAll";

    }

    /**
     * 修改之前进行查询
     * @param id
     * @param model
     * @return
     */
    @GetMapping("editById")
    public String editById(@RequestParam("id") Integer id , Model model){
       Product product =  this.productService.editById(id);
       model.addAttribute("product",product);
       return "product-edit";
    }

编写ProductService

    /**
     * 修改产品之前进行查询用于回显
     * @param pid
     * @return
     */
    Product findById(Integer pid);

    /**
     * 修改产品
     * @param product
     * @return
     */
    void edit(Product product);
    /**
     * 修改产品之前进行查询用于回显
     * @param pid
     * @return
     */
    @Override
    public Product findById(Integer pid) {
        return this.productMapper.findById(pid);
    }

    /**
     * 修改产品
     * @param product
     * @return
     */
    @Override
    public void edit(Product product) {
        this.productMapper.edit(product);
    }

编写ProductMapper

/**
 * 修改产品之前进行查询用于回显
 * @param pid
 * @return
 */
Product findById(Integer pid);

/**
 * 修改产品
 * @param product
 * @return
 */
void edit(Product product);

编写ProductMapper.xml

<!--修改产品之前进行查询-->
<select id="findById" resultType="Product">
    select * from product  where id=#{pid}
</select>

<!--修改产品-->
<update id="edit">
    update product set
    productNum=#{productNum},
    productName=#{productName},
    cityName=#{cityName},
    departureTime=#{departureTime},
    productPrice=#{productPrice},
    productDesc=#{productDesc},
    productStatus=#{productStatus}
    where id=#{id}
</update>

产品详情

编写ProductController

    /**
     * 产品详情
     * @param id
     * @param model
     * @return
     */
    @GetMapping("findById")
    public String findById(@RequestParam("id") Integer id, Model model){
        Product product = this.productService.editById(id);
        model.addAttribute("product",product);
        return "product-show";
    }

编写ProductService

/**
 * 修改产品之前进行查询用于回显,之前修改写过无需再写
 * @param pid
 * @return
 */
Product findById(Integer pid);
/**
 * 修改产品之前进行查询用于回显
 * @param pid
 * @return
 */
@Override
public Product findById(Integer pid) {
    return this.productMapper.findById(pid);
}

编写ProductMapper

/**
 * 修改产品之前进行查询用于回显
 * @param pid
 * @return
 */
Product findById(Integer pid);

编写ProductMapper.xml

<!--修改产品之前进行查询-->
<select id="findById" resultType="Product">
    select * from product  where id=#{pid}
</select>

产品删除

编写ProductController

    /**
     * 指定删除
     * @param id
     * @return
     * TODO 待优化:订单中有产品的相关信息,产品删除了,订单中依然有产品的信息
     */
    @GetMapping("deleteById")
    public String deleteById(@RequestParam("id") Integer id){
        this.productService.deleteById(id);
        return "redirect:findAll";
    }

编写ProductService

/**
 * 删除产品
 * @param pid
 * @return
 */
void deleteById(Integer pid);

@Service
public class ProductServiceImpl implements ProductService {


    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private OrderMapper orderMapper;

    /**
     * 删除产品
     * @param pid
     * @return
     */
    @Override
    public void deleteById(Integer pid) {
        //删除订单中商品外键
        this.orderMapper.updateById(pid);
        //删除商品本身
        this.productMapper.deleteById(pid);
    }
}

编写ProductMapper

/**
 * 删除订单中的商品
 */
void updateById(Integer pid);
/**
 * 删除产品
 * @param pid
 * @return
 */
void deleteById(Integer pid);

编写ProductMapper.xml

<!--删除产品-->
<delete id="deleteById">
    delete from product where id=#{pid}
</delete>

<?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.yanqi.ssm.mapper.OrderMapper">
    <!--删除订单中商品-->
    <update id="updateById">
        update  orders set  productId =  null where productId = #{id}
    </update>
</mapper>

批量删除

    /**
     * 批量删除
     * @param ids
     * @return
     */
    @PostMapping("selectDelete")
    public String selectDelete(@RequestParam("ids") int[] ids){
        for (int id : ids) {
            this.productService.deleteById(id);
        }
        return "redirect:findAll";
    }

tMapper;

@Autowired
private OrderMapper orderMapper;

/**
 * 删除产品
 * @param pid
 * @return
 */
@Override
public void deleteById(Integer pid) {
    //删除订单中商品外键
    this.orderMapper.updateById(pid);
    //删除商品本身
    this.productMapper.deleteById(pid);
}

}




### 编写ProductMapper

```java
/**
 * 删除订单中的商品
 */
void updateById(Integer pid);
/**
 * 删除产品
 * @param pid
 * @return
 */
void deleteById(Integer pid);

编写ProductMapper.xml

<!--删除产品-->
<delete id="deleteById">
    delete from product where id=#{pid}
</delete>

<?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.yanqi.ssm.mapper.OrderMapper">
    <!--删除订单中商品-->
    <update id="updateById">
        update  orders set  productId =  null where productId = #{id}
    </update>
</mapper>

批量删除

    /**
     * 批量删除
     * @param ids
     * @return
     */
    @PostMapping("selectDelete")
    public String selectDelete(@RequestParam("ids") int[] ids){
        for (int id : ids) {
            this.productService.deleteById(id);
        }
        return "redirect:findAll";
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/46365.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode恢复被误删的文件(巧用本地历史记录)

背景&#xff1a;&#xff08;希望永远不要有这个背景&#xff09;使用vscode开发项目时&#xff0c;新建了文件&#xff0c;且文件没有git add、没有git stash、没有git commit。但是不小心点中了撤销更改&#xff08;新文件的撤销更改&#xff0c;其实就是删除该新文件&#…

Set集合类详解(附加思维导图)

目录 一、Set集合思维导图 二、set集合类常用方法 2.1、HashSet集合常用方法 2.2、TreeSet集合的使用 三、HashSet、LinkedHashSet、TreeSet的使用场景 四、list和set集合的区别 一、Set集合思维导图 二、set集合类常用方法 2.1、HashSet集合常用方法 ①&#xff1a;add…

windows部署安装redis安装教程

1、下载redishttps://github.com/tporadowski/redis/releases 2、下载完然后双击安装 比较简单 略过 3、测试是否安装成功 提示bug Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf …

Flink状态的理解

Flink是一个带状态的数据处理系统&#xff1b;系统在处理数据的过程中&#xff0c;各算子所记录的状态会随着数据的处理而不断变化&#xff1b; 1. 状态 所谓状态State&#xff0c;一般指一个具体的 Task 的状态&#xff0c;即线程处理过程中需要保存的历史数据或历史累计数据…

如何判断某个视频是深度伪造的?

目录 一、前言 二、仔细检查面部动作 三、声音可以提供线索 四、观察视频中人物的身体姿势 五、小心无意义的词语 深造伪造危险吗&#xff1f; 一、前言 制作深度伪造视频就像在Word文档中编辑文本一样简单。换句话说&#xff0c;您可以拍下任何人的视频&#xff0c;让他…

HEVC网络适配层介绍

h265 的分层结构 分层结构的目的 ○ 网络类型多种多样&#xff0c;不同的网络环境具有不同的特性&#xff0c;压缩视频在其中进行传输必然会受到影响&#xff1b;比如不同网络的 MTU 有所不同&#xff1b; ○ 不同的应用场景对视频有不同的需求&#xff0c;视频业务会喜用不…

html2Canvas+jsPDF 下载PDF 遇到跨域的对象存储的图片无法显示

一、问题原因 对象存储的域名和你网址的域名不一样&#xff0c;此时用Canvas相关插件 将DOM元素转化为PDF&#xff0c;就会出现跨域错误。 二、解决办法 两步 1. 图片元素上设置属性 crossorigin"anonymous" 支持原生img和eleme组件 2. 存储桶设置资源跨域访问…

Redis多级缓存

文章目录 多级缓存背景JVM进程缓存Caffeine案例分析安装MySQL导入SQL Lua语法变量与循环数据类型声明变量循环 函数与条件控制函数条件控制 实现多级缓存安装OpenResty安装opm工具目录结构配置Nginx的环境变量运行启动 快速入门反向代理流程OpenResty监听请求编写item.lua 请求…

2023河南萌新联赛第(三)场:郑州大学 F

把题中所给的式子进行展开&#xff0c;最终可以得到一个等比数列。运用等比数列求和公式即可。 相关知识点&#xff1a;欧拉降幂&#xff0c;逆元。 逆元的用处&#xff1a;因为求和公式需要去除分子&#xff0c;而大数除法去取模会丢失精度&#xff0c;所以可以采用求出分子…

【设计模式——学习笔记】23种设计模式——桥接模式Bridge(原理讲解+应用场景介绍+案例介绍+Java代码实现)

问题引入 现在对不同手机类型的不同品牌实现操作编程(比如:开机、关机、上网&#xff0c;打电话等)&#xff0c;如图 【对应类图】 【分析】 扩展性问题(类爆炸)&#xff0c;如果我们再增加手机的样式(旋转式)&#xff0c;就需要增加各个品牌手机的类&#xff0c;同样如果我们…

C++第三方开发库matplotlib-cpp

Matplotlib-cpp是一个用于在C中绘制图表的开源库。它提供了与Python的Matplotlib库类似的功能&#xff0c;使得在C环境下进行数据可视化变得更加便捷。基于Matplotlib-cpp&#xff0c;我们可以使用各种绘图函数和样式选项来创建各种类型的图表&#xff0c;包括折线图、散点图、…

Qtday2作业

1. 头文件 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> #include<QIcon> #include<QPushButton> #include<QLineEdit> #include<QLabel> #include<QMovie> class Widget : public QWidget…

【多线程带来的的风险-线程安全的问题的简单实例-线程不安全的原因】

文章目录 前言线程不安全的5大原因1. 抢占式执行和随机调度2. 多个线程同时修改一个变量(共享数据&#xff09;3. 修改操作不是原子性的4. 内存可见性5. 指令重排序 前言 什么是线程安全&#xff1f; 简单来说&#xff0c;如果多线程环境下代码运行的结果是符合我们预期的&am…

【SpringCloud Alibaba】(一)微服务介绍

此专栏内容皆来自于【冰河】的《SpringCloud Alibaba 实战》文档。 1. 专栏介绍 我们先来看看《SpringCloud Alibaba实战》专栏的整体结构吧&#xff0c;先上图 从上图&#xff0c;大家可以看到&#xff0c;专栏从整体上分为十个大的篇章&#xff0c;分别为 专栏设计、微服务…

macOS Ventura 13.5 (22G74) 正式版发布,ISO、IPSW、PKG 下载

macOS Ventura 13.5 (22G74) 正式版发布&#xff0c;ISO、IPSW、PKG 下载 本站下载的 macOS Ventura 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也…

全志F1C200S嵌入式驱动开发(GPIO输出)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 和v3s一样,f1c200s本身的外部引脚比较少。所以这个时候,不可避免地,很多引脚的功能就会重叠在一起。这种情况下,我们就要学会取舍了。比如说,如果是学习sd卡的时候,那么spi的…

阿里云NVIDIA A100 GPU云服务器性能详解及租用费用

阿里云GPU服务器租用费用表包括包年包月、一个小时收费以及学生GPU服务器租用费用&#xff0c;阿里云GPU计算卡包括NVIDIA V100计算卡、T4计算卡、A10计算卡和A100计算卡&#xff0c;GPU云服务器gn6i可享受3折&#xff0c;阿里云百科分享阿里云GPU服务器租用表、GPU一个小时多少…

拦截Bean使用之前各个时机的Spring组件

拦截Bean使用之前各个时机的Spring组件 之前使用过的BeanPostProcessor就是在Bean实例化之后&#xff0c;注入属性值之前的时机。 Spring Bean的生命周期本次演示的是在Bean实例化之前的时机&#xff0c;使用BeanFactoryPostProcessor进行验证&#xff0c;以及在加载Bean之前进…

最新Ai创作源码ChatGPT商用运营源码/支持GPT4.0+支持ai绘画+支持Mind思维导图生成

本系统使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到本系统&#xff01; 支持GPT3模型、GPT4模型Midjourney专业绘画&#xff08;全自定义调参&#xff09;、Midjourney以图生图、Dall-E2绘画Mind思维导图生成应用工作台&#xff08;Prompt&#xff09;AI绘画广场自定…

STM32—CAN通信

文章目录 一、CAN通信简介1.1 CAN简介1.2 CAN协议特点1.3 CAN通信的帧类型1.4 数据帧结构1.5 CAN的位时序1.6 CAN的仲裁功能 二、STM32F1的CAN2.1 bxCAN简介2.2 bxCAN工作模式2.2.1 初始化模式2.2.2 正常模式2.2.3 睡眠模式2.2.4 静默模式2.2.5 环回模式 2.3 位时序和波特率 三…