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">
© 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">
© 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>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<div>
© 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方式比对,如果还有多个,则报出异常 |
@Qualifier | spring的注解,按名字注入 一般当出现两个及以上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"));
}
}