图书管理系统(SpringBoot+SpringMVC+MyBatis)

目录

1.数据库表设计

2.引入MyBatis和MySQL驱动依赖

3.配置数据库&日志

4.Model创建

5.用户登录功能实现

 6.实现添加图书功能

7.实现翻页功能


1.数据库表设计

数据库表是应⽤程序开发中的⼀个重要环节, 数据库表的设计往往会决定我们的应⽤需求是否能顺利实, 甚至决定我们的实现方式. 如何设计表以及这些表有哪些字段、关系也是非常重要.

数据库表设计是依据业务需求来设计的,数据库表通常分两种: 实体表和关系表.

创建数据库 book_test

 -- 创建数据库
 DROP DATABASE IF EXISTS book_test;
 CREATE DATABASE book_test DEFAULT CHARACTER SET utf8mb4;
 USE book_test;
 -- ⽤户表
 DROP TABLE IF EXISTS user_info;
 CREATE TABLE user_info (
         `id` INT NOT NULL AUTO_INCREMENT,
         `user_name` VARCHAR ( 128 ) NOT NULL,
         `password` VARCHAR ( 128 ) NOT NULL,
         `delete_flag` TINYINT ( 4 ) NULL DEFAULT 0,
         `create_time` DATETIME DEFAULT now(),
         `update_time` DATETIME DEFAULT now() ON UPDATE now(),
          PRIMARY KEY ( `id` ),
 UNIQUE INDEX `user_name_UNIQUE` ( `user_name` ASC )) ENGINE = INNODB DEFAULT CHARSET  = utf8mb4 COMMENT = '⽤户表 ';
 -- 图书表
 DROP TABLE IF EXISTS book_info;
 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 now(),
         `update_time` DATETIME DEFAULT now() ON UPDATE now(),
 PRIMARY KEY ( `id` )
 ) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;

 -- 初始化数据
 INSERT INTO user_info ( user_name, PASSWORD ) VALUES ( "admin", "admin" );
 INSERT INTO user_info ( user_name, PASSWORD ) VALUES ( "zhangsan", "123456" );
 -- 初始化图书数据
 INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('活着 ','Romised',100,12.2,'出版社');
 INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('不活着', 'Romised', 100, 22.2, '出版社');
 INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('想活着 ','Romised',100,32.2,'出版社');
 INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('要活着 ','Romised',100,42.2,'出版社');

2.引入MyBatis和MySQL驱动依赖

修改pom.xml文件:

 <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.1</version>
 </dependency>
 <dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
 </dependency>

3.配置数据库&日志

修改application.yml配置文件:

# 数据库连接配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  configuration:
    map-underscore-to-camel-case: true #配置驼峰自动转换
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句
  mapper-locations: classpath:mapper/**Mapper.xml
# 设置日志文件的文件名
logging:
  file:
    name: logger/spring-book.log

4.Model创建

创建UserInfo类:

@Data
public class UserInfo {
    private Integer id;
    private String userName;
    private String password;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

创建BookInfo类:

@Data
public class BookInfo {
    private Integer id;
    private String bookName;
    private String author;
    private Integer count;
    //前端展示精度
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private BigDecimal price;
    private String publish;
    private Integer status; //0-删除   1-可借阅,2-不可借阅
    private String statusCN;
}

5.用户登录功能实现

约定前后端交互接口:

 [请求]
 /user/login
 Content-Type: application/x-www-form-urlencoded; charset=UTF-8

 [参数]
 name=zhangsan&password=123456 8
 [响应]
 true  //账号密码验证正确 , 否则返回false

浏览器给服务器发送/user/login这样的HTTP请求,服务器给浏览器返回Boolean类型的数据

实现服务器代码

控制层:从数据库中, 根据名称查询用户, 如果可以查到, 并且密码⼀致, 就认为登录成功 

创建UserController:

@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/login")
    public Boolean login(String userName, String password, HttpSession session){
        //校验参数是否为空
        if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
            return false;
        }

        //验证账号密码是否正确
        //1. 根据用户名去查找用户信息
        UserInfo userInfo = userService.getUserInfoByName(userName);
        //2. 比对密码是否正确
        if (userInfo==null || userInfo.getId()<=0){
            return false;
        }
        if (password.equals(userInfo.getPassword())){
            //账号密码正确
            //存Session
            userInfo.setPassword("");
            session.setAttribute(Constants.SESSION_USER_KEY,userInfo);
            return true;
        }

        return false;

    }
}

业务层:

创建UserService:

@Service
public class UserService {
    @Autowired
    private UserInfoMapper userInfoMapper;

    public UserInfo getUserInfoByName(String name){
        return userInfoMapper.selectUserByName(name);
    }
}

数据层:

创建UserInfoMapper:

@Mapper
public interface UserInfoMapper {
    /**
     * 根据用户名称查询用户信息
     * @param name
     * @return
     */
    @Select("select * from user_info where user_name=#{name}")
    UserInfo selectUserByName(String name);

}

