SpringBoot学习笔记

SpringBoot学习笔记

一、YAML基础语法

1、配置文件

SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的

  • application.properties

    • 语法结构 :key=value
  • application.yml

    • 语法结构 :key:空格 value
2、基本语法

说明:语法要求严格!

1、k:(空格)v:表示一对键值对(空格必须有);

2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。

3、属性和值的大小写都是十分敏感的。

字面量:普通的值 [ 数字,布尔值,字符串 ]

字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;

k: v

注意:

  • “ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;

    比如 :name: “kuang \n shen” 输出 :kuang 换行 shen

  • ‘’ 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出

    比如 :name: ‘kuang \n shen’ 输出 :kuang \n shen

对象、Map(键值对

#对象、Map格式
k: 
    v1:
    v2:

在下一行来写对象的属性和值得关系,注意缩进;比如:

student:
    name: qinjiang
    age: 3
#内行写法
student: {name: qinjiang,age: 3}

数组( List、set )

用 - 值表示数组中的一个元素,比如

pets:
 - cat
 - dog
 - pig
#内行写法
pets: [cat,dog,pig]

修改SpringBoot的默认端口号

配置文件中添加,端口号的参数,就可以切换端口;

server:
  port: 8082
3、@Value获取值和@ConfigurationProperties获取值比较
@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持
4、YML支持多文档格式
server:
  port: 8081
spring:
  profiles:
    active: prod

---
server:
  port: 8083
spring:
  profiles: dev


---

server:
  port: 8084
spring:
  profiles: prod  #指定属于哪个环境

二、Wed开发

1、简介

使用SpringBoot:

1)、创建SpringBoot应用,选中我们需要的模块;

2)、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来

3)、自己编写业务代码;

2、springboot静态资源映射规则

1)、"/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射

"classpath:/META-INF/resources/", 
"classpath:/resources/",
"classpath:/static/", 
"classpath:/public/" 
"/":当前项目的根路径

localhost:8080/abc === 去静态资源文件夹里面找abc

2)、欢迎页; 静态资源文件夹下的所有index.html页面;被"/**"映射;

localhost:8080/ 找index页面

3)、所有的**/favicon.ico 都是在静态资源文件下找;

3、Thymeleaf模板引擎

1)环境配置

只要导入一个包就可以了,即在pom.xml中添加以下依赖

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>
2)语法

首先看下对应关系。

在这里插入图片描述

我们需要在项目的resources目录下的templates文件夹下面创建一个叫index.html的文件,controller层中指定Thymeleaf页面的url,然后再Model中绑定数据。

package com.Thymeleaf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class urlController {
    @GetMapping("/index")//页面的url地址
    public String getindex(Model model)//对应函数
    {
        model.addAttribute("name","bigsai");
        return "index";//与templates中index.html对应
    }
}

上述代码就是一个完整的controller。部分含义如下:

  • @controller 注解的意思就是声明这个Java文件为一个controller控制器。
  • @GetMapping(“index”) 其中@GetMapping的意思是请求的方式为get方式(即可通过浏览器直接请求),而里面的index表示这个页面(接口)的url地址(路径)。即在浏览器对项目网页访问的地址。
  • getindex() 是@GetMapping(“index”)注解对应的函数,其类型为String类型返回一个字符串,参数Model类型即用来储存数据供我们Thymeleaf页面使用。
  • model.addAttribute(“name”,“bigsai”) 就是Model存入数据的书写方式,Model是一个特殊的类,相当于维护一个Map一样,而Model中的数据通过controller层的关联绑定在view层(即Thymeleaf中)可以直接使用。
  • return “index”:这个index就是在templates目录下对应的index.html,与页面关联默认规则为:templates目录下返回字符串.html。

注意在这个html文件中的<html>标签修改为<html xmlns:th="http://www.thymeleaf.org">这样才能Thymeleaf中就可以使用Thymeleaf的语法和规范。

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">  <!--这里-->
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>
这是一个Thymeleaf程序
<div th:text="${name}">name是bigsai</div>
</body>
</html>
3)常用标签

要知道Thymeleaf是通过特殊的标签来寻找属于Thymeleaf的部分,并渲染该部分内容,而除了上面展示过的th:text之外还有很多常用标签,并且Thymeleaf也主要通过标签来识别替换对应位置内容,Thymeleaf标签有很多很多,功能也很丰富,这里列举一些比较常用的标签如下:

