spring boot 学习

springboot 官方文档

侵权联系博主 及时删除 博主q(2209265211)

  1. springboot简介

    SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。
  2. 特点

(1)可以创建独立的Spring应用程序,并且基于其Maven或Gradle插件,可以创建可执行的JARs和WARs;
(2)内嵌Tomcat或Jetty等Servlet容器;
(3)提供自动配置的“starter”项目对象模型(POMS)以简化Maven配置;
(4)尽可能自动配置Spring容器;
(5)提供准备好的特性,如指标、健康检查和外部化配置;
(6)绝对没有代码生成,不需要XML配置。

  1. 第一个springboot项目

在controller层写一个helloworld程序
@RestController:表示带返回结果的Controller
@RequestMapping("/hello"):向浏览器发送localhost:8080/hello即可跳转到这个页面在这里插入图片描述

  1. springboot配置文件 config

    官方推荐我们使用yaml的文件形式来配置 application.yaml
    yaml的语法可以参考菜鸟教程 :https://www.runoob.com/w3cnote/yaml-intro.html
person:
  name: 张三
  age: 3
  birth: 2021/4/14
  map: {k1: v1,k2: v2,k3: v3}
  list:
    - music
    - whh
  set:
    - 1
    - 2
  dog:
    name: 旺财
    age: 3

dog:
  name: 小黑
  age: 200


person类定义:

/*
@Component把普通pojo实例化到spring容器中
@ConfigurationProperties 相当于加载application.yaml中的 prefix后的东西
@PropertySource 加载自己定义的配置文件 classpath: 文件名.properties
@Autowired 自动注入
classpath 就是自己的resources文件夹下面的
 */
@Component
//@ConfigurationProperties(prefix = "person")
@PropertySource("classpath:test.properties")
public class Person {
    @Value("${name}")
    private String name;
    @Value("${age}")
    private int age;
    @Value("${birth}")
    private Date birth;
    @Value("#{{k1:'v1',k2:'v2'}}")
    private Map<String,Object> map;
    @Value("${list}")
    private List<Object> list;
    @Value("${set}")
    private Set<Object> set;
    @Autowired
    private Dog dog;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Date getBirth() {
        return birth;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    public List<Object> getList() {
        return list;
    }

    public Set<Object> getSet() {
        return set;
    }

    public Dog getDog() {
        return dog;
    }

    public Person(String name, int age, Date birth, Map<String, Object> map, List<Object> list, Set<Object> set, Dog dog) {

        this.name = name;
        this.age = age;
        this.birth = birth;
        this.map = map;
        this.list = list;
        this.set = set;
        this.dog = dog;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }

    public void setSet(Set<Object> set) {
        this.set = set;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birth=" + birth +
                ", map=" + map +
                ", list=" + list +
                ", set=" + set +
                ", dog=" + dog +
                '}';
    }
}
  1. 第一个web项目(CURD)

    这里CURD使用自己模拟数据库没有去连接数据库

@Repository将EmployeeDao注入到spring容器中

@Repository
public class EmployeeDao {
    //模拟数据库
    private static Map<Integer, Employee> employees = null;

    @Autowired
    private DepartmentDao departmentDao;
    static {
        employees = new HashMap<Integer, Employee>();

        employees.put(1001,new Employee(1001,"AA","A246542@qq.com",0,new Department(101,"教学部")));
        employees.put(1002,new Employee(1002,"BB","B246542@qq.com",1,new Department(102,"市场部")));
        employees.put(1003,new Employee(1003,"CC","C246542@qq.com",0,new Department(103,"教研部")));
        employees.put(1004,new Employee(1004,"DD","D246542@qq.com",1,new Department(104,"运营部")));
        employees.put(1005,new Employee(1005,"EE","E246542@qq.com",0,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);
    }

    //获取所有员工信息
    public Collection<Employee> getAll(){
        return employees.values();
    }

    //通过id查询员工
    public Employee getEmployeeById(Integer id) {
        return employees.get(id);
    }

    //通过id删除员工
    public void delete(Integer id) {
        employees.remove(id);
    }
}

//部门dao
@Repository
public class DepartmentDao {
    //模拟数据库
    private static Map<Integer, Department> departments = null;

    static {
        departments = new HashMap<Integer, Department>();

        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);
    }
}

Department类与Employee类的定义
因为代码太多就不把getset构造方法导入

//部门表
public class Department {
    private Integer id;
    private String departmentName;
    }
//员工表
public class Employee {
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;// 0:女 1:男
    private Department department;
    private Date birth;
}

在前端上采用thymeleaf来操作数据

  1. thymeleaf语法总结

    参考官方文档 https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#preface
    留下不会英语的泪
    命名空间: xmlns:th=“http://www.thymeleaf.org”
  2. springboot整合thymeleaf

需要在pom.xml中导入如下依赖

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

其他就全是些和业务相关的东西没什么技术 就不再做记录

  1. springboot连接数据库

上面5 使用的是自己模拟的数据 接下来就连接数据库后可使用数据库中的数据
这里介绍使用原生的jdbc连接数据库 下面再介绍整合mybatis

连接数据库当然需要导入相应的包

