springboot整合mybatis-puls登陆注册

目录

创建springboot项目

目录结构:

启动类

测试类

idea建表

pom文件

编写yml文件

qq邮箱设置

登陆注册代码

编写持久层(Dao)

注册代码

业务层

业务实现类

mapper

控制层

前端代码

注册页面

邮件正文: 

登录代码

控制层

业务层:

业务实现类:

前端代码

自动登录


创建springboot项目

Maven类型+

Lombok依赖+spring web依赖+MySQL driver依赖+mybatis framework依赖+java Mail Sender依赖

目录结构:
 

有些类是自己写的不用看,看一下结构就可以

启动类

@SpringBootApplication
@MapperScan("com.example.mapper")//将mapper路径下自动注册映射器接口为spring Bean
public class SpringBootDemo1Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemo1Application.class,args);
    }
}

测试类

@SpringBootTest
@RunWith(SpringRunner.class)
class SpringBootTestApplicationTests {

}

idea建表

use `数据库名`;
create table `user`(
    `id` int primary key auto_increment comment '主键id',
    `email` varchar(255) comment '用户邮箱',
    `password` varchar(255) comment '用户密码',
    `salt` varchar(255) comment '盐',
    `confirm_code` varchar(255) comment '确认码',
    `activation_time` datetime comment '激活时间',
    `is_valid` tinyint comment '账号状态'
)default charset=utf8 comment '用户表';

pom文件

<?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>com.example</groupId>
    <artifactId>springBoot-Test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springBoot-Test</name>
    <description>springBoot-Test</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.6.13</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.2.0</version>
            <scope>runtime</scope>
        </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>
        </dependency>
        <!--导入Mybatis坐标-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
        <!--导入mybatis-plus坐标-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.13</version>
        </dependency>
        <!--导入数据库druid坐标-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.22</version>
        </dependency>
        <!--简略get,set方法-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
        <!--模版引擎-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--添加事务管理-->
        <!-- 支持使用 Spring AOP 和 AspectJ 进行切面编程。 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- SpringBoot集成FreeMarker的依赖 :模版引擎,生成输出文本-->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>-->
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--邮箱发送-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <!--工具包:雪花算法:生成确认码-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.25</version>
        </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>com.example.springboottest.SpringBootTestApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

编写yml文件

server:
  port: 8088
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver # 配置数据库驱动程序,用于数据库通信和执行sql语句
      url: jdbc:mysql://localhost:3306/表名?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 # 加数据库名
      username: root
      password: 
  mvc: # 处理springboot与swagger2冲突
    pathmatch:
      matching-strategy: ant_path_matcher
  freemarker:
    expose-session-attributes: true # 暴露session对象的属性
    settings:
      classic_compatible: true # 配置为传统模式,控制自动处理
    suffix: .ftl # 指定模版文件后缀
  mail:
    protocol: smtp # 邮箱协议
    host: smtp.qq.com # qq邮箱,如果用网易将qq改成163
    port: 25
    username:  # 发送人邮件名(这个地方可能出错,可能是由于名字问题)
    password: # 授权码
    default-encoding: utf-8
    properties:
      mail:
        debug: true # 开启debug模式会打印邮件发送过程的日志