这边使用*是为了方便观察,开发中需要挨个写出数据库字段名

 测试:

部署程序,验证服务器是否能够正确返回数据,可以在Postman中输入URL进行测试,最好联动前端一起进行测试:

输⼊错误的⽤户名和密码, 页面弹窗警告

 输入正确的用户名和密码, 页面正常跳转到booklist.html页面

 6.实现添加图书功能

约定前后端交互接口:

 [请求]
 /book/addBook
 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
 [参数]
 bookName=图书1&author=作者1&count=23&price=36&publish=出版社1&status=1 
 [响应]
 ""   //失败信息 , 成功时返回空字符串

我们约定,浏览器给服务器发送book/addBook这样的HTTP请求,以from表单的形式提交数据

务器返回处理结果, 返回""表示添加图书成功, , 返回失败信息.

实现服务器代码 

控制层:

创建BookController:

@Slf4j
@RequestMapping("/book")
@RestController
public class BookController {

    @Autowired
    private BookService bookService;

    @RequestMapping("/getBookListByPage")
    public Result getBookListByPage(PageRequest pageRequest, HttpSession session){
        log.info("查询翻页信息, pageRequest:{}",pageRequest);
        //用户登录校验
        UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
        if (userInfo==null|| userInfo.getId()<=0 || "".equals(userInfo.getUserName())){
            //用户未登录
           return Result.unlogin();
        }
        //校验成功
        if (pageRequest.getPageSize()<0 || pageRequest.getCurrentPage()<1){
            return Result.fail("参数校验失败");
        }
        PageResult<BookInfo> bookInfoPageResult = null;
        try {
            bookInfoPageResult = bookService.selectBookInfoByPage(pageRequest);
            return Result.success(bookInfoPageResult);
        }catch (Exception e){
            log.error("查询翻页信息错误,e:{}",e);
            return Result.fail(e.getMessage());
        }
    }

    @RequestMapping(value = "/addBook", produces = "application/json")
    public String addBook(BookInfo bookInfo){
        log.info("接收到添加图书请求, bookInfo:{}",bookInfo);
        //参数校验
        if (!StringUtils.hasLength(bookInfo.getBookName())
                || !StringUtils.hasLength(bookInfo.getAuthor())
                || bookInfo.getCount()<0
                || bookInfo.getPrice()==null
                || !StringUtils.hasLength(bookInfo.getPublish())){
            return "参数校验失败, 请检查入参";
        }
        Integer result = bookService.addBook(bookInfo);
        if (result<=0){
            log.error("添加图书出错:bookInfo:{}",bookInfo);
            return "添加图书出错, 请联系管理人";
        }
        return "";
    }
}

业务层:

创建BookService:

@Slf4j
@Service
public class BookService {

