【Spring Boot】简单实践

lombok

使用Spring Boot整合SSM工程;需要使用到数据库数据。

将数据库表数据导入到数据库中(springboot_test);

编写数据库表对应的实体类;一般情况下需要编写get/set/toString等这些方法会耗时并且会让实体类看起来比较臃肿。可以使用lombok插件对实体类进行简化。

lombok是一个插件工具类包;提供了一些注解@Data、@Getter等这些注解去简化实体类中的构造方法、get/set等方法的编写。

在IDEA中安装lombok插件;

不安装插件在IDEA中使用lombok的注解虽然编译能通过,但是源码会报错。所以为了让IDEA更好的辨别lombok注解则才安装插件。

添加lombok对应的依赖到项目pom.xml文件;

 
  org.projectlombok 
  lombok 

改造实体类使用lombok注解

然后可以在Bean上使用:
@Data :自动提供getter和setter、hashCode、equals、toString等方法
@Getter:自动提供getter方法
@Setter:自动提供setter方法
@Slf4j:自动在bean中提供log变量,其实用的是slf4j的日志功能。
例如;在javabean上加@Data,那么就可以省去getter和setter等方法的编写,lombok插件会自动生成。

//在编译阶段会根据注解自动生成对应的方法;data包含get/set/hashCode/equals/toString等方法
@Data
public class User {

    private Long id;

    private String userName;

    private String password;

    private String name;

    private Integer age;

    private Integer sex;

    private Date birthday;

    private String note;

    private Date created;

    private Date updated;

}

整合SpringMVC

接下来我们来带着目的去学习

Spring端口和静态资源

目标:可以修改tomcat的端口和访问项目中的静态资源

分析

  • 修改tomcat端口
    查询**Properties,设置配置项(前缀+类变量名)到application配置文件中

  • 访问项目中的静态资源
    静态资源放置的位置;放置静态资源并访问这些资源

修改端口

先来查看一下Properties


我们可以看到第一个就是port属性

在yml中修改

#tomcat端口
server:
  port: 80

重启服务器后控制台打印如下信息


地址栏输入 http://localhost/hello ,访问成功。

访问静态资源

再看一下静态资源存放位置
其实之前也说过,我们点看同一个文件夹下ResourceProperties



看到四个目录,可以存放静态资源。

默认的静态资源路径为:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public
只要静态资源放在这些目录中任何一个,SpringMVC都会帮我们处理。
我们习惯会把静态资源放在 classpath:/static/ 目录下。我们创建目录 static ,加入一些静态文件


然后分别去访问它们
http://localhost/test.js和http://localhost/nene.jpg
访问图片会报错404,我们去pom.xml添加依赖


    org.springframework.boot
    spring-boot-starter-thymeleaf

这样输入地址就可以访问了


注意:如果访问图片时候没有显示;也可以先将项目先clean再启动,或者创建 public、resources 文件夹,然后图片放置到public或resources中。
但我觉得太麻烦,以后工作也不会用clean的方式

SpringMVC拦截器

目标:可以在Spring Boot项目中配置自定义SpringMVC拦截器

分析
编写拦截器(实现HandlerInterceptor);
编写配置类实现 WebMvcConfigurer,在该类中添加各种组件;
测试

拦截器也是我们经常需要使用的,在SpringBoot中该如何配置呢?
拦截器不是一个普通属性,而是一个类,所以就要用到java配置方式了。在SpringBoot官方文档中有这么一段说明:

If you want to keep Spring Boot MVC features and you want to add additional MVC configuration(interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc . If you wish to provide custom instances of RequestMappingHandlerMapping , RequestMappingHandlerAdapter , or ExceptionHandlerExceptionResolver , you can declare a WebMvcRegistrationsAdapter instance to provide such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc .

翻译:

如果你想要保持Spring Boot 的一些默认MVC特征,同时又想自定义一些MVC配置(包括:拦截器,格式化器, 视图控制器、消息转换器 等等),你应该让一个类实现 WebMvcConfigurer ,并且添加 @Configuration 注解,但是千万不要加 @EnableWebMvc 注解。如果你想要自定义 HandlerMapping 、 HandlerAdapter 、 ExceptionResolver 等组件,你可以创建一个 WebMvcRegistrationsAdapter 实例 来提供以上组件。如果你想要完全自定义SpringMVC,不保留SpringBoot提供的一切特征,你可以自己定义类并且添加@Configuration 注解和 @EnableWebMvc 注解

总结:通过实现 WebMvcConfigurer 并添加 @Configuration 注解来实现自定义部分
SpringMvc配置

编写拦截器

新建一个包interceptor

@Slf4j
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("这是MyInterceptor的preHandle");
        return true; // true才会放行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.debug("这是MyInterceptor的postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.debug("这是MyInterceptor的afterCompletion");

    }
}

虽然默认配置已经可以使用SpringMVC了,不过我们有时候需要进行自定义配置。
可以在 application.yml 文件中配置日志级别控制:

#日志记录级别
logging:
  level:
    org.example: debug
    org.springframework: info

编写配置类实现 WebMvcConfigurer,在该类中添加各种组件

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    //注册拦截器
    @Bean
    public MyInterceptor myInterceptor(){
        return new MyInterceptor();
    }

    //添加拦截器到spring mvc拦截器链
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor()).addPathPatterns("/*");
    }
}

重启服务器进行测试


小结

目录结构


jdbc事务和连接池

目标:配置Spring Boot自带默认的hikari数据库连接池和使用@Transactional注解进行事务配置

分析

  • 事务配置
    • 添加事务相关的启动器依赖,mysql相关依赖;
    • 编写业务类UserService使用事务注解@Transactional
  • 数据库连接池hikari配置
    只需要在application配置文件中指定数据库相关参数

spring中的jdbc连接和事务是配置中的重要一环,在SpringBoot中该如何处理呢?
答案是不需要处理,我们只要找到SpringBoot提供的启动器即可,在 pom.xml 文件中添加如下依赖:


            org.springframework.boot
            spring-boot-starter-jdbc
 

当然,不要忘了数据库驱动,SpringBoot并不知道我们用的什么数据库,这里我们选择MySQL;同样的在 pom.xml文件中添加如下依赖:

        
            mysql
            mysql-connector-java
            5.1.46
        

至于事务,SpringBoot中通过注解来控制。就是我们熟知的 @Transactional 。使用的时候设置在对应的类或方法上即可。
新建一个service,这里我们还没有新建mapper,所以先返回一个user好了

@Service
public class UserService {

    //根据id查询
    public User queryById(Long id){
        return new User();
    }

    //新增保存用户
    @Transactional
    public void saveUser(User user){
        System.out.println("新增用户... ");
    }
}

修改yml文件

#激活配置文件;需要制定其他的配置文件名称
spring:
  profiles:
    active: github,jianshu
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test
    username: root
    password: root

同时jdbcConfig类中也全部注释掉
同样的在HelloController类中打个断点



debug启动一下服务



可以看到数据库连接池已经不是druid了。

在刚才引入jdbc启动器的时候,SpringBoot已经自动帮我们引入了一个连接池


HikariCP应该是目前速度最快的连接池了,放心大胆用吧。

小结

事务配置;只需要添加jdbc启动器依赖
数据库连接池使用默认的hikari,在配置文件中配置如下:

整合mybatis

目标:配置Mybatis在Spring Boot工程中的整合包,设置mybatis的实体类别名,输出执行sql语句配置项

分析

  1. 添加启动器依赖;
  2. 配置Mybatis:实体类别名包,日志,映射文件等;
  3. 配置MapperScan

spring boot没有对mybatis进行整合,所以我们要手动添加依赖

 
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.0.1
        

配置 application.yml ,常用配置如下:

# mybatis配置
mybatis:
  # 实体类别名包路径
  type-aliases-package: org.example.pojo
  # 映射文件路径
  # mapper-locations: classpath:mappers/*.xml
  configuration:
  # 控制台输出执行sql
    log-impl: org.apache.ibatis.logging.stdout.StdOutImplv