mybatis-plus:
  # mybatis映射器XML文件位置 作用:定义sql语句和结果映射
  mapper-location: classpath:mapper/*.xml
  # 开启mybatis-plus的运行日志(建议)
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

qq邮箱设置

点击第二列的账号:开启服务,发送邮件,记下授权码 ok !

登陆注册代码

编写持久层(Dao)

        

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "user") 
public class User {
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    @TableField(value = "email")
    private String email;
    @TableField(value = "password") // 密码,使用md5+盐加密
    private String password;
    @TableField(value = "salt")
    private String salt; // 盐
    @TableField(value = "confirm_code") // 确认码
    private String confirmCode;
    @TableField(value = "activation_time") // 激活失效时间
    private LocalDateTime activationTime;
    @TableField(value = "is_valid") // 账号状态
    private Byte isValid;


}

注册代码

业务层
public interface UserService extends IService<User> {
    // 创建账号
    Map<String,Object> createAccount(User user);
    // 创建账号过程中,用于激活账号的确认码,没有激活不可以登录账号
    Map<String, Object> activation(String confirmCode);
    // 将用户信息录入数据库
    int insertUser(User user);
    // 通过确认码查找用户,不用担心确认码重复
    User selectUserByConfirmCode(String confirmCode);
    // 通过邮箱激活账号
    int updateUserByConfirmCode(String confirmCode);
    // 通过邮箱名查找用户(如果没有进行注册查重,那么将这个修改成List<User>有多个用户报异常)
    User selectUserByEmail(String email);
}
业务实现类
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper um;
    @Value("${spring.mail.username}")
    private String mailUsername; 
    @Resource //发送邮件,实现邮箱验证
    private JavaMailSender javaMailSender; 
    @Resource // 模版引擎
    private TemplateEngine templateEngine;
    @Override
    @Transactional // 事务管理
    /*
     * 创建账号:接收发送过来的邮件账号和密码,利用雪花算法生成确认码用于激活账号,使用MD5将密码进行加密
     * 设置激活时间和激活状态为未激活后添加到数据库,发送邮件领取激活码,激活账号*/
    public Map<String, Object> createAccount(User user) {
        // 检验账号是否重复

        // 雪花算法生成确认码
        String confirmCode = IdUtil.getSnowflake(1,1).nextIdStr();
        // 生成盐 随机数
        String salt = RandomUtil.randomString(6);
        // 加密密码:原始密码+盐
        String md5Pwd = SecureUtil.md5(user.getPassword()+salt);
        // 激活时间 有效时间
        LocalDateTime ldt = LocalDateTime.now().plusDays(1);
        user.setConfirmCode(confirmCode);
        user.setSalt(salt);
        user.setPassword(md5Pwd);
        user.setActivationTime(ldt);
        user.setIsValid((byte)0);
        // 新增账号
        int result = um.insert(user);
        HashMap<String, Object> hm = new HashMap<>();
        if(result > 0){
            // 发送邮件:前端会调用该路径下的方法并传递确认码参数
            String activationUrl = "http://localhost:8088/user/activation?confirmCode=" + confirmCode;
            sendMailForActivationAccount(activationUrl,user.getEmail());
            hm.put("code",200);
            hm.put("message","注册成功。请前往邮件进行账号激活");
        }else {
            hm.put("code",400);
            hm.put("message","注册失败");

        }
        return hm;
    }
    @Override
    @Transactional
    /*发送邮件申请激活账号:创建邮件,设置主题、发送者、接受者、发送日期、创建上下文环境(编写在        
    html)*/
    public void sendMailForActivationAccount(String activationUrl, String email) {
        // 创建邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);
            // 设置邮箱主题
            message.setSubject("抖音账号激活");
            // 设置邮件发送者
            message.setFrom(mailUsername);
            // 设置邮件接受者(可以设置多个)
            message.setTo(email);
            // 设置邮件发送日期
            message.setSentDate(new Date());
            // 创建上下文环境(正文) 用thymeleaf
            Context context = new Context();
            // 将url注入html中,在html中直接用
            // 当在页面点击链接时,会直接执行路径中方法
            context.setVariable("activationUrl",activationUrl);
            String text = templateEngine.process("activation-account.html",context);
            message.setText(text,true);

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        // 发送邮件
        javaMailSender.send(mimeMessage);
    }
    @Override
    /*在注册阶段会调用该方法实现账号激活:根据注册阶段传递过来的确认码查询用户,调取用户信息
    判断是否是有效激活时间,返回结果*/
    public Map<String, Object> activation(String confirmCode) {
        Map<String, Object> hm = new HashMap<>();
        // 根据确认码查询用户
        User user = um.selectUserByConfirmCode(confirmCode);
        // 判断激活时间是否失效:现在时间是在激活时间之后吗
        boolean after = LocalDateTime.now().isAfter(user.getActivationTime());
        if(after){
            hm.put("code",400);
            hm.put("message","激活失效,请重启注册");
            return hm;
        }
        // 修改状态值
        int result = um.updateUserByConfirmCode(confirmCode);
        if(result > 0){
            hm.put("code",200);
            hm.put("message","激活成功");
            return hm;
        }else {
            hm.put("code",400);
            hm.put("message","激活失效,请联系管理员");
            return hm;
        }

    }
    
    @Override
    public int insertUser(User user) {
        return um.insert(user);
    }
    @Override
    public User selectUserByConfirmCode(String confirmCode) {
        return um.selectUserByConfirmCode(confirmCode);
    }
    @Override
    public int updateUserByConfirmCode(String confirmCode) {
        return um.updateUserByConfirmCode(confirmCode);
    }
    
    @Override
    public User selectUserByEmail(String email) {
        return um.selectUserByEmail(email);
    }
    
}
mapper
public interface UserMapper extends BaseMapper<User> {
    /*
    * 根据确认码查询用户*/
    @Select("SELECT email,activation_time FROM user WHERE confirm_code = #{confirmCode} AND is_valid = 0")
    User selectUserByConfirmCode(@Param("confirmCode") String confirmCode);
    /*
    * 根据确认码查询用户并修改状态码为1*/
    @Update("UPDATE user SET is_valid = 1 WHERE confirm_code = #{confirmCode}")
    int updateUserByConfirmCode(@Param("confirmCode") String confirmCode);
    /*
    * 根据邮箱查询用户*/
    @Select("SELECT * FROM user WHERE email = #{email} AND is_valid = 1")
    User selectUserByEmail(@Param("email") String email);


}
控制层
@Api("用户界面")
@RestController
@RequestMapping("user")
public class UserController {
    @Resource
    private UserService us;

