来源:https://www.bilibili.com/video/BV1ki4y147oK?p=2
上一节链接:https://blog.csdn.net/qq_40893824/article/details/106960903
下一节链接:https://blog.csdn.net/qq_40893824/article/details/106996441
源码:
https://github.com/13407196713/layui-springboot
新建工程
1 新建 springboot 项目 layui-springBoot:
用新版 idea2020 重复之前的操作会有问题
没有红框部分,只有绿框部分
我直接删除本工程,重复之前的步骤,又正常了
2 在 pom 文件中,加入代码:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
后端连数据库 - product
3 layuispringboot 中创包 entity,其内创建 实体类 Product,加入代码:
数据类型 和 数据库对应
数据库中,若 数据名是 a_b
那 idea 中实体类中,对应数据名 命名规则是:a 部分不变,去掉下划线,b 部分首字母大写 即可
package com.southwind.entity;
import lombok.Data;
@Data
public class Product {
private Integer id;
private String name;
private String description;
private float price;
private Integer stock;//库存
private String categoryleveloneId;// 分类1
private String categoryleveltwoId;// 分类2
private String categorylevelthreeId;// 分类3
private String fileName;
}
数据名 是小驼峰形式
4 在 layuispringboot 中,创包 mapper,放接口文件,其内创建 接口 ProductMapper,加入 extends BaseMapper<Product>
5 在 resources 中,删除 application.properties
在resources 中,新建 application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mmall?serverTimezone=UTC
username: root
password: 123456
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
其中 ?serverTimezone=UTC
是为了保持时区一致
mysql 的时区:中国的时区
idea 连接数据库的时区:世界 “标准” 时区,它比我们的时区早 8 小时
6 在启动类 southwind/ layuispringboot/ LayuiSpringbootApplication 中加入扫包操作代码:
@MapperScan("com.southwind.layuispringboot.mapper")
单元测试:
7 进入 layuispringboot/ mapper/ ProductMapper,右键单击代码中 文件名
加入代码:
package com.southwind.mapper;
import com.southwind.layuispringboot.mapper.ProductMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ProductMapperTest {
@Autowired
private ProductMapper mapper;
@Test
void test(){
mapper.selectList(null).forEach(System.out::println);
}
}
修改前端代码数据
上图 前端部分 应该和 下图的数据库 数据结构 匹配:
改成(保留 3 组 相同的数据):
{
"code": 0
,"msg": ""
,"count": 3000000
,"data": [{
"id": "733"
,"name": "香奈儿"
,"description": "好闻的香水"
,"price": 152
,"stock": 978
,"categorylevelone": "化妆品"
,"categoryleveltwo": "面部护理"
,"categorylevelthree": "少女派"
,"fileName": "baby_1.jpg"
}, {
"id": "733"
,"name": "香奈儿"
,"description": "好闻的香水"
,"price": 152
,"stock": 978
,"categorylevelone": "化妆品"
,"categoryleveltwo": "面部护理"
,"categorylevelthree": "少女派"
,"fileName": "baby_1.jpg"
}, {
"id": "733"
,"name": "香奈儿"
,"description": "好闻的香水"
,"price": 152
,"stock": 978
,"categorylevelone": "化妆品"
,"categoryleveltwo": "面部护理"
,"categorylevelthree": "少女派"
,"fileName": "baby_1.jpg"
}]
}
上图是页面部分代码,也要和 数据库数据类型 匹配,变成:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Layui</title>
<link rel="stylesheet" href=".//layui/css/layui.css" media="all">
<!-- 注意:如果你直接复制所有代码到本地,上述css路径需要改成你本地的 -->
</head>
<body>
<table class="layui-hide" id="test" lay-filter="test"></table>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="getCheckData">获取选中行数据</button>
<button class="layui-btn layui-btn-sm" lay-event="getCheckLength">获取选中数目</button>
<button class="layui-btn layui-btn-sm" lay-event="isAll">验证是否全选</button>
</div>
</script>
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
<script src=".//layui/layui.js" charset="utf-8"></script>
<!-- 注意:如果你直接复制所有代码到本地,上述js路径需要改成你本地的 -->
<script>
layui.use('table', function(){
var table = layui.table;
//温馨提示:默认由前端自动合计当前行数据。从 layui 2.5.6 开始: 若接口直接返回了合计行数据,则优先读取接口合计行数据。
//详见:https://www.layui.com/doc/modules/table.html#totalRow
table.render({
elem: '#test'
,url:'data.json'
,toolbar: '#toolbarDemo'
,title: '用户数据表'
,totalRow: true
,cols: [[
{type: 'checkbox', fixed: 'left'}
,{field:'id', title:'商品ID', width:100, fixed: 'left', unresize: true, sort: true, totalRowText: '合计'}
,{field:'name', title:'用户名称', width:120, edit: 'text'}
,{field:'description', title:'商品描述', width:150}
,{field:'price', title:'商品价格', width:120, sort: true, totalRow: true}
,{field:'stock', title:'商品库存', width:120, edit: 'text', sort: true}
,{field:'categorylevelone', title:'1级分类', width:150}
,{field:'categoryleveltwo', title:'2级分类', width:150}
,{field:'categorylevelthree', title:'3级分类', width:150}
,{field:'fileName', title:'商品图片'}
,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150}
]]
,page: true
});
//工具栏事件
table.on('toolbar(test)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'getCheckData':
var data = checkStatus.data;
layer.alert(JSON.stringify(data));
break;
case 'getCheckLength':
var data = checkStatus.data;
layer.msg('选中了:'+ data.length + ' 个');
break;
case 'isAll':
layer.msg(checkStatus.isAll ? '全选': '未全选')
break;
};
});
//监听工具条
table.on('tool(test)', function(obj){
var data = obj.data;
if(obj.event === 'del'){
layer.confirm('真的删除行么', function(index){
obj.del();
layer.close(index);
});
} else if(obj.event === 'edit'){
layer.alert('编辑行:<br>'+ JSON.stringify(data))
}
});
});
</script>
</body>
</html>
后端连数据库 - product_category
1 在 entity 中新建 实体类 ProductCategory,加入代码:
package com.southwind.layuispringboot.entity;
import lombok.Data;
@Data
public class ProductCategory {
private Integer id;
private String name;
}
2 在 mapper 中新建 接口 ProductCategoryMapper,加入代码:
extends BaseMapper<ProductCategory>
3 测试接口,新建测试类 ProductCategoryMapperTest
ProductCategoryMapperTest 中,加入代码:
package com.southwind.layuispringboot.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ProductCategoryMapperTest {
@Autowired
private ProductCategoryMapper mapper;
@Test
void test(){
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("id",655);
System.out.println(mapper.selectOne(wrapper));
}
}
查询成功!
后端创建 json 格式的数据
前端是 json 的数据,所以后端给前端的数据也要是 json 格式,而不是实体类 Product 格式,vo 上场
json 格式:
{
"code": 0
,"msg": ""
,"count": 3000000
,"data": [{
"id": "733"
}]
}
code | 状态码 0 是正常 |
---|---|
msg | 为空 表示:查询成功 |
count | 总数据量 |
data | 这里 类似 实体类 Product,但不完全相同! 123级分类 的名称 不对应相同 |
这就应该是 vo 的实体类!
1 在 layuispringboot 中 创包 vo,其内创建 实体类 DataVO,加入代码:
package com.southwind.layuispringboot.vo;
import lombok.Data;
import java.util.List;
@Data
public class DataVO<T> {
private Integer code;
private String msg;
private Integer count;
private List<T> data;
}
2 在 vo 中,新建 实体类 ProductVO,加入代码:
package com.southwind.layuispringboot.vo;
import lombok.Data;
@Data
public class ProductVO {
private Integer id;
private String name;
private String description;
private float price;
private Integer stock;
private String categorylevelone;
private String categoryleveltwo;
private String categorylevelthree;
private String fileName;
}
3 在 layuispringboot 中,创包 service,其内 新建接口 ProductService,加入代码:
package com.southwind.layuispringboot.service;
import com.southwind.layuispringboot.vo.DataVO;
import com.southwind.layuispringboot.vo.ProductVO;
public interface ProductService {
public DataVO<ProductVO> findData();
}
4 service 中,创包 impl,其内 创建实现类 ProductServiceImpl,加入代码:
package com.southwind.layuispringboot.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.southwind.layuispringboot.entity.Product;
import com.southwind.layuispringboot.entity.ProductCategory;
import com.southwind.layuispringboot.mapper.ProductCategoryMapper;
import com.southwind.layuispringboot.mapper.ProductMapper;
import com.southwind.layuispringboot.service.ProductService;
import com.southwind.layuispringboot.vo.DataVO;
import com.southwind.layuispringboot.vo.ProductVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductMapper productMapper;
@Autowired
private ProductCategoryMapper productCategoryMapper;
@Override
public DataVO<ProductVO> findData() {
DataVO dataVO = new DataVO();
dataVO.setCode(0);
dataVO.setMsg("");
dataVO.setCount(productMapper.selectCount(null));
List<Product> productList = productMapper.selectList(null);
List<ProductVO> productVOList = new ArrayList<>();
for (Product product : productList) {
ProductVO productVO = new ProductVO();
BeanUtils.copyProperties(product, productVO);// 参数1 赋给 参数2
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("id", product.getCategoryleveloneId());
ProductCategory productCategory = productCategoryMapper.selectOne(wrapper);
if(productCategory != null){
productVO.setCategorylevelone(productCategory.getName());
}
wrapper = new QueryWrapper();
wrapper.eq("id", product.getCategoryleveltwoId());
productCategory = productCategoryMapper.selectOne(wrapper);
if(productCategory != null){
productVO.setCategoryleveltwo(productCategory.getName());
}
wrapper = new QueryWrapper();
wrapper.eq("id", product.getCategorylevelthreeId());
productCategory = productCategoryMapper.selectOne(wrapper);
if(productCategory != null){
productVO.setCategorylevelthree(productCategory.getName());
}
productVOList.add(productVO);
}
dataVO.setData(productVOList);
return dataVO;
}
}
步骤:
code、msg、count 赋值
再用
BeanUtils.copyProperties(product, productVO);// 参数1 赋给 参数2
其中 1、2、3级分类 的名称有不同,要手动赋值
还要判断有无空的数据(连不上的数据,如 product 中分类 id 是1,去找分类数据表,发现 1 没有对应的分类名称,这就是空数据)
5 测试接口 ProductService:ProductServiceTest
加入代码:
package com.southwind.layuispringboot.service;
import com.southwind.layuispringboot.vo.DataVO;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ProductServiceTest {
@Autowired
private ProductService service;
@Test
void findData(){
DataVO dataVO = service.findData();
int i = 0;
}
}
int i = 0;
处,打上断点,debug 一下
是 json 格式的数据!
6 layuispringboot 中,创包 controller,其内 创建控制类 ProductController,加入代码:
package com.southwind.layuispringboot.controller;
import com.southwind.layuispringboot.service.ProductService;
import com.southwind.layuispringboot.vo.DataVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping("/list")
public DataVO list(){
return productService.findData();
}
}
解决跨域
layuispringboot 中,创包 config,其内 创建配置类 CrosConfig,加入代码:
ctrl + o
package com.southwind.layuispringboot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CrosConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/*")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT","PATCH")
.maxAge(3600);
}
}
@Configuration 标注在类上,相当于把该类作为 xml 配置文件中的<beans>
,作用为:配置spring容器(应用上下文)
启动 layuispringboot/ LayuiSpringbootApplication
进入:http://localhost:8080/list
这时候因为解决了跨域问题,Hbuild 中,前端页面就可以来调用 后端提供的 json 数据了
table.html 中:
url:'data.json'
改为 url:'http://localhost:8080/list'
红框部分是没有查到的,因为分类数据表中没有对应分类
分页
装一个 json 可视化插件
进入 http://localhost:8080/list
F12:
再 F5 刷新:
看到了分页:http://localhost:8080/list?page=1&limit=10
所以分页的 2 个 参数:page、limit
1 service/ ProductService 中,加入Integer page, Integer limit
:
2 DataVO 中:
这一步是为下一步中dataVO.setCount( Long result.getTotal());
类型匹配
3 service/ impl/ ProductServiceImpl 中:
红框1、3 处,代码删除
加上红框2 处 的代码:
IPage<Product> productIPage = new Page<>(page, limit);
IPage<Product> result = productMapper.selectPage(productIPage, null);
dataVO.setCount(result.getTotal());
List<Product> productList = result.getRecords();
4 拦截器:config 中,新建 配置类 MyBatisPlusConfig,加入代码:
package com.southwind.layuispringboot.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
5 controller/ ProductController 中:
Integer page, Integer limit
6 测试类 ProductServiceTest 中:
注释掉:
7 重启 layuispringboot/ LayuiSpringbootApplication
进入 http://localhost:8080/list?page=1&limit=2
上一节链接:https://blog.csdn.net/qq_40893824/article/details/106960903
下一节链接:https://blog.csdn.net/qq_40893824/article/details/106996441