		<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>

还需要配置相应的username 和password 和url
这里在application.yaml 中配置 当然也可以在application.properties中配置

spring:
  datasource:
    username: root
    password: 123
    #serverTimezone 时区的配置
    url: jdbc:mysql://localhost:3306/ppp?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver

然后在controller中验证是否连接即可
sql语句根据自己的数据库写即可
使用的是原生的jdbc连接jdbcTemplate功能不是很强大 前面写的一个web项目涉及到了一对多我只会使用mybatis来实现这个功能

@RestController
public class MyController {
    @Autowired
    JdbcTemplate jdbcTemplate;

    @GetMapping("/index")
    public List<Map<String,Object>> getAll(){
        String sql = "select * from ppp.employee";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        System.out.println(maps);
        return maps;
    }
}
  1. springboot整合mybatis

导入他们整合的包

<!--整合mybatis 需要的包 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

还是直接用一个例子来学习最好
整合mybatis就需要数据库 数据如下

CREATE TABLE `department`  (
  `id` int(11) primary key,
  `departmentName` varchar(20)
)

INSERT INTO `department` VALUES (101, '教学部');
INSERT INTO `department` VALUES (102, '市场部');
INSERT INTO `department` VALUES (103, '教研部');
INSERT INTO `department` VALUES (104, '运营部');
INSERT INTO `department` VALUES (105, '开发部');

对应类pojo

public class Department {
    private int id;
    private String departmentName;
    }

在配置文件中书写一下信息:
mybatis.type-aliases-package:扫描的包 数据库 对应的类
mybatis.mapper-locations:xxxMapper.xml的地址 *.xml直接扫描当前目录下的所有xml

spring.datasource.username=root
spring.datasource.password=123
spring.datasource.url=jdbc:mysql://localhost:3306/ppp?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#整合mybatis
mybatis.type-aliases-package=com.yxx.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

Mapper类:

// @Mapper 表示了这是一个mybatis的mapper类
//@Repository 将该类注入spring容器
@Mapper
@Repository
public interface DepartmentMapper {
    public List<Department> queryAll();
    public Department queryById(@Param("id") int id);
    public void updateById(Department department);
    public void add(Department department);
    public void del(@Param("id") int id);
}

mapper.xml
mapper namespace="com.yxx.mapper.DepartmentMapper namespace 必须是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">
<mapper namespace="com.yxx.mapper.DepartmentMapper">
    <select id="queryAll" resultType="Department">
        select * from department
    </select>
    <select id="queryById" resultType="Department">
        select * from department where id = #{id}
    </select>
    <update id="updateById" parameterType="Department">
        update department set departmentName = #{departmentName} where id = #{id}
    </update>
    <insert id="add" parameterType="Department">
        insert into department(id,departmentName) values (#{id},#{departmentName})
    </insert>
    <delete id="del">
        delete from department where id = #{id}
    </delete>
</mapper>

接下来在controller中验证即可

// @RestController 带放回结果的Controller
@RestController
public class DepartmentController {

	//自动注入即可 因为@Repository将DepartmentMapper注入到了spring容器中
    @Autowired
    private DepartmentMapper departmentMapper;

    @GetMapping("/queryAll")
    public List<Department> queryAll(){
        List<Department> departments = departmentMapper.queryAll();
        return departments;
    }

    @GetMapping("/queryById/{id}")
    public Department queryById(@PathVariable("id") int id){
        return departmentMapper.queryById(id);
    }
    @GetMapping("/updateById")
    public String updateById(){
        Department department = new Department(105,"开发部");
        departmentMapper.updateById(department);
        return "update-ok";
    }
    @GetMapping("/add")
    public String add(){
        Department department = new Department(107,"小麦部");
        departmentMapper.add(department);
        return "add-ok";
    }
    @GetMapping("/del")
    public String del(){
        departmentMapper.del(107);
        return "del-ok";
    }
}
  1. springboot整合Security

正如你可能知道的两个应用程序的两个主要区域是“认证”和“授权”(或者访问控制)。这两个主要区域是Spring Security 的两个目标。“认证”,是建立一个他声明的主题的过程(一个“主体”一般是指用户,设备或一些可以在你的应用程序中执行动作的其他系统)。“授权”指确定一个主体是否允许在你的应用程序执行一个动作的过程。为了抵达需要授权的店,主体的身份已经有认证过程建立。这个概念是通用的而不只在Spring Security中。

Security是搞安全的框架 包含授权和认证 还有一个shiro安全框架
首先还是导入依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.4.5</version>
        </dependency>

我们需要完成Security的授权和认证
我们在自己写的配置类中需要继承WebSecurityConfigurerAdapter 来实现他的方法来完成授权与认证

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人都可以访问 功能页只有具有权限的人才能访问

        //.antMatchers("/level1/**").hasRole("vip1")设置的是url里的路径
        //不是真实路径
        //必须.hasRole("vip1")拥有这个权限才可以访问.antMatchers("/level1/**")
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

        //没有权限的话 默认跳到login页面
        //loginPage定制登录页
        http.formLogin().loginPage("/toLogin");

        //注销 注销后跳到首页
        http.csrf().disable();//关闭csrf功能 不关可能导致登出失败
        http.logout().logoutSuccessUrl("/");

        //开启记住我功能
        http.rememberMe().rememberMeParameter("remember");
    }


