SpringBoot
Controller
//返回字符串
@RestController
public class HelloController {
//返回字符串
@RequestMapping("/hello")
public String hello(){
//调用业务,接收前端参数
return "hello,World";
}
}
//返回字符串,目前认为去掉@ResponseBody是去找hello页面
@Controller
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String hello(){
//调用业务,接收前端参数
return "hello";
}
}
修改端口
在application.properties里面配置
server.port=80
pom.xml
spring-boot-starter-parent:核心依赖在父工程中 我们在写或者引入以写Springboot依赖的时候,不需要指定版本,就是因为有这些版本仓库
启动器:说白了就是Springboot的启动场景
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
比如spring-boot-starter-web,他就会帮我们导入web环境的所有依赖。
springboot会将所有的功能场景,都变成一个个的启动器。
具体启动可以参考官网:https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters
主程序
//标注这个类是一个springboot的应用
@SpringBootApplication
public class StuApplication {
public static void main(String[] args) {
//将springboot应用启动
SpringApplication.run(StuApplication.class, args);
}
}
Springboot配置文件(删除application.properties,添加application.yaml)
注意点:
以前application.properties 配置的时候都是(键=值)。而且容易乱码(settings->Editor)
现在 application.yaml 配置(键:空格值)
**yaml可以给实体类成员变量注入值**
传统方式(通过注解)
//住址实体类
@Component
public class Addr{
@Value(1)
private Integer addrId;
@Value("合肥")
private String addrName;
}
//SpringBoot测试类
@SpringBootTest
class SpringBootCeShi{
@Autowired
//如果有很多狗,需要指定@Qualifier
private Addr addr;
@Test
void contextLoads(){
sout(addr);
}
}
config.properties
//住址实体类
@Component
public class Addr{
private Integer addrId;
private String addrName;
}
//人实体类
@Component
@PropertySource(value = "classpath:config.properties")
public class Person{
//SPEL表达式取出配置文件的值
@Value("${name}")
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Addr addr;
}
//.properties。注意名字必须得一一对应
name = wwy
//测试
@SpringBootTest
class SpringBootCeShi{
@Autowired
private Person person;
@Test
void contextLoads(){
sout(person)
}
}
**yaml方式注入值**
//住址实体类
@Component
public class Addr{
private Integer addrId;
private String addrName;
}
//人实体类
@Component
@ConfigurationProperties(prefix = "person")//绑定yaml里面的值
public class Person{
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Addr addr;
}
//yaml。注意名字必须得一一对应。松散绑定:实体类的驼峰命名aaaBbbb可以在yaml使用杠aaa-bbbb
person:
name: wwy
age: ${random.int}//生成随机值
happy: ${person.flag:false}//先看可有flag,有则按照flag,没有则为false
birth: 2021/6/24
maps: {k1: v1,k2: v2}
lists:
- code
- music
- girl
addr:
addrId: 1
addrName: 合肥
//测试
@SpringBootTest
class SpringBootCeShi{
@Autowired
private Person person;
@Test
void contextLoads(){
sout(person)
}
}
注:
被这些注解修饰的类,都会交给Spring容器进行管理
@Controller
@Service
@Repository
@Component
被这个注解修饰的时候,表示本实例类的成员变量会被配置文件里面的xxx这么一类配置赋值
@ConfigurationProperties(prefix = "xxx")
被各个注解修饰的时候,表示本对象,自动去找值注入,先根据User(也就是byType)去找,如果找不到则抛出异常,如果找到则看有多少个,如果有很多则根据user (也就是byName)去找。
@Autowired
private User user;
如果根据类型在其中找到多个对象则使用@Qualifier("xxxx")
@Autowired
@Qualifier("xxxx")
private User user;
静态页面跳转
Controller层
@Controller
@RequestMapping("/father")
public class LoginController {
@GetMapping("/son")
//@ResponseBody 带则在页面显示字符串,
public String hello(){
return "test";
}
}
@Controller
public class IndexController {
@RequestMapping({"/","/index.html"})
public String index(){
return "index";
}
}
//导入maven坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
//静态资源放置
一般html文件放置在resources下的templates里面
JSR-303验证
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
@Component
@ConfigurationProperties(prefix = "user")
@Validated //用于数据校验
public class User {
private Integer id;
private String name;
@Email() //具体是邮箱格式校验
private String Em;
}
@Null 必须为null
@NotNull 不为null
@AssertTrue 必须为true
@AssertFalse 必须为false
@Min(value) 必须为数字,大于等于指定值
@Max(value) 必须为数字,小于等于指定值
@DecimalMin(value) 必须为数字,大于等于指定值
@DecimalMax(value) 必须为数字,小于等于指定值
@Size(max,min) 数字在指定范围内
@Digits(integer,fraction) 数字在可接受范围内
@Past 必须是过去的日期
@Future 必须是将来日期
@Pattern(value) 必须符合正则表达式
@Email 必须是电子邮箱格式
@Length 字符串长度在指定范围内
@NotEmpty 字符串非空
@Range 元素在合适范围内
配置文件的位置
1.工程目录下的config目录(手动创建的)
2.项目目录下
3.resources下的config目录(手动创建的)
4.resource目录下
优先级: 1 > 2 > 3 > 4(默认配置的4)
**多环境配置**
.properties多文件配置
application-dev.properties 开发环境 8081
application-test.properteis 测试环境 8083
application-prod.properteis 生产环境 8082
需要激活哪个环境只需要在上面这个文件中
(spring.profils.active=dev)便可以打开开发环境
.yaml文件配置
server:
port: 8081
speing:
profiles:
active: dev //使用开发环境
---
server:
port: 8082
spring:
profils:dev
---
server:
port:8083
spring:
profils:test
SpringBoot Web开发
SpringBoot最大特点:自动装配
步骤:
1.创建应用、选择模块 --》SpringBoot自动配置好环境
2.专注业务开发
待解决的问题:
1.导入静态资源
2.首页
3.(以前我们使用jsp,这里没有写jsp的)。现在使用模板引擎 Thymeleaf
4.装配扩展SpringMVC
5.增删改查
6.拦截器
7.国际化
**静态资源导入**
//首先确定可以将字符串显示在页面,判断工程建的是否成功
@RestController
//@RestController与@Controller共同点: 都是用来表示Spring某个类的是否可以接收HTTP请求
//@Controller:标识一个Spring类是Spring MVC controller处理器
//@RestController:这个是@Controller和@ResponseBody的结合体
//如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,配置的视图解析器InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。例如:本来应该到success.jsp页面的,则其显示success.
//如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
//如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。
public class LoginController {
@GetMapping("/a")
public String login(){
return "hello";
}
}
插入:导入jar包,使用webjars,https://www.webjars.org/
静态资源地址:(如使用webjars坐标导入的jquery)http://localhost:8080/webjars/jquery/3.6.0/jquery.js
静态资源可以放在
resources:
public: //一般放置共有资源
resources://一般放置上传的资源文件
static: //放一些静态资源,如图片
优先级:resources > static > public
http://localhost:8080/static.js
自定义静态资源目录(在配置文件中):spring.mvc.static-path-pattern=/img/,classpath:/js/
**首页**
index.html(名字必须一致)
可以放在:static目录,templates目录(必须通过Controller层请求)
关于controller层请求才能访问(要引入Thymeleaf模板引擎)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
@Controller
public class IndexController {
@RequestMapping("/hi")
public String helloPage(){
return "index";
}
}
图标定制
只需将favicon.ico放入到static文件夹下
Springboot版本降低,只需要更改pom.xml里面下面代码的version
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Thymeleaf
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
@Controller
public class IndexController {
@RequestMapping("/ceshi")
public String ceshi(Model model){
model.addAttribute("msg","hello,springboot -wwy");
return "test";
}
}
<!--text.html-->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--
简单表达式:
th:href="@{/xxx/xx/xxxx.css}" 链接使用@符号
th:text="#{hello}" 文本使用#
变量 ${...}
选择表达式 *{...}
消息 #{...}
URL @{...}
片段表达式 ~{...}
Literals
text:'one text','Another one',...
number: 0,34,3.0,12.3,...
null: null
tokens: one,sometext,main,...
文本操作:
+
|The name is ${name}}|
算数运算:
+,-,*,/,%
布尔运算:
and,or,!,not
比较运算符:
>,<,>=,<=,(gt,lt,ge,le),==,!=(eq,ne)
条件判断:
if-then (if)?(then)
if-then-else (if)?(then):(else)
Default (value)?(defaultvalue)
-->
<h1>测试</h1>
<hr>
<div th:text="${msg}"></div>
<div th:utext="${msg}"></div>
<hr>
<div th:each="u:${user}" th:text="${u}"></div>
<hr>
<div th:each="u:${user}">[[${u}]]</div>
</body>
</html>
注:所有的html元素都可以被thymeleaf替换接管: th:元素名
th:text="${msg}" th:style="${}"
th:insert
th:replace
th:each
th:if
th:unless
th:switch
th:case
th:object
th:with
th:attr
th:attrprepend
th:attrappend
th:value
th:href
th:src
th:text 完全按照后台给的文本显示,如果文本有html标签,那么标签会以文本的形式显示出来。
th:utext 如果文本内有html标签,那么标签会起作用。
th:fragment
th:remove
SpringBoot扩展SpringMVC
//如果我们要扩展SpringMVC,官方建议我们这样去做
@Configuration
@EnableWebMvc
//接管MVC的时候不能假如这个注解。这个注解就是导入一个类:
// DelegatingWebMvcConfiguration.class:从容器中获取所有的webmvcconfig
public class MyMvcConfig implements WebMvcConfigurer {
//视图跳转请求/wwy 会跳转test.html
@Override
public void addViewControllers(ViewControllerRegistry registry) {
WebMvcConfigurer.super.addViewControllers(registry);
registry.addViewController("wwy").setViewName("test");
}
}
注: 在Springboot中,有非常多的xxxxConfiguration 帮助我们进行扩展配置,只要看见这个东西,我们就要注意了!
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}
//配置虚拟目录
server.servlet.context-path=/wwy
注:
1.首页配置:所有页面的静态资源都需要使用thymeleaf接管;使用@{ }符号。一般静态资源从static目录开始找@{/css/xxx.css}
2.页面国际化:通过MessageSourceAutoConfiguration
1.在Settings->File Encodings 里面三个位置都是UTF-8
2.在resources目录下创建i18n文件夹
4.创建各种语言的 login.properties(默认) login_en_US.properties(英文) login_zh_CN.properties(中文)
login.btn=登录 login.btn=Sign in
login.password=密码 login.password=Password
login.remember=记住我 login.remember=Remember me
login.tip=请登录 login.tip=Please sign in
login.username=用户名 login.username=Username
3.我们如果需要在项目中进行按钮自动切换,我们需要自定义一个组件LocaleResolver
3.记得将自己写的组件配置到spring容器 @Bean
4.th:href="#{login.btn}"
3.登录功能实现:
<form class="form-signin" th:action="@{/user/login}">
<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<!--如果msg消息为空则不显示消息-->
<span><p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p></span>
<label class="sr-only">Username</label>
<input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only">Password</label>
<input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me" th:text="#{login.remember}">
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}"></button>
<p class="mt-5 mb-3 text-muted">© 2017-2021</p>
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
</form>
//controller层
@Controller
public class LoginController {
@RequestMapping("/user/login")
// @ResponseBody
public String login(
@RequestParam("username") String username,
@RequestParam("password") String password,
Model model){
//具体的登录业务
if (!StringUtils.isEmpty(username)&&"123456".equals(password)){
System.out.println("登录成功!");
/*重定向到main.html页面。
*其实是没有这个页面。我们在配置的时候配置,如果有这样的请求,
* 会跳到dashboard.html页面。
* */
return "redirect:/main.html";
}else {
//告诉用户你登录失败了
model.addAttribute("msg","用户名或者密码错误");
System.out.println("登录失败!");
return "index";
}
}
}
//配置Mvc
@Configuration
//@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
/*解决登录正确后,页面地址栏携带表单数据的问题
*但是这种写法会带了一个问题,只要地址栏输入正确就能
*跳入登录后的页面。后面使用拦截器解决此问题。
*/
registry.addViewController("/main.html").setViewName("dashboard");
}
//自定义的国际化就生效了
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
3.页面拦截器(阻止一些非法访问)
//config配置
/*拦截器*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
/*
*true: 放行
*false: 不放行
* */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录成功之后,应该有用户的session
Object loginUser = request.getSession().getAttribute("loginUser");
if (loginUser==null){//没有登录
request.setAttribute("msg","没有权限,请先登录!");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else{
return true;
}
}
}
//在自定义MVC配置里面注入
@Configuration
//@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
/*解决登录正确后,页面地址栏携带表单数据的问题*/
registry.addViewController("/main.html").setViewName("dashboard");
}
//自定义的国际化就生效了
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
//自定义的拦截器在此注入到Spring
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**") /*如果验证不过的不给予放行*/
.excludePathPatterns("/index.html" /*默认放行的资源*/
,"/"
,"/user/login"
,"/css/*"
,"/js/**"
,"/img/**");
}
}
//对于请求登录的用户,设置session。首先参数里面得带Session参数,HttpSession session。在用户验证成功后向session中存入登录成功者的username。
@Controller
public class LoginController {
@RequestMapping("/user/login")
// @ResponseBody
public String login(
@RequestParam("username") String username,
@RequestParam("password") String password,
Model model,
HttpSession session){
//具体的业务
if (!StringUtils.isEmpty(username)&&"123456".equals(password)){
System.out.println("登录成功!");
/*重定向到main.html页面。
*其实是没有这个页面。我们在配置的时候配置,如果有这样的请求,
* 会跳到dashboard.html页面。
* */
session.setAttribute("loginUser",username);
return "redirect:/main.html";
}else {
//告诉用户你登录失败了
model.addAttribute("msg","用户名或者密码错误");
System.out.println("登录失败!");
return "index";
}
}
}
<form class="form-signin" th:action="@{/user/login}">
<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<!--如果msg消息为空则不显示消息-->
<span><p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p></span>
<label class="sr-only">Username</label>
<input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only">Password</label>
<input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me" th:text="#{login.remember}">
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}"></button>
<p class="mt-5 mb-3 text-muted">© 2017-2021</p>
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
</form>
<!--前台从session获取值,并显示在页面-->
<a th:text="${session.loginUser}"></a>
4.前端相同模块在不同页面复用:将 A.html 页面的侧边栏抽取到 B.html 中。
主要属性:
A.html:th:fragment="sidebar"
B.html:
<!-- A.html -->
<nav th:fragment="sidebar">
<div>
<ul>
<li>
<a>
<svg></svg>
侧边栏一
</a>
</li>
<li>
<a>
<svg></svg>
侧边栏二
</a>
</li>
</ul>
</div>
</nav>
<!-- B.html -->
<div th:insert="~{A::sidebar}">
</div>
<!--
注:
th:insert
th:replace
-->
5.提取公共部分、实现跳转后之前点击的模块在跳转页面变色(选中),使用先页面传参,后页面使用三元运算符判断。
在resource->templates目录下创建一个commons目录,并且在目录里面创建一个commons.html的文件用来抽取公共资源(如:网页导航栏,侧边栏,网页底部)
1.th:fragment="sidebar"
2.th:replace="~commons/commons::topbar"
3.如果要传递参数,可以直接使用(active="")传参,接收判断即可。
<!--commons.html页面-->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!--头部导航栏-->
<nav th:fragment="topbar">
........
</nav>
<!--侧边栏-->
<nav th:fragment="sidebar">
<div>
<ul>
<li>
<a th:class="${active=='main.thml'?'nav-link active':'nav-link'}" th:href="@{/index.html}">首页</a>
</li>
<li>
<a th:class="${active=='list.thml'?'nav-link active':'nav-link'}" th:href="@{/emps}">员工列表</a>
</li>
</ul>
</div>
</nav>
</html>
<!--先页面-->
<!--顶部导航栏-->
<div th:replace="~{commons/commons::topbar}"></div>
<!--侧边栏,携带参数,(active='main.htm')-->
<div th:replace="~{commons/commons::sidebar(active='main.html')}"></div>
<!--后页面-->
<div th:replace="~{commons/commons::topbar}"></div>
<!--侧边栏,携带参数,(active='main.htm')-->
<div th:replace="~{commons/commons::sidebar(active='list.html')}"></div>
6.遍历数据表单使用
后台:model.addAttribute("emps",employees);
前台:th:each="${后端携带信息的标记}"
<table class="table table-striped table-sm">
<thead>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>department</th>
<th>birth</th>
</tr>
</thead>
<tbody>
<tr th:each="emp:${emps}">
<td th:text="${emp.getId()}"></td>
<td th:text="${emp.getLastName()}"></td>
<td th:text="${emp.getEmail()}"></td>
<td th:text="${emp.getGender()==0?'女':'男'}"></td>
<td th:text="${emp.getDepartment().getDepartmentName()}"></td>
<td th:text="${#dates.format(emp.getBirth(),'yyyy年MM月dd日 hh:mm:ss')}"></td>
<td>
<button class="btn btn-sm btn-primary">编辑</button>
<button class="btn btn-sm btn-danger">删除</button>
</td>
</tr>
</tbody>
</table>
7.添加用户
<!--添加员工-->
<h2><a class="btn btn-sm btn-success" th:href="@{/emp}">添加员工</a></h2
@GetMapping("/emp")
public String toAddpage(Model model){
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("departments",departments);
return "emp/add";
}
<form th:action="@{/emp}" method="post">
<div class="form-group">
<label>LastName</label>
<input type="text" name="lastName" class="form-control" placeholder="请输入员工姓名">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control"
placeholder="请输入邮箱">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender"
value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="0">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>department</label>
<!-- 我们在conrtroller接收的是一个Employee,所以我们需要提交的是其中的一个属性-->
<select class="form-control" name="department.id">
<option th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option>
</select>
</div>
<div class="form-group">
<label>Birth</label>
<input type="text" name="birth" class="form-control" placeholder="kuangstudy">
</div>
<button type="submit" class="btn btn-primary">添加</button>
</form>
@Autowired
EmployeeDao employeeDao;
@Autowired
DepartmentDao departmentDao;
@RequestMapping("/emps")
public String list(Model model){
Collection<Employee> employees = employeeDao.getAll();
model.addAttribute("emps",employees);
return "emp/list";
}
@PostMapping("/emp")
public String addEmp(Employee employee){
System.out.println(employee);
//添加用户
employeeDao.save(employee);//调用底层添加员工
// 重定向: redirect
// 转发: forward
return "redirect:/emps";
}
各式各样的数据库在SpringBoot中都是采用SpringData的方式处理
使用原生JDBC开发要选择:
Web:
web
SQL:
JDBC API
MySQL Driver
application.yml
spring:
datasource:
username: root
password:
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
CRUD
@RestController
public class JDBCcontroller {
@Autowired
JdbcTemplate jdbcTemplate;
//查询数据库的所有信息
//没有实体类,数据库中的信息,怎么获取? Map
@GetMapping("userList")
public List<Map<String,Object>> userList(){
String sql = "select * from user";
List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
return list_maps;
}
@GetMapping("addUser")
public String addUser(){
String sql = "insert into mybatis.user(id,name,pwd) values(3,'汪文勇','wwysystem412')";
int update = jdbcTemplate.update(sql);
System.out.println(update);
return "update-ok";
}
@GetMapping("updateUser/{id}")
public String updateUser(@PathVariable("id") int id){
String sql = "update mybatis.user set name=?,pwd=? where id="+id;
//封装
Object[] objects = new Object[2];
objects[0] = "小明2";
objects[1] = "zzzzz";
jdbcTemplate.update(sql,objects);
return "update-ok";
}
@GetMapping("deleteUser/{id}")
public String deleteUser(@PathVariable("id") int id){
String sql = "delete from mybatis.user where id = ?";
jdbcTemplate.update(sql,id);
return "delete-ok";
}
}
Druid数据库连接池配置
spring:
datasource:
username: root
password: *******
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot 默认是不注入这些属性值的,需要自己绑定
#druid 数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错 java.lang.ClassNotFoundException:org.apache.log4j.Priority
#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
Druid后台监控;过滤器Filter
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource(){
return new DruidDataSource();
}
//后台监控功能:web.xml
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
HashMap<String, String> initParameters = new HashMap<>();
//后台需要有人登录,账号密码配置
initParameters.put("loginUsername","admin");//登录的key是固定的
initParameters.put("loginPassword","admin");
//允许谁能访问
initParameters.put("allow","");
//禁止谁能访问
// initParameters.put("kuangsheng","192.168.11.123");
bean.setInitParameters(initParameters);//设置初始化参数
return bean;
}
//过滤器filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
bean.setFilter(new WebStatFilter());
//可以过滤哪些请求呢?
HashMap<String, String> initParameters = new HashMap<>();
//这些东西不进行统计
initParameters.put("exclusions","*.js,*.css,/druid/");
bean.setInitParameters(initParameters);
return bean;
}
}
Druid监控后台:http://www.localhost:8080/druid
**SpringBoot整合Mybatis**
<dependencies>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<!--Mybatis自研的,目的是为了整合。-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--SpringBoot官方的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
``实体类`
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
spring.datasource.username=root
spring.datasource.password=********
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#整合mybatis
mybatis.type-aliases-package=com.wwy.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mapper层(dao)
//这个注解表示了这是一个mybatis的mapper 类:Dao
@Mapper
@Repository
public interface UserMapper {
List<User> queryUserList();
User queryUserById(int id);
int addUser(User user);
int updateUser(User user);
int deleteUser(int id);
}
对应的mapper.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.wwy.mapper.UserMapper">
<select id="queryUserList" resultType="User">
select * from mybatis.user
</select>
<select id="queryUserById" resultType="User">
select * from mybatis.user where id = #{id}
</select>
<insert id="addUser" parameterType="User">
insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<update id="updateUser" parameterType="User">
update mybatis.user set name = #{name} , pwd = #{pwd} where id = #{id}
</update>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id = #{id}
</delete>
</mapper>
controller层(注:没有写service层)
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("/queryUserList")
public List<User> queryUserList(){
List<User> users = userMapper.queryUserList();
return users;
}
@GetMapping("/addUser")
public String addUser(){
int result = userMapper.addUser(new User(3, "李四", "123456"));
System.out.println(result);
if (result==1){
return "add-OK";
}else{
return "add-Fail";
}
}
@GetMapping("/deleteUser")
public String deleteUser(){
int result = userMapper.deleteUser(3);
return "delet-OK";
}
@GetMapping("/updateUser")
public String updateUser(){
int i = userMapper.updateUser(new User(3, "汪文勇", "wwy2021"));
return "update-OK";
}
@GetMapping("/queryUserById")
public User queryUserById(){
User user = userMapper.queryUserById(3);
return user;
}
}
`SpringSecurity(安全)```