标签作业实例
th:id替换id< input th:id="${user.id}"/>
th:text文本替换< p text:="${user.name}">
th:utext支持html的文本替换< p utext:="${htmlcontent}">
th:object替换对象< div th:object="${user}" >< /div>
th:value替换值< input th:value="${user.name}" >
th:each迭代< tr th:each=“student:${user}” >
th:href替换超链接< a th:href="@{index.html}">
th:src替换资源< script type=“text/javascript” th:src="@{index.js}">
4)链接表达式: @{…}

在Thymeleaf 中,如果想引入链接比如link,href,src,需要使用@{资源地址}引入资源。其中资源地址可以static目录下的静态资源,也可以是互联网中的绝对资源。

引入css

 <link rel="stylesheet" th:href="@{index.css}">

引入JavaScript:

 <script type="text/javascript" th:src="@{index.js}"></script>

超链接:

<a th:href="@{index.html}">超链接</a>

这样启动程序访问页面,页面的内容就自动修改成标准html语法格式的内容:
在这里插入图片描述

5)变量表达式: ${…}

在Thymeleaf中可以通过${…}进行取值。

取普通字符串:
如果在controller中的Model直接存储某字符串,我们可以直接${对象名}进行取值。代码如下:

<h2>普通字符串</h2>
<table border="0">
    <tr>
        <td th:text="'我的名字是:'+${name}"></td>
    </tr>
</table>

取JavaBean对象:

取JavaBean对象也很容易,因为JavaBean自身有一些其他属性,所以咱们就可以使用 对 象 名 . 对 象 属 性 或 者 {对象名.对象属性}或者 .{对象名[‘对象属性’]}来取值,这和JavaScript语法是不是很相似呢!除此之外,如果该JavaBean如果写了get方法,咱们也可以通过get方法取值例如${对象.get方法名},代码如下:

<h2>JavaBean对象</h2>
<table bgcolor="#ffe4c4" border="1">
    <tr>
        <td>介绍</td>
        <td th:text="${user.name}"></td><!--替换为user.name相应的值-->
    </tr>
    <tr>
        <td>年龄</td>
        <td th:text="${user['age']}"></td>
    </tr>
    <tr>
        <td>介绍</td>
        <td th:text="${user.getDetail()}"></td>
    </tr>
</table>

取List集合(each):

因为List集合是个有序列表,里面内容可能不止一个,你需要遍历List对其中对象取值,

而遍历需要用到标签:th:each,具体使用为 < tr th:each=“item:${userlist}”>,其中item就相当于遍历每一次的对象名,在下面的作用域可以直接使用,而userlist就是你在Model中储存的List的名称。的代码为:

userList.add("zhang san 66");
userList.add("li si 66");
userList.add("wang wu 66")
    
    model.addAttribute("userlist",userList);//储存List
<h2>List取值</h2>
<table bgcolor="#ffe4c4" border="1">
    <tr th:each="item:${userlist}"><!--遍历userlist中的值-->
        <td th:text="${item}"></td>
    </tr>
</table>

图

6) 消息表达: #{…}

通俗易懂的来说#{…}语法就是用来读取配置文件中数据的。在Thymeleaf你可以使用#{...}语法获取消息,具体实例代码如下:

bigsai.nane=bigsai
bigsai.age=22
province=Jiang Su
<h2>消息表达</h2>
<table bgcolor="#ffe4c4" border="1">
    <tr>
    <td>name</td>
    <td th:text="#{bigsai.name}"></td>
    </tr>
    <tr>
    <td>年龄</td>
    <td th:text="#{bigsai.age}"></td>
    </tr>
    <tr>
    <td>province</td>
    <td th:text="#{province}"></td>
    </tr>
</table>

结果

图片

7)片段引用表达式: ~{…}
1、抽取公共片段
<div th:fragment="copy">
&copy; 2011 The Good Thymes Virtual Grocery
</div>

2、引入公共片段
<div th:insert="~{footer :: copy}"></div>
~{templatename::selector}:模板名::选择器
~{templatename::fragmentname}:模板名::片段名

3、默认效果:
insert的公共片段在div标签中
如果使用th:insert等属性进行引入,可以不用写~{}:
行内写法可以加上:[[~{}]];[(~{})];

