首页 > 技术文章 > 川职院-JAVA第二阶段实训

DQGonoes 2022-06-07 14:29 原文

目录

2022-06-07

1.数据不统一

导致问题:
1.前端接收数据时不知道数据存储的格式
2.不知道业务是否成功
返回的json数据中要有一个数据表达后端操作是否成功

1.1 封装一个返回的结果集实体

package com.czdsj.core.dto;

import lombok.Data;

/**
 * 后端返回前端json数据实体
 * 2022/6/7
 */
@Data
public class MyResult {

    private String code = "100";//业务状态码:100=》业务操作成功  500=》业务操作失败(系统异常)

    private String msg = "操作成功!";//业务返回的数据表述信息  “操作成功!” “登录成功!”

    private Object data;//业务返回的数据

}

之后所有controller类中返回json数据的方法返回值类型必须填写为封装的结果集类型

/**
     * 查询学生的所有数据-返回json
     * @return
     */
    @RequestMapping(value = "/getStudentList",method = RequestMethod.GET)
    @ResponseBody
    public MyResult getStudentListData(){

        log.info("查询学生的所有数据");

        MyResult result = new MyResult();

        //控制器层调用-业务接口
        List<StudentDo> studentList = null;
        try {
            studentList = baseService.getStudentList();
        } catch (Exception e) {
            e.printStackTrace();//知道错误的原因和代码的位置
            result.setCode("500");//告诉前端后端系统异常了
            result.setMsg("学生信息查询异常!请联系管理员处理~");
        }

        result.setData(studentList);//将查询出来的数据放到data属性中

        return result;

    }

2.用户登录案例

2.1 前端部分

登录界面jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>

<html>
<head>
    <meta charset="UTF-8" />
    <title>登录页面</title>
    <!-- 引入 JQuery  -->
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-3.6.0.min.js"></script>
    <!-- 引入自定义的js文件 -->
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/base/js/index.js"></script>
</head>
<body>
   <!-- 登录表单 -->
   <form>
       <label>用户名</label>
       <input type="text" name="userName" id="userName" placeholder="请输入用户名.."/><br/>
       <label>密码</label>
       <input type="password" name="pwd" id="pwd" placeholder="请输入密码.."/><br/>
       <!-- 提交按钮-关闭默认表单提交功能 -->
       <button type="button" onclick="doLogin()">登录</button>
   </form>

</body>
</html>

登录相关ajax代码(js文件)

/**
 * 点击登录提交表单进行登录操作
 */
function doLogin(){

    var loginData={
        userName:$("#userName").val(),
        pwd:$("#pwd").val()
    };

    console.dir(loginData);

    $.ajax({
        url:"/ssm/base/doLogin",
        type:"POST",
        data:JSON.stringify(loginData),
        dataType:"JSON",
        contentType:"application/json;charset=UTF-8",
        success:function(data){
            if(data.code=="100"){
                alert(data.msg);
                //页面跳转
            }else{
                alert(data.msg);
            }
        },
        error:function(XMLHttpRequest, textStatus, errorThrown){
            console.dir("请求失败!");
        }
    });

}

2.2 后端部分

控制器层(处理登录请求和结果响应)

package com.czdsj.base.controller;

import com.czdsj.base.mybatis.domain.StudentDo;
import com.czdsj.base.mybatis.domain.UserDo;
import com.czdsj.base.service.BaseService;
import com.czdsj.core.dto.MyResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 学生基础信息采集模块-控制器层
 * 2022/6/1
 */
@Controller
@RequestMapping("/base")
@Slf4j //日志注解 自动生成一个log对象
public class BaseController {

    /**
     * 自动注入接口实现层, name是实现层类型首字母小写即可
     */
    @Resource(name = "baseServiceImpl")
    private BaseService baseService;  

/**
     * 登录操作
     * @param user
     * @return
     */
    @RequestMapping(value = "/doLogin",method = RequestMethod.POST)
    @ResponseBody
    public MyResult doLogin(@RequestBody UserDo user){

        log.info("基础模块 -- 登录操作");

        MyResult result = new MyResult();

        if(!("".equals(user.getUserName())||user.getUserName()==null&&"".equals(user.getPwd())||user.getPwd()==null)){

            int i = baseService.doLogin(user);
            if(i>0){
                result.setMsg("登录成功!");
            }else{
                result.setCode("500");
                result.setMsg("登录失败!用户名或密码错误!");
            }

        }else{
            result.setMsg("用户名和密码不能为空!");
            result.setCode("500");
            return result;
        }

        return result;

    }

}