    @Autowired
    private BookInfoMapper bookInfoMapper;  
  /**
     * 添加图书
     *
     * @param bookInfo
     * @return
     */
    public Integer addBook(BookInfo bookInfo) {
        Integer result = 0;
        try {
            result = bookInfoMapper.insertBook(bookInfo);
        } catch (Exception e) {
            log.error("添加图书出错, e:{}", e);
        }
        return result;
    }
}

数据层:

创建BookInfoMapper文件:

@Mapper
public interface BookInfoMapper {
    /**
     * 获取当前页的信息
     * @param offset
     * @param pageSize
     * @return
     */
    @Select("select * from book_info where status !=0 " +
            "order by id asc limit #{offset},#{pageSize}")
    List<BookInfo> selectBookInfoByPage(Integer offset, Integer pageSize);

    @Insert("insert into book_info (book_name,author, count, price, publish, status) " +
            "values(#{bookName}, #{author}, #{count}, #{price},#{publish}, #{status})")
    Integer insertBook(BookInfo bookInfo);
}

前端代码中补全add():

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

                }
            });        
            
        }

7.实现翻页功能

假设数据库中的数据有很多,一下子全部展示出来肯定不现实,我们可以使用分页来解决这个问题

分页时, 数据是如何展示的呢 1: 显⽰1-10 条的数据、第2: 显⽰11-20 条的数据 3: 显⽰21-30 条的数据 以此类推...

要想实现这个功能, 从数据库中进行分页查 ,我们要使用LIMIT关键字

查询第一页的SQL语句:

 SELECT * FROM book_info LIMIT 0,10

查询第二页的SQL语句:

 SELECT * FROM book_info LIMIT 10,10

查询第三页的SQL语句:

 SELECT * FROM book_info LIMIT 20,10

观察以上SQL语句 ,发现: 开始索引⼀直在改变, 每页显⽰条数是固定的 开始索引的计算公式: 开始索引 = (当前页码 - 1) * 每页显示条数

 

前端在发起查询请求时 ,需要向服务端传递的参数 

currentPage  当前页码默认值为1

pageSize 每页显示条数默认值为10

为了项⽬更好的扩展性, 通常不设置固定值,而是以参数的形式来进行传递 扩展性: 软件系统具备面对未来需求变化而进行扩展的能⼒

比如当前需求⼀页显示10, 后期需求改为⼀页显示20, 后端代码不需要任何修改

后端响应时, 需要响应给前端的数据

records 所查询到的数据列表(存储到List 集合中)