三种引入公共片段的th属性:

th:insert:将公共片段整个插入到声明引入的元素中

th:replace:将声明引入的元素替换为公共片段

th:include:将被引入的片段的内容包含进这个标签中

<footer th:fragment="copy">
&copy; 2011 The Good Thymes Virtual Grocery
</footer>

引入方式
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>

效果
<div>
    <footer>
    &copy; 2011 The Good Thymes Virtual Grocery
    </footer>
</div>

<footer>
&copy; 2011 The Good Thymes Virtual Grocery
</footer>

<div>
&copy; 2011 The Good Thymes Virtual Grocery
</div>

引入片段的时候传入参数:

<nav class="col-md-2 d-none d-md-block bg-light sidebar" id="sidebar">
    <div class="sidebar-sticky">
        <ul class="nav flex-column">
            <li class="nav-item">
                <a class="nav-link active"
                   th:class="${activeUri=='main.html'?'nav-link active':'nav-link'}"
                   href="#" th:href="@{/main.html}">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home">
                        <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
                        <polyline points="9 22 9 12 15 12 15 22"></polyline>
                    </svg>
                    Dashboard <span class="sr-only">(current)</span>
                </a>
            </li>

<!--引入侧边栏;传入参数-->
<div th:replace="commons/bar::#sidebar(activeUri='emps')"></div>

三、SpringBoot与数据访问

1、JDBC
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.15.22:3306/jdbc
    driver-class-name: com.mysql.jdbc.Driver

效果:

默认是用org.apache.tomcat.jdbc.pool.DataSource作为数据源;

数据源的相关配置都在DataSourceProperties里面;

2、整合Druid数据源
导入druid数据源
@Configuration
public class DruidConfig {

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
       return  new DruidDataSource();
    }

    //配置Druid的监控
    //1、配置一个管理后台的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();

        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
        initParams.put("allow","");//默认就是允许所有访问
        initParams.put("deny","192.168.15.21");

        bean.setInitParameters(initParams);
        return bean;
    }


    //2、配置一个web监控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");

        bean.setInitParameters(initParams);

        bean.setUrlPatterns(Arrays.asList("/*"));

        return  bean;
    }
}

3、整合MyBatis
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.1</version>
		</dependency>

spring:
  thymeleaf:
    cache: false
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useUnicode=trun&characterEncoding=utf8&useSSl=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
    username: root
    password: 123456