业务接口层

package com.czdsj.base.service;

import com.czdsj.base.mybatis.domain.StudentDo;
import com.czdsj.base.mybatis.domain.UserDo;

import java.util.List;

/**
 * 学生基础信息采集-业务接口层
 * 2022/6/1
 */
public interface BaseService {
     /**
     * 用户登录
     * @param user
     * @return
     */
    int doLogin(UserDo user);

}

业务接口实现层

package com.czdsj.base.service.impl;

import com.czdsj.base.mybatis.dao.BaseMapper;
import com.czdsj.base.mybatis.domain.StudentDo;
import com.czdsj.base.mybatis.domain.UserDo;
import com.czdsj.base.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.List;

/**
 * 学生基础信息采集-业务实现层
 * 2022/6/1
 */
@Service
public class BaseServiceImpl implements BaseService {

    /**
     * 通过容器自动注入mybatis接口的实现
     */
    @Autowired
    private BaseMapper baseMapper;
        /**
     * 用户登录
     * @param user
     * @return
     */
    @Override
    public int doLogin(UserDo user) {

        int i = baseMapper.doLogin(user);

        return i;
    }
}

Mybatis接口-mapper接口

package com.czdsj.base.mybatis.dao;

import com.czdsj.base.mybatis.domain.StudentDo;
import com.czdsj.base.mybatis.domain.UserDo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * Mybatis接口层
 * 2022/6/1
 */
@Mapper
public interface BaseMapper {
    int doLogin(UserDo user);

}

MybatisSQL映射文件-mapperXML

<?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.czdsj.base.mybatis.dao.BaseMapper">
    
<select id="doLogin" resultType="java.lang.Integer" parameterType="com.czdsj.base.mybatis.domain.UserDo">
        select count(*) from t_user
        where userName= #{userName}
          and pwd=#{pwd}
    </select>


</mapper>

2022-06-08

MyBatis代码生成

1.MyBatisTool代码生成工具使用

解压发在群里的mybatisTool.zip,导入idea,注意按照java项目的方式导入,不要使用maven项目的导入方式

(1)导入项目完成后,找到项目根目录下的lib文件夹,右键点击-》add as Library.. 进行jar包依赖导入idea项目

(2)打开src源码路径,修改config.ini配置文件

# --  mysql驱动包路径 --
DriverClass=com.mysql.cj.jdbc.Driver
# --  mysql连接url路径 --
ConnectionURL=jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
# --  数据库用户名 --
Username=root
# --  数据库用户密码 --
Password=root123456


# --  生成文件保存的位置 --
TargetPath=D:\\mybatis

# --  domain包含:数据库表映射实体POJO类、example对象 --
DomainPackage=com.czdsj.你的模块名.mybatis.domain
# --  DaoPackage:生成查询映射接口类 --
DaoPackage=com.czdsj.你的模块名.mybatis.dao
# --  MapperPackage:生成查询映射xml文件 --
MapperPackage=com.czdsj.你的模块名.mybatis.dao

Table = 表名  (想要生成多个表的代码,多个表用英文逗号分隔)

(3)确认配置文件无误后,打开Generate类运行生成代码

当idea控制台出现如下时说明生成成功

D:\mybatis/com/czdsj/demo/mybatis/domain/TUser.java
D:\mybatis/com/czdsj/demo/mybatis/domain/TUserExample.java
D:\mybatis/com/czdsj/demo/mybatis/dao/TUserMapper.java
D:\mybatis/com/czdsj/demo/mybatis/dao/TUserMapper.xml
=============== ok ===============

Process finished with exit code 0

此时对应的文件已经生成到你的本机路径中了

2.生成文件以及目录解释

目录:

mybatis
	-- dao    存放mapper接口以及关联sql映射文件的包
    -- domain  存放对应表生成的POJO类的包以及条件类包

文件:

(1)dao包下:

XXMapper.java:生成的Mapper接口文件,已经定义好了对应表的基础增删改查接口方法