total  总记录数 (用于告诉前端显示多少页, 显示页数:(total+pageSize-1)/pageSize

显示页数totalPage 计算公式为 : total % pagesize == 0 ? total / pagesize : (total / pagesize)+1 ;

pagesize - 1 total / pageSize 的最⼤的余数 ,所以(total + pagesize -1) / pagesize就得到总页数

 翻页请求和响应部分, 我们通常封装在两个对象中

翻页请求对象:

 @Data
 public class PageRequest {
     private int currentPage = 1; // 当前页
     private int pageSize = 10; // 每页中的记录数
     private int offset; 
     public int getOffset() {
         return (currentPage-1) * pageSize;
     }
  }

翻页列表结果类:

 import lombok.Data; 
 import java.util.List; 
 @Data
 public class PageResult<T> {
     private int total;//所有记录数
     private List<T> records; // 当前页数据 
     public PageResult(Integer total, List<T> records) {
        this.total = total;
        this.records = records;
     }
 }

 返回结果中, 使⽤泛型来定义记录的类型 

约定前后端交互接口

 [请求]
 /book/getListByPage?currentPage=1
 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
 [参数]


 [响应]
 Content-Type: application/json 10
 {
     "total": 25,
     "records": [{
            "id": 25,
            "bookName": "图书21",
            "author": "作者2",
            "count": 29,
            "price": 22.00,
            "publish": "出版社1",
            "status": 1,
            "statusCN": "可借阅 "
     }, {
             ......
     } ]
 }

我们约定,浏览器给服务器发送book/getListByPage这样的HTTP请求,通过currentPage参数告诉服务器当前请求为第几页的数据, 后端根据请求参, 返回对应页的数据

实现服务器代码 

控制层:

完善 BookController:

@Slf4j
@RequestMapping("/book")
@RestController
public class BookController {

    @Autowired
    private BookService bookService;

    @RequestMapping("/getBookListByPage")
    public Result getBookListByPage(PageRequest pageRequest, HttpSession session){
        log.info("查询翻页信息, pageRequest:{}",pageRequest);
//        //用户登录校验
//        UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
//        if (userInfo==null|| userInfo.getId()<=0 || "".equals(userInfo.getUserName())){
//            //用户未登录
//            return Result.unlogin();
//        }
        //校验成功
        if (pageRequest.getPageSize()<0 || pageRequest.getCurrentPage()<1){
            return Result.fail("参数校验失败");
        }
        PageResult<BookInfo> bookInfoPageResult = null;
        try {
            bookInfoPageResult = bookService.selectBookInfoByPage(pageRequest);
            return Result.success(bookInfoPageResult);
        }catch (Exception e){
            log.error("查询翻页信息错误,e:{}",e);
            return Result.fail(e.getMessage());
        }
    }

    @RequestMapping(value = "/addBook", produces = "application/json")
    public String addBook(BookInfo bookInfo){
        log.info("接收到添加图书请求, bookInfo:{}",bookInfo);
        //参数校验
        if (!StringUtils.hasLength(bookInfo.getBookName())
                || !StringUtils.hasLength(bookInfo.getAuthor())
                || bookInfo.getCount()<0
                || bookInfo.getPrice()==null
                || !StringUtils.hasLength(bookInfo.getPublish())){
            return "参数校验失败, 请检查入参";
        }
        Integer result = bookService.addBook(bookInfo);
        if (result<=0){
            log.error("添加图书出错:bookInfo:{}",bookInfo);
            return "添加图书出错, 请联系管理人";
        }
        return "";

    }

    @RequestMapping("/queryBookInfoById")
    public BookInfo queryBookInfoById(Integer bookId){
//        long start = System.currentTimeMillis();
        log.info("根据ID查询图书, bookId:"+bookId);
        BookInfo bookInfo = null;
        try {
            bookInfo = bookService.queryBookInfoById(bookId);
        }catch (Exception e){
            log.error("查询图书失败, e:{}",e);
        }
//        long end = System.currentTimeMillis();
//        log.info("queryBookInfoById 执行耗时: "+ (end-start) + "ms");
        return bookInfo;
    }

    @RequestMapping(value = "/updateBook",  produces = "application/json")
    public String updateBook(BookInfo bookInfo){
        log.info("接收到更新图书的请求, bookInfo:{}",bookInfo);
        Integer result = bookService.updateBook(bookInfo);
        if (result == 0){
            log.error("更新图书失败, 请联系管理员");
            return "更新图书失败, 请联系管理员";
        }
        return "";
    }

    @RequestMapping(value = "/batchDelete", produces = "application/json")
    public String batchDelete(@RequestParam List<Integer> ids){
        log.info("接收请求, 批量删除图书, 图书ID:{}",ids);
        Integer result = bookService.batchDelete(ids);
        if (result<=0){
            log.error("批量删除失败, ids:{}",ids);
            return "批量删除失败, 请联系管理员";
        }
        return "";
    }
}

业务层:

BookService

@Slf4j
@Service
public class BookService {

    @Autowired
    private BookInfoMapper bookInfoMapper;

    public PageResult<BookInfo> selectBookInfoByPage(PageRequest pageRequest) {
        if (pageRequest == null) {
            return null;
        }
        //获取总记录数
        Integer count = bookInfoMapper.count();
        //获取当前记录
        List<BookInfo> bookInfos = bookInfoMapper.selectBookInfoByPage(pageRequest.getOffset(), pageRequest.getPageSize());
        if (bookInfos != null && bookInfos.size() > 0) {
            for (BookInfo bookInfo : bookInfos) {
                //根据status 获取状态的定义
                bookInfo.setStatusCN(BookStatusEnum.getNameByCode(bookInfo.getStatus()).getName());
            }
        }

        return new PageResult<>(bookInfos, count, pageRequest);

    }

    /**
     * 添加图书
     *
     * @param bookInfo
     * @return
     */
    public Integer addBook(BookInfo bookInfo) {
        Integer result = 0;
        try {
            result = bookInfoMapper.insertBook(bookInfo);
        } catch (Exception e) {
            log.error("添加图书出错, e:{}", e);
        }
        return result;
    }

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

    /**
     * 更新图书
     * @param bookInfo
     * @return
     */
    public Integer updateBook(BookInfo bookInfo) {
        Integer result = 0;
        try {
            result = bookInfoMapper.updateBook(bookInfo);
        } catch (Exception e) {
            log.error("更新图书失败, e:{}", e);
        }
        return result;
    }
    public Integer batchDelete(List<Integer> ids){
        Integer result =0;
        try {
            result = bookInfoMapper.batchDelete(ids);
        }catch (Exception e){
            log.error("批量删除图书失败, ids:{}",ids);
        }
        return result;
    }
}

 翻页信息需要返回数据的总数和列表信息, 需要查两次SQL

 图书状态: 图书状态和数据库存储的status有⼀定的对应关系

如果后续状态码有变动, 我们需要修改项目中所有涉及的代码, 这种情况, 通常采用枚举类来处理映射关系

数据层:

翻页查询SQL

@Mapper
public interface BookInfoMapper {
    /**
     * 获取当前页的信息
     * @param offset
     * @param pageSize
     * @return
     */
    @Select("select * from book_info where status !=0 " +
            "order by id asc limit #{offset},#{pageSize}")
    List<BookInfo> selectBookInfoByPage(Integer offset, Integer pageSize);

    /**
     * 获取总记录数
     * @return
     */
    @Select("select count(1) from book_info where status !=0")
    Integer count();
}

 实现客户端代码:

function getBookList() {
                $.ajax({
                    type: "get",
                    url: "/book/getBookListByPage" + location.search,
                    success: function (result) {
                        //真实的前端处理逻辑, 要比咱们代码复杂
                        if (result.code == "UNLOGIN") {
                            location.href = "login.html";
                            return;
                        }

                        var finalHtml = "";
                        //加载列表
                        var pageResult = result.data;
                        for (var book of pageResult.records) {
                            //根据每一条记录去拼接html, 也就是一个tr
                            finalHtml += '<tr>';
                            finalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '" id="selectBook" class="book-select"></td>';
                            finalHtml += '<td>' + book.id + '</td>';
                            finalHtml += '<td>' + book.bookName + '</td>';
                            finalHtml += '<td>' + book.author + '</td>';
                            finalHtml += '<td>' + book.count + '</td>';
                            finalHtml += '<td>' + book.price + '</td>';
                            finalHtml += '<td>' + book.publish + '</td>';
                            finalHtml += '<td>' + book.statusCN + '</td>';
                            finalHtml += '<td><div class="op">';
                            finalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>';
                            finalHtml += '<a href="javascript:void(0)" onclick="deleteBook(' + book.id + ')">删除</a>';
                            finalHtml += '</div></td></tr>';
                        }

                        $("tbody").html(finalHtml);

                        //翻页信息
                        $("#pageContainer").jqPaginator({
                            totalCounts: pageResult.total, //总记录数
                            pageSize: 10,    //每页的个数
                            visiblePages: 5, //可视页数
                            currentPage: pageResult.pageRequest.currentPage,  //当前页码
                            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?currentPage=" + page;
                                }

                            }
                        });

                    },
                    error: function (error) {
                        console.log(error);
                        if (error.status == 401) {
                            console.log("401");
                            location.href = "login.html";
                        }
                    }
                });
            }

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

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

