java实战——图书管理项目

文章目录

  • 项目所需要的技术栈
  • 项目演示
  • 项目准备工作
    • 环境准备
    • 数据库数据准备
  • 前后端交互分析(前端代码我们使用现成)
  • 图书列表界面的创建
    • 查看前端发送的请求
    • 根据前端接收的返回值来编写model层
    • 根据请求编写controller层
    • 根据controller编写Service
    • 根据Service编写Mapper层
  • 添加图书
  • 前端
    • 后端Controller
    • Service
    • Mapper
  • 修改书籍信息
  • 批量删除
  • 结尾

项目所需要的技术栈

该项目是一个针对于SpringBoot+Mybatis+SpringMVC的基础运用项目适合初学者来检验水平测试能力,该项目所需技术栈如下

  • SpringBoot:作为项目的框架,使用Maven托管代码
  • Mybatis:使用Mybatis框架操纵数据库,其中使用了xml和注解两种方式去操作数据库
  • 前端ajax:前后端的交互使用的是ajax作为前端为后端发送数据以及接收数据
  • 使用的其他依赖:除此之外还使用了email的工具包来编写了注册页面在pom.xml文件中需要导入特定的依赖
  • 项目分层:项目分为前端页面+control(与前端建立连接的控制层)+Service(服务层供control层进行调用)+Mapper(操纵数据库实现数据与后端代码的 交互)+Model(需要实现的主类)。

项目演示

csdnBook

项目准备工作

首先项目准备层我们需要先确定好自己项目的大致框架也就是分为了多少个package,这些package之间的关系是怎么样的以及,是否要导入其他的依赖,以及建立好后端和数据库的连接等。那么首先我们先从创建一个SpringBoot项目开始

环境准备

创建项目的过程我们要先选好我们项目的路径,环境,spring版本,jdk的版本等。环境如下
在这里插入图片描述

首先我们得项目环境如图中所示首先Name和location是自己准备,然后语言我们使用java语言项目代码托管使用Maven,JDK版本使用17,java版本同上也是17版本。之后点击Next。
在这里插入图片描述
在这里我们需要配置好我们的项目所需要使用的依赖有哪些,以及我们Spring版本,我们的Spring版本使用3.2.6,然后我们的工具选择如下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这些环境准备好之后我们就可以点击create了。
代码分层各个层的package创建如下
在这里插入图片描述
后端环境准备好之后我们就要来准备一下数据库了

数据库数据准备

在这里插入图片描述
我们数据库的名称就叫book_test我们数据库的建表语句如下首先是user_info管理登录用户

CREATE TABLE `user_info` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_name` varchar(128) NOT NULL,`password` varchar(128) NOT NULL,`delete_flag` tinyint(4) DEFAULT '0',`create_time` datetime DEFAULT CURRENT_TIMESTAMP,`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`),UNIQUE KEY `user_name_UNIQUE` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='用户表'

其次是我们的图书表管理各种图书图书表建表语句如下

CREATE TABLE `book_info` (`id` int(11) NOT NULL AUTO_INCREMENT,`book_name` varchar(127) NOT NULL,`author` varchar(127) NOT NULL,`count` int(11) NOT NULL,`price` decimal(7,2) NOT NULL,`publish` varchar(256) NOT NULL,`status` tinyint(4) DEFAULT '1' COMMENT '0-⽆效, 1-正常, 2-不允许借阅',`create_time` datetime DEFAULT CURRENT_TIMESTAMP,`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=81 DEFAULT CHARSET=utf8mb4

前后端交互分析(前端代码我们使用现成)

然后我们开始进行我们前后端交互的准备,其实也就是前端代码应当如何跟后端代码进行交互这里我们从第一个页面的login开始

 <div class="container-login"><div class="container-pic"><img src="pic/computer.png" width="350px"></div><div class="login-dialog"><h3>登陆</h3><div class="row"><span>用户名</span><input type="text" name="userName" id="userName" class="form-control"></div><div class="row"><span>密码</span><input type="password" name="password" id="password" class="form-control"></div><div class="row"><button type="button" class="btn btn-info btn-lg" onclick="login()">登录</button></div><div class="row"><button type="button" class="btn btn-info btn-lg" onclick="sign_in()">注册</button></div></div>