XXMapper.xml:生成的与Mapper接口映射关联的同名xml文件,已对应接口方法编写好基础增删改查动态sql语句

(2)domain包下:(如表名为t_user)

TUser:生成的数据库表与java实体映射POJO类,表字段与java属性名一致,数据类型表达一致

TUserExample:生成的对应实体的条件对象,是mybatis代码自动生成的核心类

3.基础生成的方法解释

对应生成的mapper接口


@Mapper
public interface TUserMapper {

    //如:select * from t_user where userID = #{userId}
    TUser selectByPrimaryKey(String userId);//通过主键查询数据

    int insert(TUser record);//插入(全表插入,所有字段必须填写,不填写时用空字符串填充)

    int insertSelective(TUser record);//插入(部分字段插入,根据你传递的对象属性值是否填写来判断)

    int insertBatch(List<TUser> records);//批量插入(采用了mybatis缓存技术)

    //如:delete from t_user where userID = #{userId}
    int deleteByPrimaryKey(String userId);//根据主键字段删除

int updateByPrimaryKey(TUser record);//根据主键字段值作为条件修改(全表字段修改,不填写时用空字符串填充)

int updateByPrimaryKeySelective(TUser record);//根据主键字段值作为条件修改(部分字段,根据你传递的对象属性值是否填写来判断)

}

4.代码生成基础增删改查案例

可以更新SVN项目

控制器层

/**
 * 案例控制层
 * 2022/6/8
 */
@Controller
@RequestMapping("/demo")
@Slf4j
public class DemoController {

    @Resource(name="demoServiceImpl")
    private DemoService demoService;

    /**
     * 新增数据
     * @return
     * @RequestBody: 如果前端发送的是json字符串再添加
     *
     */
    @RequestMapping(value = "/add",method = RequestMethod.POST)
    @ResponseBody
    public MyResult add(TStudent student){

        log.info("案例-添加数据");

        MyResult result = new MyResult();

        int i = demoService.addStudent(student);

        if(i>0){
            result.setMsg("添加成功!添加【"+i+"】条数据");
        }else{
            result.setCode("500");
            result.setMsg("添加数据失败!");
        }

        return result;

    }


    /**
     * 修改数据
     * @return
     */
    @RequestMapping(value = "/update",method = RequestMethod.PUT)
    @ResponseBody
    public MyResult update(TStudent student){

        log.info("案例-修改数据");

        MyResult result = new MyResult();

        int i = demoService.updateStudent(student);

        if(i>0){
            result.setMsg("修改成功!修改【"+i+"】条数据");
        }else{
            result.setCode("500");
            result.setMsg("修改数据失败!");
        }

        return result;

    }

    /**
     * 删除数据
     * @return
     */
    @RequestMapping(value = "/delete",method = RequestMethod.DELETE)
    @ResponseBody
    public MyResult delete(String code){

        log.info("案例-删除数据");

        MyResult result = new MyResult();

        int i = demoService.deleteStudent(code);

        if(i>0){
            result.setMsg("删除成功!");
        }else{
            result.setCode("500");
            result.setMsg("删除数据失败!");
        }

        return result;

    }


    /**
     * 查询数据-根据主键id查询
     * @return
     */
    @RequestMapping(value = "/getStudentByCode",method = RequestMethod.GET)
    @ResponseBody
    public MyResult getStudentByCode(String code){

        log.info("案例-查询数据-根据主键id查询");

        MyResult result = new MyResult();

        TStudent student = demoService.getStudentByCode(code);

        if(student!=null){
            result.setData(student);
            result.setMsg("学生信息查询成功!");
        }else{
            result.setCode("500");
            result.setMsg("学生信息查询失败!");
        }

        return result;

    }

}

业务接口层

/**
 * 案例-接口层
 * 2022/6/8
 */
public interface DemoService {

    /**
     * 新增数据
     * @return
     */
    int addStudent(TStudent student);

    /**
     * 修改数据
     * @return
     */
    int updateStudent(TStudent student);

    /**
     * 删除数据
     * @return
     */
    int deleteStudent(String code);

    /**
     * 查询数据-根据主键id查询
     * @return
     */
    TStudent getStudentByCode(String code);
}

业务实现层

/**
 * 案例-业务实现层
 * 2022/6/8
 */