相关文章

探索互联网寻址机制 | 揭秘互联网技术的核心,解析网络寻址

揭秘互联网技术的核心&#xff0c;解析网络寻址题 前提介绍局域网地址IP地址的分配方式动态IP分配机制内部网&#xff08;intranet&#xff09;ICANN负责IP分配DHCP协议获取IP地址 域名系统域名是什么域名工作方式hosts文件存储域名映射关系DNS分布式数据库DNS域名解析 Java进行…

增加软件投入的重要性:提升自动化程度与用户界面设计的价值

一、引言 在许多项目中&#xff0c;硬件系统通常占据了大量预算&#xff0c;而对软件的投入相对较少。这种不平衡往往导致软件自动化程度低、操作不便、界面简陋&#xff0c;过多的人工干预不仅降低了工作效率&#xff0c;还影响了用户体验。特别是对于一些国家项目&#xff0…

【背包题】oj题库

目录 1282 - 简单背包问题 1780 - 采灵芝 1888 - 多重背包&#xff08;1&#xff09;​编辑 1891 - 开心的金明 2073 - 码头的集装箱 1905 - 混合背包 1282 - 简单背包问题 #include <bits/stdc.h> using namespace std; //二维数组:dp[i][j]max(dp[i-1][j],v[i]dp[…