    @ApiOperation(value = "注册账号")
    @PostMapping("create")
    public Map<String,Object> createAccount(@RequestBody User user){
        return us.createAccount(user);
    }
    @ApiOperation(value = "激活账号")
    @GetMapping("activation")
    /*通过邮件激活相当于网页传递数据。因为路径中追加了confirmCode所以会自动传参*/
    public Map<String,Object> activation(String confirmCode){
        return us.activation(confirmCode);
    }

}
前端代码

因为用的是thymeleaf写的所以目录结构如下(记得写在templates中)

注册页面
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 引入 jQuery -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <style>
    body {
      background: url('https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.jpg') no-repeat;
      background-size: 100% 130%;
    }

    #login_box {
      width: 20%;
      height: 400px;
      background-color: #00000060;
      margin: auto;
      margin-top: 10%;
      text-align: center;
      border-radius: 10px;
      padding: 50px 50px;
    }

    h2 {
      color: #ffffff90;
      margin-top: 5%;
    }

    #input-box {
      margin-top: 5%;
    }

    span {
      color: #fff;
    }

    input {
      border: 0;
      width: 60%;
      font-size: 15px;
      color: #fff;
      background: transparent;
      border-bottom: 2px solid #fff;
      padding: 5px 10px;
      outline: none;
      margin-top: 10px;
    }

    button {
      margin-top: 50px;
      width: 60%;
      height: 30px;
      border-radius: 10px;
      border: 0;
      color: #fff;
      text-align: center;
      line-height: 30px;
      font-size: 15px;
      background-image: linear-gradient(to right, #30cfd0, #330867);
    }

    #sign_up {
      margin-top: 45%;
      margin-left: 60%;
    }

    a {
      color: #b94648;
    }
  </style>
</head>

<body>
<div id="login_box">
  <h2>REGISTRY</h2>
  <div id="input_box">
    <input type="text" id = "email" name="email" placeholder="请输入用户名">
  </div>
  <div class="input_box">
    <input type="password" id = "password" name="password" placeholder="请输入密码">
  </div>

  <button id = "registry">注册</button><br><br>

    <p>Come to us ? <a href="login">Login</a></p>

</div>
/*当id:registry发生点击行为thymeleaf会接受相应过来的数据并转换成json格式,然后调用url路径下的方法创建账号
  * result接收控制层返回的数据(Map)在网页提示创建成功或创建失败*/
<script type="text/javascript" charset="UTF-8">
  $("#registry").on("click",function (){
    $.ajax({
      url:"/user/create",
      type: "POST",
      contentType: "application/json",
      data: JSON.stringify({ 
        email: $("#email").val(),
        password: $("#password").val()
      }),
      dataType: "json",
      success: function(result){
        alert(result.message);
      },
      error: function(result){
        alert("发生错误");
      }
    });
  });