@Service
public class DemoServiceImpl implements DemoService {

    @Resource
    private TStudentMapper tStudentMapper;

    /**
     * 新增数据
     * @return
     */
    @Override
    public int addStudent(TStudent student) {

        int i = tStudentMapper.insertSelective(student);

        return i;
    }

    /**
     * 修改数据
     * @return
     */
    @Override
    public int updateStudent(TStudent student) {

        //update t_student set XX=XX where code = "XX"
        int i = tStudentMapper.updateByPrimaryKeySelective(student);

        return i;
    }

    /**
     * 删除数据
     * @return
     */
    @Override
    public int deleteStudent(String code) {

        int i = tStudentMapper.deleteByPrimaryKey(code);

        return  i;
    }

    /**
     * 查询数据-根据主键id查询
     * @return
     */
    @Override
    public TStudent getStudentByCode(String code) {

        TStudent tStudent = tStudentMapper.selectByPrimaryKey(code);

        return tStudent;
    }
}

mybatis使用代码生成的内容,不再展示

2022-06-09

mybatis代码生成example条件查询

注意:生成的example对象只能实现单表条件查询

如:查询学生年龄大于25岁,编号(code)为1的数据

//1.创建条件对象-> 你要使用哪个表进行条件查询,就要创建表对应的example对象
        TStudentExample example = new TStudentExample();

        //2.设置条件-> 创建条件分支对象
        TStudentExample.Criteria criteria = example.createCriteria();

        //3.通过criteria对象设置条件
        // select * from t_sutdent where age > 25 and code = 1;
        criteria.andAgeGreaterThan(25);

        criteria.andCodeEqualTo("1");

        //4.进行查询
        List<TStudent> tStudents = tStudentMapper.selectByExample(example);

常用条件方法:以age字段为例

public Criteria andAgeIsNull()    字段为空条件

public Criteria andAgeIsNotNull()   字段不为空条件

public Criteria andAgeEqualTo(Integer value)   等于条件

public Criteria andAgeNotEqualTo(Integer value)  不等于条件
  
public Criteria andAgeGreaterThan(Integer value)  大于条件

public Criteria andAgeGreaterThanOrEqualTo(Integer value)   大于等于条件 

public Criteria andAgeLessThan(Integer value)  小于条件

public Criteria andAgeLessThanOrEqualTo(Integer value)   小于等于条件 

public Criteria andAgeIn(List<Integer> values)   in 逻辑条件

public Criteria andAgeNotIn(List<Integer> values)   not in 逻辑条件

public Criteria andAgeBetween(Integer value1, Integer value2)   区间条件 between a and b

public Criteria andAgeNotBetween(Integervalue,Integer value2) 排除区间 not between a and b

ssm集成Swagger2

(1)引入依赖

<!--swagger-->
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>2.6.1</version>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>2.6.1</version>
    </dependency>

swagger依赖需要jackson包,检查项目中是否引入jackson,没有以下依赖再进行引入

<dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.12.3</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.12.3</version>
    </dependency>
    <!-- Swagger2 - fasterxml -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.12.3</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml</groupId>
      <artifactId>classmate</artifactId>
      <version>1.5.1</version>
    </dependency>

(2)创建Swagger配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@EnableSwagger2
@Configuration
public class Swagger2Config {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.huawei"))
                .paths(PathSelectors.any())
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("华为昆明数字经济学院 实验项目 ")
                .termsOfServiceUrl("localhost:8080/ssm2")
                .description("springmvc swagger2")
                .contact(new Contact("Gaojingbo", "http://www.baidu.com", "760662328@qq.com"))
                .version("1.1")
                .build();
    }


}

(3)在dispatch-servlet.xml配置文件中配置swagger

<!-- 开启默认静态映射 -->
    <mvc:default-servlet-handler />
    <!-- 注册swagger的自定义配置类,id一定要为:swagger2Config -->
    <bean class="com.huawei.config.Swagger2Config" id="swagger2Config"/>
    <!-- SwaggerUI页面静态资源文件映射配置 -->
    <mvc:resources location="classpath:/META-INF/resources/" mapping="swagger-ui.html"/>
    <mvc:resources location="classpath:/META-INF/resources/webjars/" mapping="/webjars/**"/>