最后配置mapper扫描

需要注意,这里没有配置mapper接口扫描包,因此我们需要给每一个Mapper接口添加 @Mapper 注解,才能被识别。
@Mapper
public class UserMapper {
}
或者,我们也可以不加注解,而是在启动类上添加扫描包注解,我们推荐这种方式

@SpringBootApplication
//扫描mybatis所有的业务mapper接口
@MapperScan("org.example.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

通用mapper

通用mapper是国人写的,可以实现自动拼接sql语句;所有的mapper都不需要编写任何方法也就是不用编写sql语句。可以提高开发效率。
目标:配置通用Mapper组件到Spring Boot项目中并使用Mapper接口

分析:

  1. 添加启动器依赖;
  2. 改造UserMapper继承Mapper;
  3. 修改启动引导类Application中的Mapper扫描注解;
  4. 修改User实体类添加jpa注解;
  5. 改造UserService实现业务功能;

添加启动器依赖;

通用Mapper的作者也为自己的插件编写了启动器,我们直接引入即可。在项目的 pom.xml 文件中加入如下依赖:

        
            tk.mybatis
            mapper-spring-boot-starter
            2.1.5
        

注意:一旦引入了通用Mapper的启动器,会覆盖Mybatis官方启动器的功能,因此需要移除对官方Mybatis启动器的依赖

改造UserMapper

注释掉@mapper,这是mybatis的

package org.example.mapper;

import org.example.pojo.User;
import tk.mybatis.mapper.common.Mapper;
//@Mapper
public interface UserMapper extends Mapper {
}

修改启动引导类Application中的Mapper扫描注解

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
//扫描mybatis所有的业务mapper接口
//@MapperScan("org.example.mapper")
@MapperScan("org.example.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

修改User实体类添加jpa注解

主键回填,当我们插入一条数据以后,插入完后它会将数据库的主键值回填到你刚才插入的数据中。

//在编译阶段会根据注解自动生成对应的方法;data包含get/set/hashCode/equals/toString等方法
@Data
@Table(name = "tb_user")
public class User {
    @Id
    //主键回填
    @KeySql(useGeneratedKeys = true)
    private Long id;
    //@Column
    //user_name-->userName
    private String userName;

    private String password;

    private String name;

    private Integer age;

    private Integer sex;

    private Date birthday;

    private String note;

    private Date created;

    private Date updated;

}

@Column可以不加,只要你的数据库的列名能和你的类属性对的上,支持驼峰和下划线的转换。

对 UserService 的代码进行简单改造

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    //根据id查询
    public User queryById(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }

    //新增保存用户
    @Transactional
    public void saveUser(User user) {
        System.out.println("新增用户... ");
        //选择性新增,如果属性为空,则该属性不会出现在insert语句上
        userMapper.insertSelective(user);
    }
}

注意:
在启动引导类上面的mapper扫描注解 一定要修改为 通用mapper的扫描注解

整合测试

目标:可以访问处理器对应路径将数据库中的数据根据id查询

分析

改造HelloController,注入UserService利用其方法实现查询;
启动项目进行测试 http://localhost/user/用户id --> http://localhost/user/1

    @Autowired
    private UserService userService;

    /**
     * 根据用户id查询用户
     * @param id 用户id
     * @return 用户
     */
    @GetMapping("/user/{id}")
    public User queryById(@PathVariable long id){
        return userService.queryById(id);
    }

整合Junit

目标:在Spring Boot项目中使用Junit进行单元测试UserService的方法

分析

添加启动器依赖spring-boot-starter-test;
编写测试类

添加依赖


            org.springframework.boot
            spring-boot-starter-test
        

UserService类名称上按cmd+shift+t



两个方法都勾选上


测试类加两个注解
@RunWith(SpringRunner.class)
@SpringBootTest

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private  UserService userService;

    @Test
    public void queryById() {
        User user = userService.queryById(1L);
        System.out.println("user = " + user);
    }

    @Test
    public void saveUser() {
        User user = new User();
        user.setUserName("test2");
        user.setName("test2");
        user.setAge(13);
        user.setPassword("123456");
        user.setSex(1);
        user.setCreated(new Date());
        userService.saveUser(user);
    }
}