</script>
</body>
</html>
邮件正文: 
<html>
<body>
<!--根据自己需要编写,-->
<div>
    <p>Email 地址验证</p> <!--target:新的窗口打开超链接-->
    <p>这封信是由<a href="https://www.douyin.com" target = "_blank">抖音</a>发送的</p>
    <p>
        由于你在抖音进行了新用户注册或用户修改,如果你没有进行过此操作,请忽略这封邮件。如果你是新用户或者修改你的账号
        请点击下方链接:
    </p>
    <p>
        <a th:href="@{${activationUrl}}"><span th:text="${activationUrl}"></span></a>
        感谢你的访问,祝你生活愉快。
    </p>

</div>
</body>
</html>

登录代码

控制层

登录界面:http://localhost:8088/gameLogin/login

@Api(value = "登录页面")
@Controller
@RequestMapping("gameLogin")
public class LoginController {
    @Resource
    private UserService us;
    @GetMapping("login") 
    public String login(){
        return "login";
    }
    @GetMapping("registry")
    public String registry(){
        return "registry";
    }
    @PostMapping("loginAccount")
    @ResponseBody
    public Map<String,Object> loginAccount(@RequestBody User user){
        return us.loginAccount(user);
    }
}
业务层:
public interface UserService extends IService<User> {
    Map<String,Object> loginAccount(User user);
}
业务实现类:
@Override
    /*
     * 登录账号*/
    public Map<String, Object> loginAccount(User user) {
        Map<String, Object> hm = new HashMap<>();
        User user1 = um.selectUserByEmail(user.getEmail());
        // 如果账号不存在或未激活
        if(user1 == null || user1.getIsValid() == (byte)0){
            hm.put("code",400);
            hm.put("message","该账户不存在或未激活");
            return hm;
        }
        // 进行密码比对
        String md5Pwd = SecureUtil.md5(user.getPassword()+user1.getSalt());
        if(!md5Pwd.equals(user1.getPassword())){
            hm.put("code",400);
            hm.put("message","用户名或密码错误");
            return hm;
        }
        hm.put("code",200);
        hm.put("message","登陆成功");
        return hm;
    }
前端代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 引入 jQuery -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <style>
    body {
      background: url('https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.jpg') no-repeat;
      background-size: 100% 130%;
    }

    #login_box {
      width: 20%;
      height: 400px;
      background-color: #00000060;
      margin: auto;
      margin-top: 10%;
      text-align: center;
      border-radius: 10px;
      padding: 50px 50px;
    }

    h2 {
      color: #ffffff90;
      margin-top: 5%;
    }

    #input-box {
      margin-top: 5%;
    }

    span {
      color: #fff;
    }

    input {
      border: 0;
      width: 60%;
      font-size: 15px;
      color: #fff;
      background: transparent;
      border-bottom: 2px solid #fff;
      padding: 5px 10px;
      outline: none;
      margin-top: 10px;
    }

    button {
      margin-top: 50px;
      width: 60%;
      height: 30px;
      border-radius: 10px;
      border: 0;
      color: #fff;
      text-align: center;
      line-height: 30px;
      font-size: 15px;
      background-image: linear-gradient(to right, #30cfd0, #330867);
    }

    #sign_up {
      margin-top: 45%;
      margin-left: 60%;
    }

    a {
      color: #b94648;
    }
  </style>
</head>

<body>
<div id="login_box">
  <h2>LOGIN</h2>
  <div id="input_box">
    <input type="text" id="email" name="email" placeholder="请输入用户名">
  </div>
  <div class="input_box">
    <input type="password" id="password" name="password" placeholder="请输入密码">
  </div>

  <button id = "login">登录</button><br><br>

    <p>New to us ? <a href="registry">Registry</a></p>
</div>
<script type="text/javascript" charset="UTF-8">
  $("#login").on("click",function (){
    $.ajax({
      url:"/gameLogin/loginAccount",
      type: "POST",
      contentType: "application/json",
      data: JSON.stringify({ // 将对象转化为json格式
        email: $("#email").val(),
        password: $("#password").val()
      }),
      dataType: "json",
      success: function(result){
        alert(result.message);
        if(200 == result.code) {
          window.location.href = "https://www.douyin.com"
        }
      },
      error: function(result){
        alert("发生错误");
      }
    });
  });