(4)在需要的controller类和方法,以及实体pojo类添加注解

controller类

@Api(description = "日志相关")
@Controller
@RequestMapping("/log")
public class LogController {
 
	@Autowired
	private ILogDAO mapper;
 
	@ApiOperation(value = "查询记录(GET)", notes = "查询记录:http method is get")
	@RequestMapping(value = "/user/queryByGet.json",method = RequestMethod.GET)
	@ResponseBody
	public APIResponse<List<Log>> queryByGet(
	@ApiParam(required = true, hidden = false, value = "用户名") @PathVariable String name,
	@ApiParam(required = true, hidden = false, value = "删除标识",example = "true",allowableValues = "true|false") @PathVariable boolean flag,
	@ApiParam(required = true, value = "当前页",allowableValues = "1,100",example = "5") @RequestParam("currentPage") int currentPage,
	@ApiParam(required = true, value = "每页显示数量") @RequestParam("pageSize") int pageSize) {  ...

pojo参数类

@ApiModel(value = "userInfo", description = "用户信息")
public class User {
    @ApiModelProperty(value = "id", required = true, example = "1000", allowableValues = "1,100")
    private int id;
    @ApiModelProperty(value = "用户名", required = true, example = "张三")
    private String name;
    @ApiModelProperty(value = "生日", required = true, example = "日期")
    private Date birth;
    @ApiModelProperty(value = "用户状态", required = true, example = "0", allowableValues = "0,2")
    private UserStatusEnum status;
    @ApiModelProperty(value = "用户状态", required = false, example = "true", allowableValues = "true|false")
    private boolean testFlag2;
 
 
    @ApiModelProperty(value = "用户状态", hidden = true)
    private int flag = 0;

2022-06-10

数据库设计

数据库设计师软件工程开发流程中很重要的一环

软件工程开发流程:

1. 定制招标方案
2. 招标公告公示
3. 投标、定标

重点
1. 需求分析:分析客户对软件的期许(什么效果、什么操作)
需求分析文档(功能、大致流程、采集的数据样本)

2. 需求确认:技术设计解决方案(功能流程说明、原型设计(UI设计))

3.概要设计(编程解决的逻辑设计):数据库E_R图设计、技术选型
概要设计说明书(技术研究方案)

4.详细设计:数据库表设计、框架设计、编码设计
数据库SQL文件、java框架开发源码以及说明文档

5.开发:计划

6.测试阶段:压力测试;黑盒测试、白盒测试(压力、网络安全、并发)

7.测试运行:

8.运维:数据库数据的备份、恢复、修改、bug的修改

ER图的设计

ER图元素:

E-R图案例:

实体之间的关系

1对1关系:一个人只有一个身份证,一个身份证只对应一个人的信息

1对多关系:一个用户有多个订单,一个订单只对应一个用户

多对1关系:(一对多的反向关系)多个订单对应一个用户,一个用户可能有多个订单

多对多关系:一个用户可以购买多个商品,一种商品可能会被多个人购买,所以有中间表管理多对多关系,就是订单表。所以注意多对多关联关系中一定有中间表:如用户一对多订单表,订单表一对多商品表

关联关系中的E-R完整画法:

数据库设计阶段:

1.概念设计:E-R图设计,区分实体、描述属性、描述属性之间的关系

2.逻辑设计:逻辑模型图,只是描述字段之间的关系

3.物理模型:在逻辑模型基础上添加字段的长度、约束等设计生成SQL代码

2022-06-13

驼峰规则:

(1)java的属性、数据库字段

第一个英文单词首字母小写,第二个单词或之后更多的词组首字母也大写:如:用户名 userName

(2)java类名声明

第一个英文单词首字母大写,第二个单词或之后更多的词组首字母也大写

(3)java常量、静态变量(类变量)

所有单词使用英文大写描述,每个词组之间用下划线隔开 :如 用户名 USER_NANE

PowerDeisgner逻辑模型教程

https://blog.csdn.net/bcbobo21cn/article/details/109325923

2022-06-14

LayUI官网:

http://www.layuiweb.com

通用的layui类库引入:

<%@ include file="/WEB-INF/views/common.jsp" %>

请更新svn

common.jsp的内容是公共的js、css类库

<!-- layui-css样式表文件 -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/static/js/layui/css/layui.css"/>
<!-- layui-js文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/layui/layui.js"></script>

<!-- jquery引入 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-3.6.0.min.js"></script>


1.layui表单提交

(1)改写提交表单的按钮,添加元素

<!-- lay-submit-代表可以进行layui表单提交事件监听 lay-filter 不能重复,区别相同事件的不同元素 -->
                <button type="button" lay-submit lay-filter="doLoginFilter" style="width: 100%" class="layui-btn">登&nbsp;&nbsp;&nbsp;录</button>

(2)在js文件中编写监听

1.使用layui需要按格式编写

js文件中需要使用layui的事件监听、页面元素渲染等功能需要引入对象

layui.use(['layer', 'form','laydate'], function(){
    var layer = layui.layer
    var form = layui.form;

    //监听、事件代码....

});
2.编写表单提交的事件监听
layui.use(['layer', 'form','laydate'], function(){
    var layer = layui.layer
    var form = layui.form;

    //监听登录表单提交
    //form.on('监听事件名称(事件出现的元素lay-filter值)', function(监听事件返回参数值){
    form.on('submit(doLoginFilter)', function(data){
        console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value}

        return false;//阻止表单原始功能页面跳转
    });

});
3.在表单提交时,使用AJAX提交表单的数据

ajax代码

$.ajax({
            url:"/ssm/demo/doLogin",
            type:"POST",
            data:JSON.stringify(data.field),//将layui获取的数据封装成json字符串提交
            dataType:"JSON",
            contentType:"application/json;charset=UTF-8",
            success:function(data){

            },
            error:function(XMLHttpRequest, textStatus, errorThrown){
                console.dir("请求失败!");
            }
        });

后端controller方法部分代码

@RequestMapping("/demo")
@Slf4j
@Controller
public class DemoController {


    @RequestMapping(value = "/doLogin",method = RequestMethod.POST)
    @ResponseBody
    public MyResult doLogin(@RequestBody LoginDto dto){

        log.info("测试-登录");

        System.out.println(dto);

        return null;
    }

2.Layui表格

要使用表格,需要引入layui的table模块

layui.use(['layer', 'form','laydate','table'], function() {
    var layer = layui.layer
    var form = layui.form;
    var table = layui.table;//引入table模块
    
    
    
});

案例:后端编写好查询用户数据的接口,前端js中在layui模块中调用table.render方法

html:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>用户信息首页</title>
    <meta charset="UTF-8" />
    <%@ include file="/WEB-INF/views/common.jsp" %>

    <script type="text/javascript" src="${pageContext.request.contextPath}/static/sys/userIndex.js"></script>
</head>
<body>

<table id="userTable" lay-filter="userTableFilter"></table>

</body>
</html>

js:layui代码

table.render({
        elem: '#userTable'//选中要渲染的元素
        ,height: 200 //表格的高度 单位px不用写
        ,url: '/ssm/demo/getUserList' //数据接口
        ,parseData:function(res){ //res 即为原始返回的数据
            return {
                "code":0,
                "msg": res.msg, //解析提示文本
                "data": res.data //解析数据列表
            };
        }
        ,cols: [[ //表头
            {field: 'userName', title: '用户名'},
            {field: 'realName', title: '真实姓名'},
            {field: 'nickName', title: '昵称'},
            {field: 'pwd', title: '密码'}
        ]]
    });

Layui弹窗

以添加新增按钮弹出添加用户弹窗为案例

(1) 定义一个添加按钮(案例为带图标的方式)

按钮html代码:

   <button class="layui-btn layui-btn-normal" onclick="layerUserAdd()"><i class="layui-icon">&#xe624;</i>新增</button>

(2)编写layui弹出层

注意:弹窗中表单元素编写在html中,用div套住,div定义id,且定义行内样式:display:none;默认隐藏div
div代码案例

<div id="userAddFormDiv"  style="display: none">
    <form class="layui-form" style="padding: 20px">
        <div class="layui-form-item">
            <label class="layui-form-label">用户名</label>
            <div class="layui-input-block">
                <input type="text" name="userName"  placeholder="请输入用户名" autocomplete="off" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">密码</label>
            <div class="layui-input-block">
                <input type="text" name="pwd"  placeholder="请输入密码" autocomplete="off" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">确认密码</label>
            <div class="layui-input-block">
                <input type="text" name="pwd2"  placeholder="请确认您输入的密码" autocomplete="off" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">昵称</label>
            <div class="layui-input-block">
                <input type="text" name="nickName"  placeholder="请输入昵称" autocomplete="off" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">真实姓名</label>
            <div class="layui-input-block">
                <input type="text" name="realName"  placeholder="请输入真实姓名" autocomplete="off" class="layui-input" />
            </div>
        </div>
        <div class="layui-form-item">
            <button class="layui-btn" type="reset">重置</button>
            <button class="layui-btn" type="button" onclick="layerUserCancel()" >取消</button>
            <button class="layui-btn" type="button" lay-submit lay-filter="doAddUser" >保存</button>
        </div>
    </form>
</div>

(3)layui弹出层代码

弹出层需要引入layui的layer模组
JavaScript代码:

  //弹出用户添加窗口
function layerUserAdd(){
    layui.use(['layer'], function() {
        var layer = layui.layer;
		
		//弹出一个窗体
        var index = layer.open({
            type: 1,
            title:"添加用户信息",
            closeBtn:0,//将右上角的关闭按钮去掉
            area: ['50%', '80%'], //宽高
            content: $("#userAddFormDiv")
        });

    });
}


//点击取消添加用户的弹窗
function layerUserCancel(){
    layui.use(['layer'], function() {
        var layer = layui.layer;

        //暴力关闭网页上所有的layui弹窗
        layer.closeAll();

        //通过js脚本的方式,给div添加一个样式,display:none;
        $("#userAddFormDiv").attr("style","display:none;");
    });
}

2022-06-21

echarts的使用:

1.引入echarts

在项目中只要引入common.jsp即可,如果自己的项目引入下载的echarts.min.js文件即可

   <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/echarts.min.js"></script>

2.在html中创建dom容器

div的高度和宽度决定了,echarts图表的大小

<!-- 容器 -->
<div id="tubiao1" class="echartsDiv">

</div>

3.在js中初始化容器对象加载echarts

// 基于准备好的dom,初始化echarts实例,参数传入对应容器的dom对象,建议通过js通过id属性获取元素对象方法
    var myChart1 = echarts.init(document.getElementById('tubiao2'));

    //将echarts官网编写好的效果,以及echarts demo集中的option代码拷贝过来
    var option = {
        xAxis: {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                data: [150, 230, 224, 218, 135, 147, 260],
                type: 'line'
            }
        ]
    };
    
    //通过配置项目渲染echarts
    myChart1.setOption(option1);

echarts案例解析:

1.折线图

效果:

option = {
  title: {/* 图表标题 */
    text: 'Stacked Line'
  },
  tooltip: {/* 鼠标悬浮弹窗效果 */
    trigger: 'axis'
  },
  legend: {/* 图例 */
      /* 在折线图和柱状图中图例要和图表实例(series下的每个对象的name值一一对应) */
    data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
  },
  grid: {/* 网格配置 */
    left: '3%',/* 网格边距的缩放 */
    right: '4%',
    bottom: '3%',
    containLabel: true/* 是否显示网格 */
  },
  toolbox: {/* 右上角工具栏,如果不要就删除 */
    show: true,/* 是否显示 */
    feature: {
      dataView: { readOnly: false },/* 图片化显示 */
      magicType: { type: ['line', 'bar'] },/* 折线图柱状图转换 */
      restore: {},/* 刷新 */
      saveAsImage: {}/* 下载图片 */
    }
  },
  xAxis: {/* x轴配置 */
    type: 'category',/* 显示图例的轴标识 */
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']/* X轴图例数据 */
  },
  yAxis: {/* y轴配置 */
    type: 'value'/* 数据轴 */
  },
  series: [/* 图表实例 */
    {/* 每有一个柱状、一条折线都有一个对象配置 */
      name: 'Email',/* 实例名称 */
      type: 'line',/* 实例样式:line 折线图  bar 柱状图 pie 饼图 */
      data: [120, 132, 101, 134, 90, 230, 210]/* 图表数据 */
    },
    {
      name: 'Union Ads',
      type: 'line',
      stack: 'Total',
      data: [220, 182, 191, 234, 290, 330, 310]
    }
  ]
};

2.柱状图

效果:

option = {
  title: {
    text: 'World Population'
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'shadow'
    }
  },
  legend: {},/* 如果图例数据没有定义,会自动根据图表实例内容生成图例 */
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World']
  },
  yAxis: {
    type: 'value',
    
  },
  series: [
    {
      name: '2011',
      type: 'bar',
      data: [18203, 23489, 29034, 104970, 131744, 630230]
    },
    {
      name: '2012',
      type: 'bar',
      data: [19325, 23438, 31000, 121594, 134141, 681807]
    }
  ]
};