【three.js案例一】智慧星球

直接附上源码: import * as THREE from three; import { OrbitControls } from three/addons/controls/OrbitControls.js;//场景 const scene = new THREE.Scene();const geometry = new THREE.SphereGeometry(50,32,16);console.log(.postion,geometry.attributes.position)…

CorelDraw 2024软件安装包下载 丨不限速下载丨亲测好用

​简介&#xff1a; CorelDRAW Graphics Suite 订阅版拥有配备齐全的专业设计工具包&#xff0c;可以通过非常高的效率提供令人惊艳的矢量插图、布局、照片编辑和排版项目。价格实惠的订阅就能获得令人难以置信的持续价值&#xff0c;即时、有保障地获得独家的新功能和内容、…

【电路笔记】-共集极放大器

共集极放大器 文章目录 共集极放大器1、概述2、等效电路3、电压增益4、偏置方法5、输入阻抗6、输出阻抗7、电流增益8、示例:共集电极放大器的电压、电流和功率增益9、达林顿对10、总结1、概述 本文介绍另一种用于放大信号的双极晶体管架构,通常称为共集电极放大器 (CCA)。 C…

VSCode插件开发之初始化项目

VS code常见组件 在VS Code插件开发中&#xff0c;常用的组件有很多&#xff0c;这些组件可以帮助你实现各种功能和交互。以下是一些常见的组件&#xff1a; Extension API模块: 提供了许多类和方法&#xff0c;用于与VS Code编辑器进行交互&#xff0c;例如vscode.workspace用…

基于Python+Flask+MySQL+HTML的B站数据可视化分析系统

FlaskMySQLVue 基于PythonFlaskMySQLHTML的B站数据可视化分析系统 项目采用前后端分离技术&#xff0c;项目包含完整的前端HTML&#xff0c;以及Flask构成完整的前后端分离系统 爬虫文件基于selenium&#xff0c;需要配合登录账号 简介 主页 登录页面&#xff0c;用户打开浏…

JS读取目录下的所有图片/require动态加载图片/文字高亮

<template class"aa"><div class"demo-image__lazy container"><div class"head"><div class"left-bar"><div><span>综合</span></div><div><span>定位</span><…

ARM32开发--PWM高级定时器

目录 文章目录 前言 目标 学习内容 需求 高级定时器通道互补输出 开发流程 通道配置 打开互补保护电路 完整代码 练习题 总结 前言 在嵌入式软件开发中&#xff0c;PWM&#xff08;脉冲宽度调制&#xff09;技术被广泛应用于控制各种电子设备的亮度、速度等参数。…