小结

在Spring Boot项目中如果编写测试类则必须要在类上面添加@SpringBootTest

整合redis

参考之前写的两篇
https://www.jianshu.com/p/299580dd37c8
https://www.jianshu.com/p/1ab84ccf6244

目标:在Spring Boot项目中使用Junit测试RedisTemplate的使用

分析

添加启动器依赖;spring-boot-starter-data-redis
配置application.yml中修改redis的连接参数;(redis需要启动)
编写测试类应用RedisTemplate操作redis中的5种数据类型(string/hash/list/set/sorted set)

添加依赖

        
            org.springframework.boot
            spring-boot-starter-data-redis
        

修改yml文件

spring:
  profiles:
    active: github,jianshu
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test
    username: root
    password: root
  redis:
    host: localhost
    port: 6379

新建一个redisTest测试类测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class redisTest {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void test(){
        //string 字符串
//        redisTemplate.opsForValue().set("str", "abboo");
        redisTemplate.boundValueOps("str").set("abboo");
        System.out.println("str = " + redisTemplate.opsForValue().get("str"));

        //hash 散列
        redisTemplate.boundHashOps("h_key").put("name", "abboo");
        redisTemplate.boundHashOps("h_key").put("age", 13);
        //获取所有域
        Set set = redisTemplate.boundHashOps("h_key").keys();
        System.out.println(" hash散列的所有域:" + set);
        //获取所有值
        List list = redisTemplate.boundHashOps("h_key").values();
        System.out.println(" hash散列的所有域的值:" + list);

        //list 列表
        redisTemplate.boundListOps("l_key").leftPush("c");
        redisTemplate.boundListOps("l_key").leftPush("b");
        redisTemplate.boundListOps("l_key").leftPush("a");
        //获取全部元素
        list = redisTemplate.boundListOps("l_key").range(0, -1);
        System.out.println(" list列表中的所有元素:" + list);

        // set 集合
        redisTemplate.boundSetOps("s_key").add("a", "b", "c");
        set = redisTemplate.boundSetOps("s_key").members();
        System.out.println(" set集合中的所有元素:" + set);

        // sorted set 有序集合
        redisTemplate.boundZSetOps("z_key").add("a", 30);
        redisTemplate.boundZSetOps("z_key").add("b", 20);
        redisTemplate.boundZSetOps("z_key").add("c", 10);
        set = redisTemplate.boundZSetOps("z_key").range(0, -1);
        System.out.println(" zset有序集合中的所有元素:" + set);
    }
}

Spring Boot项目部署

目标:将Spring Boot项目使用maven指令打成jar包并运行测试

分析

  1. 需要添加打包组件将项目中的资源、配置、依赖包打到一个jar包中;可以使用maven的package;

  2. 部署:java -jar 包名

  3. 添加项目的pom.xml插件;在pom.xml要显式的加入插件spring-boot-maven-plugin,否则无法产生 jar 清单
    文件,导致打出来的 jar 无法使用命令运行;


        
           
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    
  1. 使用maven的命令package打包;



    之后在项目下的 target 目录中将有如下jar包:


运行打出来的包;使用命令: java –jar 包全名 或
命令行下

![image.png](https://upload-images.jianshu.io/upload_images/14301043-e4be56b4526315e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

此时浏览器输入
http://localhost/user/1
还是可以运行的

插件安装

在应用spring boot工程的时候;一般情况下都需要创建启动引导类 Application.java 和 application.yml 配置文件,而且内容都是一样的;为了便捷可以安装一个IDEA的插件 JBLSpringBootAppGen 在项目上右击之后可以自动生成启动引导类Application.java和application.yml配置文件。

安装完之后在IDEA中任意一个maven项目或src目录上 右击,选择 JBLSpringBootAppGen 即可。

思维导图

你可能感兴趣的:(【Spring Boot】简单实践)