3.饼图

效果:

option = {
  tooltip: {
    trigger: 'item'
  },
  legend: {
    top: '5%',
    left: 'center'
  },
    /* 饼图就没有x y轴的配置了,直接配置在实例中  */
  series: [
    {
      name: 'Access From',
      type: 'pie',
      radius: ['40%', '70%'],/* 内径和外径缩放比例 */
      avoidLabelOverlap: false,
      itemStyle: {
        borderRadius: 10,
        borderColor: '#fff',
        borderWidth: 2
      },
      label: {/* 扇形区域图表名称显示配置 */
        show: false, //是否显示文字
        position: 'center'//显示文字位置
      },
      emphasis: {/* 饼图中央文字显示配置 */
        label: {
          show: true,
          fontSize: '40',
          fontWeight: 'bold'
        }
      },
      data: [/*  一个饼图的数据是综合在一个series对象中的,比例自动计算,格式必须按照要求填写  */
        { value: 1048, name: 'Search Engine' },
        { value: 735, name: 'Direct' },
        { value: 580, name: 'Email' },
        { value: 484, name: 'Union Ads' },
        { value: 300, name: 'Video Ads' }
      ]
    }
  ]
};

2022-06-23

查询语句的组成:

select  投影字段
from  表名
[关联查询  left join]
on  关联查询条件
where 筛选查询条件
group by 分组语句
order by 排序语句