</script>
</body>
</html>

自动登录

package com.example.utils;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringBootConfiguration;

@SpringBootConfiguration
public class AutoStartLogin implements CommandLineRunner {
    @Override
    public void run(String ... args) {
        try {
            Runtime.getRuntime().exec("cmd /c start http://localhost:8088/gameLogin/login");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

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

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

相关文章

Excel 公式的定义、语法和应用(LOOKUP 函数、HLOOKUP 函数、VLOOKUP 函数;MODE.MULT 函数; ROUND 函数)

一、公式的定义和语法 二、公式的应用 附录 查找Excel公式使用方法的官方工具【强烈推荐&#xff01;&#xff01;&#xff01;】&#xff1a;Excel 函数&#xff08;按字母顺序&#xff09;【微软官网】 excel 函数说明语法LOOKUP 函数在向量或数组中查找值LOOKUP(lookup_va…

Django模型的继承

Django模型的继承 Django模型的继承&#xff0c;包括模型的抽象基类、Meta继承、related_name和related_query_name属性、多表继承、Meta和多表继承、继承与反向关系、代理模型、代理模型继承和未托管模型&#xff0c;以及多重继承等内容。本文讲解一下抽象基类继承&#xff0…

轻松复现一张AI图片

轻松复现一张AI图片 现在有一个非常漂亮的AI图片&#xff0c;你是不是想知道他是怎么生成的&#xff1f; 今天我会交给大家三种方法&#xff0c;学会了&#xff0c;什么图都可以手到擒来了。 需要的软件 在本教程中&#xff0c;我们将使用AUTOMATIC1111 stable diffusion W…

按照模板导出复杂样式的excel

导出excel通常使用的是apache poi,但是poi的api相当复杂&#xff0c;所以当导出的excel样式比较复杂时&#xff0c;写起来就比较头疼了&#xff0c;这里推荐使用easypoi, 可以很方便的根据模板来导出复杂excel 文档地址: 1.1 介绍 - Powered by MinDoc 我们要实现如图所示效果…

【报错】ModuleNotFoundError: No module named ‘einops‘

1 报错 💔💔💔 ModuleNotFoundError: No module named einops 解决方法 💚 💚 💚 pip --default-timeout=100 install einops -i https://pypi.tuna.tsinghua.edu.cn/simple 问题解决啦!!!🌺🌺🌺 2 报错 💔💔💔 ModuleNotFoundError: No module

基于postCSS手写postcss-px-to-vewiport插件实现移动端适配

&#x1f31f;前言 目前前端实现移动端适配方案千千万&#xff0c;眼花缭乱各有有缺&#xff0c;但目前来说postcss-px-to-vewiport是一种非常合适的实现方案&#xff0c;postcss-px-to-vewiport是一个基于postCss开发的插件&#xff0c;其原理就是将项目中的px单位转换为vw(视…

HTML5+JavaScript实现语音合成(文字转语音)

HTML5JavaScript实现语音合成&#xff08;文字转语音&#xff09; 本文介绍用HTML5和JavaScript实现语音合成朗读&#xff08;文字转语音&#xff09;。 Web Speech API 有两个部分&#xff1a;SpeechSynthesis 语音合成&#xff08;文本到语音 TTS&#xff09;和 SpeechReco…

汽车研发项目进度管理的挑战与优化策略

随着汽车行业的快速发展和市场竞争的加剧&#xff0c;新车型研发项目的进度管理成为车企赢得市场的关键。然而&#xff0c;由于汽车研发项目通常具有投资大、周期长、技术难度高、参与方众多等特点&#xff0c;项目进度管理面临着诸多挑战。为了提升车型研发效率、缩短研发周期…

SQL的基础语句

1、select语句 select colums from table_name 2、条件语句 #查询出查询出用户id为1和3的用户记录 IN 操作符允许我们在 WHERE 子句中规定多个值。 select * from student where id in (1,3) #查询出所有姓王的同学 模糊查询 like 通配符(% 任意多个字符 _单个字符) #下例…

使用Docker搭建本地Nexus私有仓库

0-1开始Java语言编程之路 一、Ubuntu下Java语言环境搭建 二、Ubuntu下Docker环境安装 三、使用Docker搭建本地Nexus Maven私有仓库 四、Ubuntu下使用VisualStudioCode进行Java开发 你需要Nexus Java应用编译构建的一种主流方式就是通过Maven, Maven可以很方便的管理Java应用的…

病理验证mIF和TMA路线(自学)

目录 技术 使用配对病理切片 mIF验证 单基因使用TMA验证 技术 多重荧光免疫组化技术 (Multiplex immunohistochemical&#xff0c;mIHC) 也称作酪氨酸信号放大 (Tyramide dignal amplification&#xff0c;TSA) 技术&#xff0c;是一类利用辣根过氧化酶 (Horseradish Pero…

【数据结构(邓俊辉)学习笔记】向量01——接口与实现

文章目录 0.意图1、概述2 从数组到向量3 向量ADT接口4 Vector 模板类5 构造与析构5.1默认构造方法5.2基于复制的构造方法5.3 析构方法 0.意图 一方面是将工作学习中零星的知识点串起来&#xff0c;另一方面向量是其他数据类型的基础&#xff0c;比如栈队列等&#xff0c;所以基…

算法练习|Leetcode49字母异位词分词 ,Leetcode128最长连续序列,Leetcode3无重复字符的最长子串,sql总结

目录 一、Leetcode49字母异位词分词题目描述解题思路方法:哈希总结 二、Leetcode128最长连续序列题目描述解题思路方法:总结 三、Leetcode3无重复字符的最长子串题目描述解题思路方法:双指针法总结sql总结 一、Leetcode49字母异位词分词 题目描述 给你一个字符串数组&#xf…

linux下 Mysql8.0 离线安装

环境&#xff1a;centos7.9 MysqlL8.0.36安装包 链接&#xff1a;https://pan.baidu.com/s/1bKwHr05z8Ye82dT9tntdUA 提取码&#xff1a;3a5z 参考Centos安装MYSQL8(离线可用) 文章目录 1、解压安装2、配置启动2.1 修改配置文件2.2 mysql 启动 3、mysql 测试 1、解压安装 #…

kettle数据迁移从oracle到mysql

kettle数据迁移从oracle到mysql 下载方式1&#xff1a;方式2&#xff1a;方式3&#xff1a;下载后解压就行 二、启动三、连接数据库1.前期2.oracle数据库3.mysql数据库 四、迁移一、配置表输入参数1.在【转换】里面&#xff0c;选择【核心对象】&#xff0c;选中将【表输入】拖…

springboot 批量下载文件, zip压缩下载

一、使用hutool 工具类 效果&#xff1a;下载速度可以 1、依赖&#xff1a;hutool <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version> </dependency>2、调用方式 im…

Rust 使用结构体组织相关联的数据

目录 结构体的定义和实例化 使用字段初始化简写语法使用结构体更新语法从其他实例创建实例使用没有命名字段的元组结构体来创建不同的类型没有任何字段的类单元结构体结构体示例程序 通过派生 trait 增加实用功能方法语法 定义方法带有更多参数的方法关联函数多个 impl 块本文有…

向量的点积和叉积的几何意义

1. 点积 点积(dot product)&#xff0c;又称标量积&#xff08;scalar product&#xff09;。结果等于。 可用于 判断的是否垂直求投影长度求向量是抑制作用还是促进作用 2. 叉积 叉积(cross product)&#xff0c;又称为向量积(vector product)。模长等于&#xff0c;方向…

简单学量化——pandas的应用26——sort_values函数5

简单学量化——pandas的应用26——sort_values函数5 sort_values是pandas中的排序函数&#xff0c;语法如下&#xff1a; DataFrame.sort_values(by,axis0,ascendingTrue,inplaceFalse,kindquicksort,na_positionlast, ignore_indexFalse,keyNone) 前面我们学习了by、axis、a…

嵌入式linux中uboot的启动过程分析

之前对这个uboot的源码了解有些许遗忘。最近做AVB校验,需要uboot到kernel的这个过程。这里再复习一下。 与大多数BootLoader一样,uboot的启动过程分为BL1和BL2两个阶段。 BL1阶段通常是开发板的配置等设备初始化代码,需要依赖依赖于SoC体系结构,通常用汇编语言来实现; …