springBoot总结

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(安全)```

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值