关联查询:

(1)内连接:inner join

SELECT
	* 
FROM
	t_student AS stu
	INNER JOIN t_res AS res ON stu.`code` = res.`code`

当两表或多表关联时,只有满足条件的留下

(2)左连接:left join

SELECT
	* 
FROM
	t_student AS stu  #主  左表
	left JOIN 
	t_res AS res   #从  右表
	ON stu.`code` = res.`code`;

当两表或多表关联时,左表(主表)数据会全部保留,但是关联表(从表、右表)数据没有关联对应关系时,将用null(空)填充

(3)右连接:right join

SELECT
	* 
FROM
	t_student AS stu   #从  右表
	right JOIN 
	t_res AS res  #主  左表
	ON stu.`code` = res.`code`;

当两表或多表关联时,右表(主表)数据会全部保留,但是关联表(从表、左表)数据没有关联对应关系时,将用null(空)填充

多表关联查询:

案例一:

select * from t_student 
left join t_student_class
on t_student.code = t_student_class.code
left join t_class
on t_student_class.classID = t_class.classID

关联查询条件语句:

SELECT
	* 
FROM
	t_student AS stu  #主  左表
	left JOIN 
	t_res AS res   #从  右表
	ON stu.`code` = res.`code`
	where res.res>80   # 注意在关联结束之后写总体条件筛选

分组查询

select avg(res),projectName from t_res
GROUP BY projectName;

在分组查询中,GROUP BY 后面跟上要分组的字段,查询投影中,只能使用聚合函数和分组条件字段进行投影

关联查询中的分组

SELECT
	sum(res.res) as res_sum,
	stu.code
FROM
	t_student AS stu  #主  左表
	left JOIN 
	t_res AS res   #从  右表
	ON stu.`code` = res.`code`
	GROUP BY stu.code;

关联子查询

  # 查询出各个学生的各科目成绩总和 sum()
select * from t_student as t_stu
left join (
	SELECT
		sum(res.res) as res_sum,
		stu.code
	FROM
		t_student AS stu  #主  左表
		left JOIN 
		t_res AS res   #从  右表
		ON stu.`code` = res.`code`
		GROUP BY stu.code
) as stuRes
on t_stu.code = stuRes.code

推荐阅读