java-springboot


微服务阶段

javase:OOP

mysql:持久化

html+ css:前端,视图层

javaweb:独立开发mvc三层架构:原始

ssm:框架,简化开发流程,配置开始较为复杂

war:tomcat运行

spring简化:spring-boot(内嵌tomcat):微服务

服务:微服务

Hello Spring-Boot

什么是Spring-Boot

  • Spring-bootjavaweb的开发框架
  • 约定大于配置
  • 集成了大量第三方配置:redismysqlRabbitMQ

它能干嘛

  • 为所有Sping 开发者更快入门
  • 提供各种默认配置简化项目
  • 内嵌容器简化Web
  • 没有冗余代码生成和XML配置要求

微服务架构

  • 微服务 Resful风格 是一种风格
    • 把一个个服务分成多个服务(业务
  • SpringMVC:来配置,Controller:提供接口

架构的一种方式

  1. 用户在controller下单:
  2. 通过消息队列 异步不同的服务器上完成以下步骤
    • 仓库动接、资金冻结、验证、仓库数量减少、仓库解冻、资金冻结
  3. 每种服务可以互相组合:高内聚,低耦合

各个服务之间低耦合

引入Spring-Boot

方法一:

spring-boot 开始页面:https://start.spring.io/

  1. 选择下载
  2. 接着在idea里面选择导入项目

方法二:使用idea创建

Spring-Boot 目录结构

Hello world!

  • 创建com.hui.demo.controller.HelloController
@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello() {
        return "hello world!";
    }
}
  • 通过浏览器访问localhost:8080/hello 即可

你也可以这样写:

@Controller
@RequestMapping("/hello")
public class HelloController {

    @GetMapping("/hello")
    @ResponseBody
    public String hello() {
        return "hello world!";
    }
}
  • 通过浏览器访问localhost:8080/hello/hello 即可

附上常用的几个注解:

@Controller:处理http请求

@RestController:Spring4之后新加入的注解,原来返回json。需要@ResponseBody和@Controller配合

@RequestMapping :配置url映射

@ResponseBody:将java对象转为json格式的数据

更改banner和端口号

  • resources中创建banner.txt
    • 然后将要启动的样子放入banner.txt
  • 更改端口号在application.properties
    • 加入一行:server.port=8081

原理初探

pom.xml

  • spring-boot-dependencies:核心依赖在夫工程中
  • 写入SpingBoot依赖不需要版本:因为有这些版本仓库

启动器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
  • 需要使用寿命功能只需要找到对应的启动器就可以了

官网上写了有多少个启动器

主程序

这里要分析下源码

。。。等我学完再把这里补上吧

外置配置

Spring-boot使用全局配置文件,文件名固定

  • application.properties
    • key=value
  • application.yml
    • key: value (注意有空格)

SpringBoot 推荐使用yml作为外置配置文件

yml 基础语法

  • yml可以有如下类型
name: hui3c

# 对象
student:
  name: huist
  age: 3

# 对象:也可以写成行内的方法
student2: {name: huist,age: 3}

# 数组
pets:
  - cat
  - dog
  - pig

# 数组:行内写法
pets2: [cat,dog,pig]

实体类

// ----------Person.java-----------------
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class Person {
    private String name;
    private  Integer age;
    private Boolean wife;
    private Date brith;
    private Map<String,Object> maps;
    private Dog dog;
}
// ---------Dog.java---------
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class Dog {
    private String name;
    private Integer age;
}
  • 通过yal赋值
person:
  name: hui3c
  age: 23
  wife: false
  birth: 2121/02/02
  maps: {k1: v1,k2: v2}
  lists:
    - code
    - music
  dog:
    name: 小黄
    age: 3
  • 在实体类中使用@ConfigurationProperties注解来导入对应的yml文件

注解将配置绑定yml为person对象

...
@ConfigurationProperties(prefix = "person")
public class Person {
    ...

解决方法

pom.xml中导入对应依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

测试类:


@SpringBootTest
class DemoApplicationTests {

    @Autowired
    private Person person;
    @Test
    void contextLoads() {
        System.out.println(person);
    }
}

用于配置文件与实体类属性一一绑定

<!-- 通过此 注解 绑定 properties 配置文件 -->
@PropertySource(value = "class:hello.properties")

yml 其他功能

yml占位符:可以指定范围、随机数生成、uuid生成等等.. 这些可以简化很多业务代码

# 随机数占位符
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}

# 可以使用 : 表示默认值
  dog:
  # 如果person.hello没有值就展示hello
    name: ${person.hello:hello}_dog