这里我们发现有个登录按钮那么我们应该先看看这个登录按钮是如何提交数据的。这里我们可以看出来当我们点击这个登录按钮之后,那么就会执行function login这个函数,这个函数其实就是通过ajax向后端发送请求的函数,他发送的数据包括,我们输入的用户名,我们输入的密码这些那么ajax的代码如下

function login() {// var userName=  $("#userName").val();// var password = $("#password").val()$.ajax({url: "/user/login",type: "post",data:{userName: $("#userName").val(),password: $("#password").val()},success:function(result){if(result.code=="SUCCESS" && result.data ==""){//密码正确location.href = "book_list.html?pageNum=1";}else{alert(result.errMsg);}//返回fail 如何处理?//返回一个统一的错误界面}});}

这里我们可以看到前端login交互代码中我们的ajax中的内容发送是将输入框中的用户名和密码发送进入,并且按照我们的url现实的是user和login那么我们就可以知道我们后端代码关于这部分地方该怎么来处理了。

  1. 首先我们要有相应的类去接收这部分提交的数据那么结合前端和数据库的设计来看我们的这个用户信息类需要有以下这些信息
    (1). 用户名称
    (2). 用户密码
    (3). 删除标志
    (4). 创建时间
    (5). 修改时间
    (6). 用户ID

那么按照上面的分层约定我们的用户信息类应该处于Model层那么代码如下

package com.example.mybooksystem.Model;import lombok.Data;import java.util.Date;
@Data
public class UserInfo {private Integer id;private String userName;private String password;private Integer deleteFlag;private Date createTime;private Date updateTime;
}

那么我们的controller层的路径也应该跟前端的url路径保持一致我们的controller的初始框架其实也就确定了下来如下

package com.example.mybooksystem.Controller;
import com.example.mybooksystem.Model.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/user")
@RestController
public class UserControl {@RequestMapping("/login")public void login(UserInfo userInfo){/*详细代码*/}
}

此外我们还需要添加一些工具类比如说我们看到前端代码在收到后端代码返回值的那部分,
在这里插入图片描述
也就是这一部分,我们发现我们后端的返回值既需要包含一个空字符串,也需要包含一个状态码为SUCCESS的状态表示,因此我们需要一个Result工具类对我们返回结果做包装,此外还需要创建一个状态码类来表示我们返回的状态码。那么这部分工具类的实现其实我们可以使用,一个enum进行那么首先我们要先创建一个Enums的package然后把我们的类写进去。
在这里插入图片描述

package com.example.mybooksystem.Enums;
import lombok.Data;
public enum ResultStatus {SUCCESS(200),FAIL(-1),NOLOGIN(-2);public int getCode() {return code;}public void setCode(int code) {this.code = code;}private int code;ResultStatus(int code){this.code=code;}
}

有了这个状态码代码后我们还需要创建一个对结果进行包装的Result类它的实现我们可以放在model层那么代码如下

package com.example.mybooksystem.Model;import com.example.mybooksystem.Enums.ResultStatus;
import lombok.Data;@Data
public class Result<T> {private T data;private ResultStatus code;private String errMsg;public static <T>Result success(T data){Result result=new Result<>();result.setData(data);result.setCode(ResultStatus.SUCCESS);return result;}public static <T>Result Fail(T data){Result result=new Result<>();result.setData(data);result.setCode(ResultStatus.FAIL);return result;}public static <T>Result Nologin(T data){Result result=new Result<>();result.setData(data);result.setCode(ResultStatus.NOLOGIN);return result;}
}

然后接下来我们要对这个login进行数据的对比,也就是查看前端发送来的数据和我们数据库中的数据是否一致,那么这部分的代码应该怎么写呢?这里我们需要先对我们的数据库进行配置,配置文件就是yml。内容如下

spring:application:name: MyBookSystem# ???????datasource:url: jdbc:mysql://127.0.0.1:3308/book_test?characterEncoding=utf8&useSSL=false #这里也是自己配置的写username: #连接数据库的用户名称password: #连接数据库使用的密码driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:configuration:map-underscore-to-camel-case: true #????????mapper-locations: classpath:mybatis/*Mapper.xml #数据库xml文件的扫描路径
logging:file:name: spring-book.log
server:port: 9090

那么接下来我们按照分层来写的Controller层调用的就是Service层,然后Service层调用的是Mapper层,Mapper层负责去数据库里面拿数据,因此我们先从Mapper层来写那么mapper层其实就是绑定了响应的xml文件因此我们还需要一个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.example.mybooksystem2.Mapper.UserInfoMapper"><select id="SelectByName" resultType="com.example.mybooksystem2.Model.UserInfo">select * from user_info where user_name=#{userName} --绑定我们的mapper类中的方法</select>
</mapper>

Mapper

package com.example.mybooksystem2.Mapper;import com.example.mybooksystem2.Model.UserInfo;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserInfoMapper {UserInfo SelectByName(String userName);
}

Service

package com.example.mybooksystem2.Service;
import com.example.mybooksystem2.Mapper.UserInfoMapper;
import com.example.mybooksystem2.Model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {@AutowiredUserInfoMapper userInfoMapper;public UserInfo SelectByName(UserInfo userInfo){return userInfoMapper.SelectByName(userInfo.getUserName());}
}

Controller

package com.example.mybooksystem2.Controller;import com.example.mybooksystem2.Enums.ResultStatus;
import com.example.mybooksystem2.Model.*;
import com.example.mybooksystem2.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {@AutowiredUserService userService;@RequestMapping("/login")public com.example.mybooksystem2.Model.Result<String> login(com.example.mybooksystem2.Model.UserInfo userInfo){com.example.mybooksystem2.Model.Result<String> result=new com.example.mybooksystem2.Model.Result<>();if(userInfo==null){result.setData("");result.setCode(ResultStatus.FAIL);System.out.println("未收到登录信息");result.setErrMsg("未收到登录信息");return  result;}if(userInfo.getUserName()==null||userInfo.getPassword()==null){result.setData("");result.setCode(ResultStatus.FAIL);System.out.println("未收到登录信息");result.setErrMsg("未收到登录信息");return  result;}com.example.mybooksystem2.Model.UserInfo userInfo1=userService.SelectByName(userInfo);if(userInfo1==null){result.setCode(ResultStatus.FAIL);result.setData("");System.out.println("用户名或者密码错误");return  result;}if(userInfo1.getPassword().equals(userInfo.getPassword())){result.setCode(ResultStatus.SUCCESS);result.setData("");System.out.println("成功登录");return  result;}return result;}
}

到这里登录界面就是搞定了那么接下来该实现最复杂的图书列表界面了

图书列表界面的创建

查看前端发送的请求

$.ajax({url: "/book/getBookListByPage" + location.search,type: "get",success: function (result) {//前端需要做更多的判断, 课堂不过多扩展// if (result.code == "NOLOGIN") { //用户未登录//     location.href = "login.html";// }if (result.data != null && result.data.records != null) {var finnalHtml = "";for (var book of result.data.records) {finnalHtml += '<tr>';finnalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '" id="selectBook" class="book-select"></td>';finnalHtml += '<td>' + book.id + '</td>';finnalHtml += '<td>' + book.bookName + '</td>';finnalHtml += '<td>' + book.author + '</td>';finnalHtml += '<td>' + book.count + '</td>';finnalHtml += '<td>' + book.price + '</td>';finnalHtml += '<td>' + book.publish + '</td>';finnalHtml += '<td>' + book.statusCN + '</td>';finnalHtml += '<td>';finnalHtml += '<div class="op">';finnalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>';finnalHtml += '<a href="javascript:void(0)" οnclick="deleteBook(' + book.id + ')">删除</a>';finnalHtml += '</div></td></tr>';}$("tbody").html(finnalHtml);var data = result.data;//翻页信息$("#pageContainer").jqPaginator({totalCounts: data.count, //总记录数pageSize: 10,    //每页的个数visiblePages: 5, //可视页数currentPage: data.pageRequest.pageNum,  //当前页码first: '<li class="page-item"><a class="page-link">首页</a></li>',prev: '<li class="page-item"><a class="page-link" href="javascript:void(0);">上一页<\/a><\/li>',next: '<li class="page-item"><a class="page-link" href="javascript:void(0);">下一页<\/a><\/li>',last: '<li class="page-item"><a class="page-link" href="javascript:void(0);">最后一页<\/a><\/li>',page: '<li class="page-item"><a class="page-link" href="javascript:void(0);">{{page}}<\/a><\/li>',//页面初始化和页码点击时都会执行onPageChange: function (page, type) {console.log("第" + page + "页, 类型:" + type);if (type == "change") {location.href = "book_list.html?pageNum=" + page;}}});}},error: function (error) {console.log(error);if (error != null && error.status == 401) {location.href = "login.html";}}});

在这里我们得到了我们的前端url是getBookListByPage然后根据返回信息我们可以知道,我们需要返回的信息有哪些,那么接下来就需要到我们的model层进行实现了

根据前端接收的返回值来编写model层

首先我们需要有图书的信息//BookInfo

package com.example.mybooksystem2.Model;import lombok.Data;import java.math.BigDecimal;
import java.util.Date;
@Data
public class BookInfo {private Integer id;private String bookName;private String author;private Integer count;private BigDecimal price;private String publish;private Integer status; //1-正常   2-不可借阅private String statusCN;private Date createTime;private Date updateTime;
}

其次我们需要有每页要显示多少条数据那么我们需要一个接收请求的类因为前端给我们发送的数据其实是一个这一页要的数据是从多少到多少的那种格式因此我们也需要按照这个格式去接收请求

package com.example.mybooksystem2.Model;
import lombok.Data;
@Data
public class PageRequest {private Integer pageNum=1;private Integer pageSize=10;private Integer offSet;public Integer getOffSet(){return (pageNum-1)*pageSize;}
}

然后我们还需要处理返回值因此我们需要对返回值进行处理的类也就是PageResult

package com.example.mybooksystem2.Model;
import com.example.mybooksystem2.Model.PageRequest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class PageResult<T> {private List<T> records;private Integer count;private PageRequest pageRequest;
}

然后根据项目演示中我们发现我们需要将状态码转换为字符串因此我们后端可以直接进行转换方法就是制作一个enum即可

package com.example.mybooksystem2.Enums;
public enum BookStatus {DELETE(0,"删除"),NORMAL(1,"可借阅"),FORBIDDEN(2,"不可借阅"),;private Integer code;BookStatus(Integer code,String desc){this.code=code;this.desc=desc;}public Integer getCode() {return code;}public static BookStatus getDescBycode(Integer code){switch (code){case 0: return DELETE;case 1: return NORMAL;case 2:default:return FORBIDDEN;}}public void setCode(Integer code) {this.code = code;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}private String desc;
}

根据请求编写controller层

然后根据上面实现的类我们可以编写出controller的代码首先我们获得的是,PageRequest,其次我们返回的是一个Result,然后这个Result中包含的是一个PageResult,听到这里有很多人可能头有些大?这是什么?我给大家解读以下请看下面的这个代码

@RestController
@RequestMapping("/book")
public class BookController {@AutowiredBookService bookService;@RequestMapping("/getBookListByPage")public Result<PageResult<BookInfo>> getBookListByPage(PageRequest pageRequest){PageResult<BookInfo>bookInfoPageResult=bookService.selectBookByPage(pageRequest);return Result.success(bookInfoPageResult);}
}

请结合前端一起看一下这个代码,前端中我们需要判断是否success,因此我们的返回值必须有个字段时success可是这样一看的话我们就需要Result,这里我们注意Result是一个模板类,因此我们可以进行套娃,首先先讨一个PageResult这样就可以使得我们的返回值可以显示这个图书的状态,Result可以显示我们后端是否执行成功,只用BookInfo就可以展示每本图书的信息了。

根据controller编写Service

那么接下来就要你根据上面的controller我们看一下项目演示图片
在这里插入图片描述
我们发现我们包含的元素,有一个状态这个状态时一个字符串的形式表现出来的,但是Controller层我们可以看到他时负责和前端交互然后把数据返回的,也就是说这里的数据处理需要依靠Service层来进行才可以那么Service该如何进行呢?代码如下

@Service
public class BookService {@AutowiredBookInfoMapper bookInfoMapper;public PageResult<BookInfo>selectBookByPage(PageRequest pageRequest){List<BookInfo>bookInfos=bookInfoMapper.QueryBookByPage(pageRequest.getOffSet(),pageRequest.getPageSize());for(BookInfo bookInfo:bookInfos){bookInfo.setStatusCN(BookStatus.getDescBycode(bookInfo.getStatus()).getDesc());}return new PageResult<>(bookInfos,count,pageRequest);}
}

这里大部分代码应该都是可以理解的,我给捋一下,首先就是service代码调用mapper代码,maper的内部其实使用的时select的limit查询从而使得我们可以获取到某一页的数据。然后当我们获取到数据后这个数据保存在我们设置的List < BookInfo>中,接下来就是到了最难懂的一步,我们可以看到我们在显示的时候显示的状态是一个String字符串,可是我们的BookInfo 在数据库中为了存储方便使用的是一个整数,因此这个该怎么办呢?这时候我们就用到了我们的BookInfo中的另一个参数
在这里插入图片描述
也就是statusCN这个变量是一个String类型他保存的就是从status转换来的字符串,当然了如果我们使用if判断的形式那太麻烦了因此我们设置的有一个类那就是我们的BookStatus在这里面我们有一个方法
getDescBycode()我们来看一下这个方法的代码如下

    public static BookStatus getDescBycode(Integer code){switch (code){case 0: return DELETE;case 1: return NORMAL;case 2:default:return FORBIDDEN;}}

在这里插入图片描述
我们结合上面两个部分来看我们可以得出它可以返回一个BookStatus对象这个对象包含的有各种数字代表的是哪种状态然后我们再调用BookStatus中的getDesc()方法就可以得出我们的这本书是一个什么状态了。

根据Service编写Mapper层

那么有了上面Service层的介绍我想大家也能猜到Mapper层是什么了,他就是一个limit查询代码如下

    @Select("select * from book_info where status!=0 order by id asc limit #{offset},#{limit}")List<BookInfo>QueryBookByPage(Integer offset,Integer limit);

添加图书

然后接下来我们来实现添加图书有了上面的经验这里其实我们就很简单了
在这里插入图片描述

前端

首先依旧是第一步结合前端推后端

      function add() {$.ajax({url: "/book/addBook",type: "post",data: $("#addBook").serialize(),success: function (result) {if (result.code == "SUCCESS" && result.data == "") {//添加成功location.href = "book_list.html";} else {alert(result.data);}}, error: function (error) {//用户未登录if (error != null && error.status == 401) {location.href = "login.html";}}});}

首先通过前端我们可以得到下面这些信息,首先我们的url是addBook,其次我们的数据其实就是表格中输入的数据那么有了这些加上上面的基础那么你的想法是什么呢?
反正我的第一想法就是利用BookInfo接收到前端获取到的信息,然后调用Service,Service调用Mapper然后使用一个insert语句将这个记录插入进去。然后我们再来看一下它的返回值,我们可以看到它的返回值依然是一个SUCCESS+一个空字符串那就好写了我们直接上代码

后端Controller

    @RequestMapping("/addBook")public Result<String>addBook(BookInfo bookInfo){Integer n= bookService.addBook(bookInfo);Result<String>result=new Result<>();if(n<=0){result.setCode(ResultStatus.FAIL);result.setData("失败");return result;}if(n==1){result.setData("");result.setCode(ResultStatus.SUCCESS);return result;}return result;}

这里首先后端调用Service根据Service的返回值进行判断,插入是否成功

Service

Service层调用Mapper层来更改数据库

    public Integer addBook(BookInfo bookInfo){Integer n=bookInfoMapper.addBook(bookInfo);return n;}

Mapper

然后mapper层写出接口,再有xml文件绑定这个接口方法进行sql代码的实现。

    Integer addBook(BookInfo bookInfo);
        <insert id="addBook">insert into book_info (book_name,author,`count`,`price`,publish)values (#{bookName},#{author},#{count},#{price},#{publish})</insert>

经过上面的步骤我们的图书就添加进去了。

修改书籍信息

修改书籍信息分为两步我们从前端页面来进行介绍
在这里插入图片描述
首先当我们点击修改之后会跳转到updata.html,
在这里插入图片描述
此时我们的界面中会显示原有的图书信息,那么此时我们的图书信息该怎么获取呢?很明显在更改操作开始前先进行了一个查找工作,那么既然如此我们需要先实现一个接口也就是queryBookById,那么按照我们的代码逻辑,首先controller层实现接口调用Service层,Service层调用Mapper层我们来看一下
Mapper层

    @Select("select * from book_info where id=#{id}")BookInfo queryBookById(Integer id);

Service层

   public BookInfo queryBookById(Integer id){return bookInfoMapper.queryBookById(id);}

controller层

    @RequestMapping("/queryBookById")public Result<BookInfo>queryBookById(Integer bookId){BookInfo bookInfo=bookService.queryBookById(bookId);return Result.success(bookInfo);}

然后我们继续实现updata这里比较困难的地方就是有时候我们更改可能只更改名称其余的字段可能是空因此我们需要在xml编写sql代码

        <update id="updateBook">update book_info<set><if test="bookName!=null">book_name=#{bookName},</if><if test="author!=null">author=#{author},</if><if test="count!=null">`count` =#{count},</if><if test="price!=null">price=#{price},</if><if test="publish!=null">publish=#{publish},</if><if test="status!=null">status=#{status}</if></set>where id=#{id}</update>

那么有了Mapper层的xml代码之后我们其他的代码就很容易实现了。

批量删除

批量删除是怎么样的呢?其实批量删除就是传入一个数组这个数组里面的元素是你要删除的bookId
那么我们用到的Sql语句是怎么样的呢我们来看一下xml中的代码即可首先我们要先知道book_info使用的是什么删除我们在未来工作中一般都是使用逻辑删除,也就是说这个数据并不是真的被删除了而是被逻辑删除了,如何逻辑删除就是使用一个status字段,用它来标记即可sql代码如下
XML代码

        <delete id="batchDeleteBook">update book_info set status=0where id in <foreach collection="ids" open="(" close=")" item="id" separator=",">#{id}</foreach></delete>

这里我使用了foreach构造出了一个序列。


Mapper代码

 Integer batchDeleteBook(List<Integer>ids);

Service代码

    public Integer batchDeleteBook(List<Integer>ids){return bookInfoMapper.batchDeleteBook(ids);}

Controller代码

    @RequestMapping("/batchDeleteBook")public Result<String>batchDeleteBook(@RequestParam List<Integer>ids){Integer n=bookService.batchDeleteBook(ids);if(n==ids.size()){return Result.success("");}else{return Result.Fail("");}}

结尾

这里代码主体已经完成如果有感兴趣的人可以访问我的github或者gittee获取前端代码以及获取我更新了的后端代码
gitee连接
github连接

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux C语言:指针与数组

一、指针与数组的基本用法 数组指针是指数组在内存中的起始地址&#xff0c;数组元素的地址是指数组元素在内存中的起始地址一维数组的数组名为一维数组的指针&#xff08;起始地址&#xff09; 例如&#xff1a; double x[8]; 因此&#xff0c;x为x数组的起始地址 设指针变…

什么是浏览器指纹

在数字互联网时代&#xff0c;我们的在线活动几乎都会留下痕迹。其中&#xff0c;浏览器指纹就像我们的数字身份证&#xff0c;让网站能够识别和追踪用户。本文将详细介绍浏览器指纹是什么&#xff0c;它如何工作。 一、什么是浏览器指纹 浏览器指纹&#xff08;Browser Fing…

【C语言 || 排序】希尔排序

文章目录 前言1.希尔排序1.1 直接插入排序1.2 直接插入排序的实现1.2.1 直接插入排序的代码实现 1.3 直接插入排序的时间复杂度1.4 希尔排序1.4.1 希尔排序概念1.4.1 希尔排序的代码实现 前言 1.希尔排序 1.1 直接插入排序 在写希尔排序之前&#xff0c;我们需要先了解直接插入…

stable diffusion 局部重绘 reference-only api 接口调试

webUI api payload 插件生成的接口参数不准确&#xff0c;reference-only 的image不是对象&#xff0c;就是不同字符串字段&#xff0c;直接传&#xff0c;不是套image。 综上&#xff0c;那个插件参数不确定&#xff0c;应直接看插件的源码&#xff0c;看它接受什么参数 错误…

Paper Reading: PAMS:通过参数化最大尺度量化超分辨率

PAMS: Quantized Super-Resolution via Parameterized Max Scale PAMS&#xff1a;通过参数化最大尺度量化超分辨率, ECCV 2020 paper: https://arxiv.org/pdf/2011.04212.pdf GitHub: https://github.com/colorjam/PAMS 摘要 深度卷积神经网络&#xff08;DCNNs&#xff09;…

“Photoshop AI插件:StartAI的全面使用攻略

随着人工智能技术的飞速发展&#xff0c;Photoshop作为设计师们不可或缺的工具&#xff0c;也在不断地融入AI技术&#xff0c;以提升设计效率和效果。在2024年&#xff0c;PSAI插件StartAI因其强大的功能和易用性&#xff0c;成为了Photoshop用户的得力帮手。下面来给大家详细介…

CentOS 7x 使用Docker 安装oracle11g完整方法

1.安装docker-ce 安装依赖的软件包 yum install -y yum-utils device-mapper-persistent-data lvm2添加Docker的阿里云yum源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo更新软件包索引 yum makecache fast查看docker…

深入浅出 Babel:现代 JavaScript 的编译器

在现代前端开发中&#xff0c;JavaScript 的版本更新速度非常快&#xff0c;新的语法和特性层出不穷。然而&#xff0c;旧版本的浏览器并不总是支持这些新特性。为了确保代码的兼容性和稳定性&#xff0c;我们需要一个工具来将现代 JavaScript 代码转换为旧版本的代码。Babel 就…

信息打点web篇----企业宏观资产打点

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 专栏描述&#xff1a;因为第一遍过信息收集的时候&#xff0c;没怎么把收集做回事 导致后来在实战中&#xff0c;遭遇资产获取少&#xff0c;可渗透点少的痛苦&#xff0c;如今决定 从头来过&#xff0c;全面全方位…

python安装系列问题

python3.4版本以上安装了python之后自带安装python。 1、换源 以Windows&#xff0c;清华源为例&#xff1a; 直接在user目录中创建一个pip目录&#xff0c;例如&#xff1a;C:\Users\xx\pip&#xff0c;新建文件pip.ini&#xff0c;内容如下: [global] index-url https:/…

C#的Switch语句3(如何为一段代码应用多个case标签)

文章目录 上一篇文章中断函数执行堆叠caseswitch中实用的字符串函数将字符串转换为小写 switch例子 上一篇文章 C#的Switch语句2 中断函数执行 switch语句内部可以使用return语句&#xff0c;这为控制程序流程和函数返回值提供了一种直接的方式。 当在switch语句块中遇到re…

CleanShot X for Mac v4.7 屏幕截图录像工具(保姆级教程,小白轻松上手,简单易学)

Mac分享吧 文章目录 一、准备工作二、部分特有功能效果1、截图软件的普遍常用功能&#xff08;画框、箭头、加文字等&#xff09;都具备&#xff0c;不再详细介绍2、ABCD、1234等信息标注&#xff08;每按一下鼠标&#xff0c;即各是A、B、C、D...等&#xff09;3、截图更换背…

SD-WAN组网如何帮助企业降低网络成本?

企业在构建IT网络时&#xff0c;常常面临节省费用和提升效益的挑战。IT开销主要包括设备、网络和维护成本。利用OgCloud的SD-WAN组网方案&#xff0c;企业可以有效地应对这些问题。 企业专线网络的高成本问题 企业专线的费用较高&#xff0c;而且数据不能同时在多条专线上传输。…

【linux】Valgrind工具集详解(十六):交叉编译、移植到arm(失败)

1、源码下载 官网:https://valgrind.org/ 源码:https://valgrind.org/downloads/current.html 2、配置 ./configure CC=arm-linux-gnueabihf-gcc \CXX=arm-linux-gnueabihf-g++ \AR=arm-linux-gnueabihf-ar \--host=arm-linux-gnueabihf \--pr

Postman如何在本地测试服务接口

项目架构及背景&#xff1a; 网关微服务多个业务微服务 服务部署在阿里云上&#xff0c;文件服务器用的是OSS。配置参数用Nacos进行统一管理。通过构建docker镜像包部署各业务微服务以及网关服务。 需求&#xff1a; 某一个业务微服务中开发了若干接口&#xff0c;需要在本地…

如何使用Indicator-Intelligence收集与威胁情报相关的域名和IPv4地址

关于Indicator-Intelligence Indicator-Intelligence是一款针对威胁情报的强大数据收集工具&#xff0c;该工具可以帮助广大研究人员通过威胁情报活动中生成的静态文件来查找与威胁行为相关的域名和IPv4地址。 需要注意的是&#xff0c;请在目标组织授权后再使用该工具进行安…

IFM易福门SV7500SV4200涡街流量计型号都是进口的。

IFM易福门SV7500SV4200涡街流量计型号都是进口的。工程余料。

数据质量管理-规范性管理

数据质量管理简介 数据质量管理是一个持续性的管理动作&#xff0c;有些人在做数据质量管理的时候会陷入一步到位的误区&#xff0c;想要通过一个工具、平台&#xff0c;或者一套质检规则就完成整体的数据质量管理&#xff0c;而实际数据质量管理从数据接入的那一刻就需要介入…

热门常用在线免费工具

图片&绘图 免费且易于使用的在线PDF工具 nullhttps://tools.pdf24.org/zh/免费的在线图片压缩工具 TinyPNG – Compress WebP, PNG and JPEG images intelligentlyFree online image compressor for faster websites! Reduce the file size of your WEBP, JPEG, and PNG…

互联网应用主流框架整合之SpingMVC运转逻辑及高级应用

Spring MVC处理器的执行过程 在SpringMVC的流程中&#xff0c;它会把控制器的方法封装为处理器(Handler)&#xff0c;为了更加灵活&#xff0c;SpringMVC还提供了处理器的拦截器&#xff0c;从而形成了一条包括处理器和拦截器的执行链&#xff0c;即HandlerExecutionChain&…