分离式网络变压器与传统网络变压器在电路设计中如何选择?

Hqst盈盛&#xff08;华强盛&#xff09;电子导读&#xff1a;今天分享的是&#xff1a;分离式网络变压器与传统网络变压器在电路设计中如何选择&#xff1f; 首先&#xff0c;我们要了解传统网络变压器和分离式网络变压器在设计上主要有以下不同点&#xff1a; 1、传统网络变…

Java GUI编程

引言 图形用户界面&#xff08;GUI&#xff09;编程是使应用程序与用户进行交互的重要部分。Java提供了多种用于GUI开发的工具和库&#xff0c;最常用的是Swing和AWT。本文将详细介绍Java GUI编程的基础知识&#xff0c;包括Swing和AWT框架、事件处理以及高级GUI组件的使用&…

【Pandas驯化-02】pd.read_csv读取中文出现error解决方法

【Pandas】驯化-02pd.read_csv读取中文出现error解决方法 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 相关内容文档获取 微信公众号 &…

剃头师傅不担心AI大模型 到底谁该担心?

到底学什么&#xff0c;不会被AI替代&#xff1f; 我家附近有一家美容店&#xff0c;已经开了20多年&#xff0c;店里的一位伙计硬是靠着自己的坚持从学徒熬成了门店的合伙人&#xff0c;所以现在去理发时&#xff0c;我都叫他“周董”。 这天&#xff0c;我问他&#xff0c;…

网络通信的两大支柱:TCP与UDP协议详解(非常详细)零基础入门到精通,收藏这一篇就够了

在构建现代互联网通信的基石中&#xff0c;TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;起着至关重要的作用。本文将深入探讨两者的区别及应用场景。 1 TCP和UDP的共同点 传输层协议&#xff1a; TCP和UDP都是传输层协议&#xff…

联想电脑电池只能充到80%,就不在充电了,猛一看以为坏了,只是设置了养护模式。

现在电池管理模式有三种&#xff1a; 1&#xff09;常规 2&#xff09;养护 3&#xff09;快充 好久没有用联想的电脑了&#xff0c;猛一看&#xff0c;咱充到了80%不充了&#xff0c;难道电池是坏的&#xff1f;我们要如何设置才可以让其充电到100%呢&#xff1f; 右下角…

智慧监狱技术解决方案

1. **建设背景**&#xff1a;介绍了智慧监狱建设的战略部署&#xff0c;包括司法部提出的“数字法治、智慧司法”信息化体系建设&#xff0c;以及智慧监狱建设的总体目标、重点任务和实施步骤。 2. **建设需求**&#xff1a;分析了当前监狱系统存在的问题&#xff0c;如子系统…

后端中缓存的作用以及基于Spring框架演示实现缓存

缓存的作用及演示 现在我们使用的程序都是通过去数据库里拿数据然后展示的 长期对数据库进行数据访问 这样数据库的压力会越来越大 数据库扛不住了 创建了一个新的区域 程序访问去缓存 缓存区数据库 缓存里放数据 有效降低数据访问的压力 我们首先进行一个演示 为了演示…

大模型系列:Prompt提示工程常用技巧和实践

前言 Prompt提示语是使用大模型解决实际问题的最直接的方式&#xff0c;本篇介绍Prompt提示工程常用的技巧&#xff0c;包括Zero-Shot、Few-Shot、CoT思维链、Least-to-Most任务分解。 内容摘要 Prompt提示工程简述Prompt的一般结构介绍零样本提示Zero-Shot少样本提示Few-Sho…

企业化运维(3)_PHP、nginx结合php-fpm、memcache、openresty、goaccess日志可视化

###1.PHP源码编译### 解压PHP压缩包&#xff0c;切入PHP目录&#xff0c;进行configure-->make-->make installd三部曲 [rootserver1 ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel ##依赖性 [rootserver1 ~]# yum…