自动松散绑定

有一配置last-name

last-name: hui3c

有在实体类的表现LastName

private String LastName;

JSR303 校验

在实体类上使用注解@Validated,你可以在某个属性上使用JSR303的注解来进行简单的数据校验

  • 在使用之前需要导入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  • 例子:检测类型是否符合email
...
@Validated
public class Person {
    @Email
    private String email;
    ...

其他jsr303校验参数

yml 作用域

yml 可以在以下这些区域存在(优先级顺序)

  • file:./config/ :项目下 ./config/application.yml 优先级最高
  • file:./
  • classpath:/config/
  • classpath:/

多环境配置

server:
  port: 8081


---
server:
  port: 8082
spring:
  profiles: dev

---
server:
  port: 8083
spring:
  profiles: test

使用sping.profile.active 指定哪套环境,不指定则为8081,指定为如下配置后为8082

server:
  port: 8081
spring:
  profiles:
    active: dev
---
...

spring boot配置

挖个坑以后填,正在分析源码

spring-boot web开发

没有什么比web开发更简单的了

首要解决的问题:

  • 导入静态资源
  • 首页
  • jsp,模板引擎Thymeleaf
  • 装配springmvc
  • 增删更改查
  • 拦截器
  • 国际化

webjars官网:https://www.webjars.org/

静态资源

maven 方式引入 jqueryJavaScript