    //认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {


        //inMemoryAuthentication()从内存中读数据 正常应该在数据库中去读
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2", "vip3").and()
                .withUser("yxx").password(new BCryptPasswordEncoder().encode("123")).roles("vip2").and()
                .withUser("ppp").password(new BCryptPasswordEncoder().encode("123")).roles("vip2", "vip3");
    }
}

@EnableWebSecurity:表示我们开启WebSecurity的功能
其他的在代码注解中写的很完整

  1. springboot整合shiro

我还没去学 等以后学了在补充 先挖个坑

springboot整合swagger

swagger是什么?
Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。
Swagger 的优势
支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。
提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试。参数和格式都定好了,直接在界面上输入参数对应的值即可在线测试接口。

老规矩导入依赖

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

导入该依赖后启动项目即可访问 localhost:8080/swagger-ui.html
在该路径下即可查看自己配置的东西
在这里插入图片描述
在配置类中配置相关信息:

@Configuration
@EnableSwagger2 //开启swagger2 就可以访问 http://localhost:8080/swagger-ui.html
//多个分组 只需要多个Docket即可
public class SwaggerConfig {


    //配置swagger 的 Docket 的bean实例
    @Bean
    public Docket docket(Environment environment) {
        //获取当前项目的环境
        Profiles profiles = Profiles.of("dev");
        boolean flag = environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("yxx")
                //enable 是否开启swagger2
                .enable(flag)
                .select()
                //RequestHandlerSelectors,配置要扫描接口的方式
                //basePackage 指定要扫描的包
                //any 扫描全部
                //none 不扫描
                //withClassAnnotation 扫描类上的注解
                //withMethodAnnotation 扫描方法上的注解
                .apis(RequestHandlerSelectors.basePackage("com.yxx.controller"))
                //paths() 过滤什么路径
                //.paths(PathSelectors.ant("/index"))
                .build();
    }

    @Bean
    public Docket docket2() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("a");
    }

    @Bean
    public Docket docket3() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("b");
    }

    //配置swagger的信息info
    public ApiInfo apiInfo() {
        Contact DEFAULT_CONTACT = new Contact("yxx", "", "2209265211@qq.com");
        return new ApiInfo(" yxx Api Documentation", "学习", "2.0", "urn:tos", DEFAULT_CONTACT, "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList());
    }
}

还有一个@ApiXXX的东西是给swagger-ui.html上书写注释的东西 贴上代码更好理解

//@ApiXXX就是加注释 在swagger中能够看到这些注释
@ApiModel("用户类")//给类加注释
public class User {
    @ApiModelProperty("用户名")//给类中属性
    private String name;
    @ApiModelProperty("密码")
    private String password;
}

/*
@Api 给Controller加注释
@ApiOperation 给Controller中的方法加注释
@ApiParam 给Controller中的方法中的参数加注释
@ApiModel 给实体类加注释
@ApiModelProperty 给实体类的属性加注释
 */
//这个是controller中的代码
@Api("我的控制类")
@RestController
public class MyController {

    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }

    //只要我们的接口 返回值是一个实体类 就会被扫描到swagger中
    @PostMapping("/user")
    public User user() {
        return new User();
    }

    @ApiOperation("username控制")
    @GetMapping("/username")
    public String username(@ApiParam("用户名") String username) {
        return "hello" + username;
    }
}

实际效果出来如下:
在这里插入图片描述

异步任务 邮件任务 定时任务

  1. 异步任务

好像并没有什么讲的 就几个注解
@EnableAsync //开启异步任务 在入口类中添加
@Async //表示这是一个异步方法

  1. 邮件任务

导入依赖:

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

需要配置相关

spring.mail.username=XXX //自己的邮箱 写全路径 包括@XX.com
spring.mail.password=XXX //需要自己去自己的邮箱开启pop3服务 获取授权码
spring.mail.host=smtp.163.com

在test中测试即可
不知道为什么我用qq邮箱会出错 但用163就没问题

@Autowired
    MailSender mailSender;

    @Test
    void contextLoads() {
        //一个简单的邮件
        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject("springboot学习");
        message.setText("springboot");
        message.setTo("XXX");//目标邮箱
        message.setFrom("XXX");//发送邮箱
        mailSender.send(message);
    }
  1. 定时任务

@EnableScheduling //开启定时功能 在入口类中添加

@Service
public class ScheduledService {


    //cron表达式
    //秒 分 时 日 月 周几
    @Scheduled(cron = "40 16 21 * * *")  //表示这是一个定时方法
    public void hello(){
        System.out.println("你被执行了!");
    }
}

cron表达式用起来非常不舒服 的是没办法你必须用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值