mybatis:
  mapper-locations: classpath:mapper/*.xml 
  type-aliases-package: com.example.demo1.pojo
  configuration:
    map-underscore-to-camel-case: true

1)、配置数据源相关属性

2)、给数据库建表

3)、创建JavaBean

4)、注解版

//指定这是一个操作数据库的mapper
@Mapper
public interface DepartmentMapper {

    @Select("select * from department where id=#{id}")
    public Department getDeptById(Integer id);

    @Delete("delete from department where id=#{id}")
    public int deleteDeptById(Integer id);

    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into department(departmentName) values(#{departmentName})")
    public int insertDept(Department department);

    @Update("update department set departmentName=#{departmentName} where id=#{id}")
    public int updateDept(Department department);
}

四、过程笔记

1、springboot的entity,dao,controller,service层的理解。

1) Entity层:

实体层,数据库在项目中的类
主要用于定义与数据库对象的属性,提供get/set方法,带参和无参的构造方法。

2 )Dao层:

持久层,主要是和数据库进行交互
dao层首先胡创建dao接口,接着就可以在配置文件中定义该接口的实现类;接着就可以在模块中调用dao的接口进行数据业务的处理,而不用关注此接口的具体实现是哪一个类,dao层的数据源和数据库实在配置文件中进行配置的。

3 )Service层:

业务层控制业务

业务模块的逻辑应用设计,和DAO层一样都是先设计接口,再创建要实现的类,然后在配置文件中进行配置其实现的关联。接下来就可以在service层调用接口进行业务逻辑应用的处理。

好处:封装Service层的业务逻辑有利于业务逻辑的独立性和重复利用性。

4)Controller层:

控制层 控制业务逻辑
具体的业务模块流程的控制,controller层主要调用Service层里面的接口控制具体的业务流程,控制的配置也要在配置文件中进行。

5)Controller和Service的区别是:

Controller负责具体的业务模块流程的控制;Service层负责业务模块的逻辑应用设计
总结:具体的一个项目中有:controller层调用了Service层的方法,Service层调用Dao层的方法,其中调用的参数是使用Entity层进行传递的。

2、常用注解

相关注解说明
@SpringBootConfiguration与@Configuration作用相同,都是用来声明当前类是一个配置类,这里表明是springboot主类使用的配置类
@EnableAutoConfiguration是springboot实现自动化配置的核心注解,通过这个注解把spring应用所需的bean注入容器中
@ComponentScan用来自动扫描被这些注解标识的类,最终生成ioc容器里的bean,默认扫描范围是@ComponentScan注解所在配置类包及子包的类
@Repository持久层(dao)注入spring容器
@Service业务逻辑层(server)注入spring容器
@Controller控制层(controller)注入spring容器
@Component普通pojo注入spring容器
@ResponseBody@ResponseBody的作用其实是将java对象转为json格式的数据。
@RestController作用等于在类上面添加了@ResponseBody和@Controller
@AutoWired@Autowired默认按类型装配,如果发现找到多个bean,则按照name方式比对,如果还有多个,则报出异常
@Qualifierspring的注解,按名字注入 一般当出现两个及以上bean时,不知道要注入哪个,结合@AutoWired使用
@Resource默认按名称注入例如@Resource(name = “zhaozhao”)则根据name属性注入找不到则报错,若无name属性则根据属性名称注入,如果匹配不成功则按照类型匹配匹配不成功则报错。
@RequestMapping@RequestMapping(url),通过该注解就可以通过配置的url进行访问,方式可以是get或post请求,两种方式均可
@GetMapping@GetMapping(url) ,功能类似的,只是这个限定了只能是Get请求
@PostMapping@PostMapping(url),功能类似的,只是这个限定了只能是Post请求
@Value用于获取bean的属性,一般用于读取配置文件的数据,作用在变量上
@ConfigurationProperties用于注入Bean属性,然后再通过当前Bean获取注入值,作用在类上
@PropertySource用于指定要读取的配置文件,可以和@Value或@ConfigurationProperties配合使用
@Configuration作用于类上表示这是一个配置类,可理解为用spring的时候xml里面的< beans>标签
@Bean产生bean对象加入容器,作用于方法,可理解为用spring的时候xml里面的标签
@RequestParam获取查询参数。即url?name=这种形式
@PathVariable获取路径参数。即url/{id}这种形式。
@RequestParam获取Body的参数,一般用于post获取参数
@RequestHeader获取请求头的信息
@CookieValue获取Cookie的信息

3、常用依赖

                    《  MySQL依赖  》
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

                    《   Druid依赖   》
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>


                   《--mybatis依赖--》
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>


                     《--Web依赖--》
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>


                      《  webiars依赖   》
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.6.0</version>
</dependency>


                       《  thymeleaf依赖  》
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

 
                    《   lombok依赖    》
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
</dependency>

                      《   junit依赖    》
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <scope>test</scope>
</dependency>



五、实际操作效果截图

SpringBoot+MyBatis+Thymeleaf

1、登录页面

在这里插入图片描述

2、注册页面

在这里插入图片描述

3、员工管理页面
在这里插入图片描述

六、部分代码

1、controller控制层

package com.example.demo1.controller;

import com.example.demo1.mapper.UserMapper;
import com.example.demo1.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.Collection;
@Controller
public class UserController {
    @Autowired
    UserMapper userMapper;
    @GetMapping("/emps")//视图映射,跳转到全体员工页面
    public String list(Model model){
        Collection<User> users = userMapper.getAll();
        model.addAttribute("emps",users);
        return "emp/list";
    }


    @GetMapping("/emp")//接收来自员工管理页面请求
    public String ToAdd(){
        return "emp/add";//跳转到员工添加页面
    }

    @PostMapping("/emp")//接收添加完成的成员信息
    public String jiaUser(User user){
   userMapper.jiaUser(user);
        return "redirect:/emps";
    }
    @GetMapping("/emp/{id}")//接收删除请求
    public  String chuUse(@PathVariable("id") long id , Model model){
        userMapper.shanUser(id);
     return "redirect:/emps";//更新成删除成功之后的界面
    }
    @GetMapping("/cha/{id}")//接收来自员工管理界面的修改请求
    public String GaiUser(@PathVariable("id") long id,Model model){
        User emp = userMapper.chaUser(id);
        model.addAttribute("emp",emp);
        return "emp/gai";//跳转到修改员工信息界面
    }
    @PostMapping("/xiu")//接收修改完成的信息
    public String GaiUser(User user) {
        userMapper.gaiUser(user);
        return "redirect:/emps";//返回员工管理界面
    }
}

package com.example.demo1.controller;

import com.example.demo1.mapper.UserMapper;
import com.example.demo1.pojo.User;
import com.example.demo1.utils.ValidateImageCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Controller
public class HelloworldController      //Alt+Enter可查看红色警告解决方法
{
    @RequestMapping({"/index"})
    public String hello(){
        return "index";
    }

    @RequestMapping({"/main"})
    public String hell(){
        return "dashboard";
    }

    @RequestMapping({"/user/list"})
    public String hel(){
        return "list";
    }
    @GetMapping("/toRegister")
    public String toRgsiter() {
        return "emp/regist";
    }
    //这就是视图映射

    @Autowired
    UserMapper userMapper;

    @RequestMapping("/user/login")//点击登录跳转的页面
    public String dash(
                        @RequestParam("username") String username,
                        //@RequestParam(A)B。可将HTML中name=“A“输入的值赋值给B

                        @RequestParam("password") String password,
                        Model model, HttpSession session) {
        User info = userMapper.getInfo(username, password);

        if (info!=null)
        {
            //StringUtils.isEmpty(A),为空则返回1;   "A".equals(B)与A==B类似

            session.setAttribute("loginUser",username);//保存loginUser的值,能在跳转之后的页面显现

            return "redirect:/main";//redirect可用于重定向

        }else
        {
            model.addAttribute("msg","用户名密码错误");//msg的值只能在返回的那页面才有效
            return "index";
        }

    }
    // 注册方法
    @PostMapping("/register")
    public String register(User user, String code, HttpSession session,Model model) {
        String sessionCode = (String) session.getAttribute("code");
        if (sessionCode.equalsIgnoreCase(code)) { // 忽略大小写比较验证码
            userMapper.jiaUser(user);//验证码正确就添加成员
            model.addAttribute("msg","恭喜注册成功");
            return "index"; // 跳转到登陆界面
        } else {
            return "redirect:/toRegister";
        }
    }

    // 生成验证码
    @GetMapping("/code")//这为验证码生成的图片地址
    public void getImage(HttpSession session, HttpServletResponse response) throws IOException {
        // 生成验证码
        String securityCode = ValidateImageCodeUtils.getSecurityCode();
        BufferedImage image = ValidateImageCodeUtils.createImage(securityCode);
        // 存入session作用域中
        session.setAttribute("code", securityCode);
        // 响应图片
        ServletOutputStream os = response.getOutputStream();
        ImageIO.write(image, "png", os);
    }
}

2、mapper接口层

ackage com.example.demo1.mapper;

import com.example.demo1.pojo.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.Collection;
import java.util.List;

@Mapper

public interface UserMapper {


    User getInfo(String name,String password);

    Collection<User> getAll();
    void jiaUser(User user);
    void shanUser(long id);
    void gaiUser(User user);
    User chaUser(long id);

    List<String> allId();
}

UserMapper.xml

<?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.demo1.mapper.UserMapper">

    <select id="getInfo" resultType="User" parameterType="String">
        select * from user where name = #{name } and password = #{password}
    </select>

    <select id="getAll" resultType="com.example.demo1.pojo.User">
        select * from user
    </select>
    <select id="allId" resultType="String">
        select name from user
    </select>
    <insert id="jiaUser"  parameterType="User">
        insert into user (name ,password,gender,bumen) values ( #{name},#{password},#{gender},#{bumen})
    </insert>
    <delete id="shanUser" parameterType="long">
        delete from user where id=#{id}
    </delete>
    <update id="gaiUser" parameterType="User">
        update user set name =#{name},password=#{password},gender=#{gender},bumen=#{bumen} where id=#{id}
    </update>
    <select id="chaUser" parameterType="long" resultType="User">
        select * from user where id=#{id}
    </select>

</mapper>

3、生成验证码代码

package com.example.demo1.utils;


import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;

public class ValidateImageCodeUtils {
    /**
     * 验证码难度级别 Simple-数字 Medium-数字和小写字母 Hard-数字和大小写字母
     */
    public enum SecurityCodeLevel {
        Simple, Medium, Hard
    };
    /**
     * 产生默认验证码,4位中等难度
     *
     * @return
     */
    public static String getSecurityCode() {
        return getSecurityCode(4, SecurityCodeLevel.Medium, false);
    }
    /**
     * 产生长度和难度任意的验证码
     *
     * @param length
     * @param level
     * @param isCanRepeat
     * @return
     */
    public static String getSecurityCode(int length, SecurityCodeLevel level, boolean isCanRepeat) {
        // 随机抽取len个字符
        int len = length;
        // 字符集合(--除去易混淆的数字0,1,字母l,o,O)
        char[] codes = {
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
        };
        // 根据不同难度截取字符串
        if (level == SecurityCodeLevel.Simple) {
            codes = Arrays.copyOfRange(codes, 0, 10);
        } else if (level == SecurityCodeLevel.Medium) {
            codes = Arrays.copyOfRange(codes, 0, 36);
        }
        // 字符集和长度
        int n = codes.length;
        // 抛出运行时异常
        if (len > n && isCanRepeat == false) {
            throw new RuntimeException(String.format("调用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常," + "当isCanRepeat为%3$s时,传入参数%1$s不能大于%4$s", len, level, isCanRepeat, n));
        }
        // 存放抽取出来的字符
        char[] result = new char[len];
        // 判断能否出现重复字符
        if (isCanRepeat) {
            for (int i = 0; i < result.length; i++) {
                // 索引0 and n-1
                int r = (int) (Math.random() * n);
                // 将result中的第i个元素设置为code[r]存放的数值
                result[i] = codes[r];
            }
        } else {
            for (int i = 0; i < result.length; i++) {
                // 索引0 and n-1
                int r = (int) (Math.random() * n);
                // 将result中的第i个元素设置为code[r]存放的数值
                result[i] = codes[r];
                // 必须确保不会再次抽取到那个字符,这里用数组中最后一个字符改写code[r],并将n-1
                codes[r] = codes[n - 1];
                n--;
            }
        }
        return String.valueOf(result);
    }
    /**
     * 生成验证码图片

     * @param securityCode

     * @return

     */
    public static BufferedImage createImage(String securityCode){

        int codeLength = securityCode.length();//验证码长度

        int fontSize = 18;//字体大小

        int fontWidth = fontSize+1;

        //图片宽高

        int width = codeLength*fontWidth+6;
        int height = fontSize*2+1;
        //图片

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics2D g = image.createGraphics();

        g.setColor(Color.WHITE);//设置背景色

        g.fillRect(0, 0, width, height);//填充背景

        g.setColor(Color.LIGHT_GRAY);//设置边框颜色

        g.setFont(new Font("Arial", Font.BOLD, height-2));//边框字体样式

        g.drawRect(0, 0, width-1, height-1);//绘制边框

        //绘制噪点

        Random rand = new Random();

        g.setColor(Color.LIGHT_GRAY);

        for (int i = 0; i < codeLength*6; i++) {

            int x = rand.nextInt(width);

            int y = rand.nextInt(height);

            g.drawRect(x, y, 1, 1);//绘制1*1大小的矩形

        }

        //绘制验证码

        int codeY = height-10;

        g.setColor(new Color(19,148,246));

        g.setFont(new Font("Georgia", Font.BOLD, fontSize));
        for(int i=0;i<codeLength;i++){
            double deg=new Random().nextDouble()*20;
            g.rotate(Math.toRadians(deg), i*16+13,codeY-7.5);
            g.drawString(String.valueOf(securityCode.charAt(i)), i*16+5, codeY);
            g.rotate(Math.toRadians(-deg), i*16+13,codeY-7.5);
        }

        g.dispose();//关闭资源
        return image;
    }

    public static void main(String[] args) throws IOException {
        String securityCode = ValidateImageCodeUtils.getSecurityCode();
        System.out.println(securityCode);

        BufferedImage image = ValidateImageCodeUtils.createImage(securityCode);
        ImageIO.write(image,"png",new FileOutputStream("aa.png"));
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值