  1. 在springboot中使用如下方式访问静态文件
    • webjars locatlhost:8080/webjars/.
    • public, static, /**,resources localhost:8080/
  2. 优先级
    • resources > static(默认)>public

自定义配置目录

spring.mvc.static-path-pattern=/**

首页配置

模板渲染

使用Thymeleaf 引擎渲染页面

官网:https://www.thymeleaf.org/

github:https://github.com/thymeleaf/thymeleaf

使用手册:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.pdf

目标:通过controller 跳转到指定页面

导入依赖:你也可以在创建项目时就导入

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

2.3后使用

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

得出你可以这样配置

spring.thymeleaf.suffix=
spring.thymeleaf.prefix=

渲染路径

  • 编写控制成代码com.hui.controller
@Controller
public class IndexController {
    
    @RequestMapping("/test")
    public String test() {
        return "test";
    }
}
  • resources->templates->test.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>test</h1>
</body>
</html>
  • 浏览器访问127.0.0.1:8080/test即可完成映射

基本用法

  1. 控制器传值
  • 需要传入 Model model
  • 使用model下的addAttribute 方法绑定变量值
@Controller
public class IndexController {

    @RequestMapping("/test")
    public String test(Model model) {
        model.addAttribute("msg", "hello,world!");
        return "test";
    }
}
  1. 在html中引入依赖
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  1. 绑定属性使用:th:text
<h1 th:text="${msg}">test</h1>

补充 - 循环

  • 控制层有一数组
model.addAttribute("users", Arrays.asList("user1","user2"));
  • 使用th:each 循环输出
<ul th:each="user:${users}">
    <li th:text="${user}"></li>
</ul>

<!-- 或者 行内写法 -->
<ul th:each="user:${users}">
    <li>[[ ${user} ]]</li>
</ul>

文档的第10小节,4小节有所有的用法以及语法,与vue差不多

管理系统初探

引入文件

将html和静态资源分别放入statictemplates

伪造数据库实体类

  • com.hui.pojo:两个实体类 对应部门表和员工表
// -------------Department-----------------
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
    private Integer id;
    private String departmentName;
}

// -------------Employee-----------------
@Data
@NoArgsConstructor
public class Employee {

    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;

    private Department department;
    private Date birth;

    // 不接受birth参数
    public Employee(Integer id, String lastName, String email, Integer gender, Department department) {
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.department = department;
        // 通过new方式创建
        this.birth = new Date();
    }
}

Dao实现类

  • com.hui.dao
// -------------DepartmentDao-----------------
@Repository
public class DepartmentDao {

    private static Map<Integer, Department> departments = null;

    static {
         departments = new HashMap<>();
         departments.put(101, new Department(101,"教学部"));
         departments.put(102, new Department(102, "市场部"));
         departments.put(103, new Department(103, "教研部"));
         departments.put(104, new Department(104, "运营部"));
         departments.put(105, new Department(105, "后勤部"));
    }

    // 获得所有部门信息
    public Collection<Department> getDepartments() {
        return departments.values();
    }

    // 通过id得到部门
    public Department getDepartmentById(Integer id) {
        return departments.get(id);
    }
}
// -------------EmployeeDao-----------------
package com.hui.dao;
@Repository
public class EmployeeDao {
    private static Map<Integer, Employee> employees = null;
    // 员工所属部门
    @Autowired
    private DepartmentDao departmentDao;
    static {
        //创建一个员工表
        employees = new HashMap<>();
        employees.put(1001, new Employee(1001, "AA", "[email protected]", 1, new Department(101, "教学部")));
        employees.put(1002, new Employee(1002, "BB", "[email protected]", 0, new Department(102, "市场部")));
        employees.put(1003, new Employee(1003, "CC", "[email protected]", 1, new Department(103, "教研部")));
        employees.put(1004, new Employee(1004, "DD", "[email protected]", 0, new Department(104, "运营部")));
        employees.put(1005, new Employee(1005, "EE", "[email protected]", 1, new Department(105, "后勤部")));
    }
    // 增加员工
    private static Integer initId = 1006;
    public void save(Employee employee) {
        if (employee.getId() == null) {
            employee.setId(initId++);
        }
        // 部门关联外键
        employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));

        employees.put(employee.getId(),employee);
    }
    // 通过id查询
    public Employee getEmployeeById(Integer id) {
        return employees.get(id);
    }
    // 删除员工
    public void delete(Integer id) {
        employees.remove(id);
    }
}

首页静态

首页使用覆盖mvc配置(视图控制)方法来展示首页

  • 创建com.hui.config.MyMvcConfig
/**
 * @author Hui3c
 * @program: springbootweb
 * @description: 覆盖mvc配置类
 * @date 2021-04-04 10:36:43
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    // 重写 视图控制层
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }
}
  • 关闭掉渲染引擎的缓存
spring:
  thymeleaf:
    cache: false
  • 修改所有页面静态资源
    • thymeleaf中,资源用@包裹
    • 别忘了引入依赖生命
<html lang="en" xmlns:th="http://www.thymeleaf.org">

修改前:

<link href="asserts/css/bootstrap.min.css" rel="stylesheet">
<link href="asserts/css/signin.css" rel="stylesheet">
<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">

修改后:加th: 链接用@{...}包裹

<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{/css/signin.css}" rel="stylesheet">
<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">

数据库应用

整合mybatis

再导入mybatis依赖

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>

手册:https://github.com/alibaba/dubbo-spring-boot-starter/blob/master/README_zh.md

数据源配置

  • 注意要设置时区serverTimezone
  • 在配置mybatis文件目录时注意mybatis前不需要加/
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://127.0.0.1:3306/mybatis?serverTimezone=UTC&useSSL=true&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.jdbc.Driver
    
# mybatis别名设置。(扫描包),以及mapper文件位置
# <typeAliases>
#     <package name="com.hui.pojo"/>
# </typeAliases>
mybatis:
  type-aliases-package: com.hui.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

1、编写实体类

  • com.hui.pojo.user
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}

2、编写mapper 接口类

  • com.hui.mapper.UserMapper
  • 加一个注解,然后写需要的东西
@Mapper
@Repository
public interface UserMapper {
    List<User> queryUserList();
    User queryUserById(int id);
    int addUser(User user);
    int updataUser(User user);
    int deleteUser(int id);
}

3、编写Mybatis配置文件

  • resources->mybatis->mapper创建UserMapper.xml,需要在配置文件中加载此文件
  • 别忘了要先绑定对应mapper
<?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">

<!--绑定一个dao/mapper接口-->
<mapper namespace="com.hui.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>

	<update id="deleteUser" parameterType="int" >
		delete from mybatis.user where id = #{id}
	</update>

</mapper>

4、编写控制层

  • com.hui.controller.UserController
  • 记得注解@Autowired自动导入
@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper;

    @GetMapping("/queryUserList")
    public List<User> queryUserList() {
        List<User> users = userMapper.queryUserList();
        for (User user : users) {
            System.out.println(user);
        }
        return users;
    }

    @GetMapping("/addUser")
    public String addUser() {
        userMapper.addUser(new User(5,"name","123"));
        return "ok";
    }

    @GetMapping("/updateUser")
    public String updateUser() {
        userMapper.updataUser(new User(5,"name","321"));
        return "ok";
    }

    @GetMapping("/deleteUser")
    public String deleteUser() {
        userMapper.deleteUser(5);
        return "ok";
    }

}

文章作者: Hui3c
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-ND 4.0 许可协议。转载请注明来源 Hui3c !
  目录