Spring Boot(学习记录Servlet和JDBC、单元测试、断言)

源生的Servlet、Listener、Filter:
首先需要一个@WebServlet注解然后再SpringBootapplication注解上加上@ServletComponentScan(basePackages = "cqupt.boot")//将servlet扫描进去这个注解(这个对于下面的监听器和过滤器同理),这两个一起用就达到源生servlet的效果了。

@WebServlet(urlPatterns = "/my")//servlet的访问地址
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("666");
    }
}

Filter

@Slf4j
@WebFilter(urlPatterns = {"/css/*","/images/*"})//过滤器 servlet是单星写法,双星是spring写法
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyFilter初始化完成");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter工作");
    }

    @Override
    public void destroy() {
        log.info("MyFilter销毁");
    }
}

Listener

@Slf4j
@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("监听到项目初始化完成");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("监听到项目销毁");
    }
}

可以将以上的注解都不要,通过配置Configuration来往容器中添加组件来实现。

//proxyBeanMethods =true  保证依赖的组件始终是单实例的
@Configuration
public class MyRegisterConfig {
//    //注册Servlet
    @Bean
    public ServletRegistrationBean myServlet(){
        MyServlet myservlet=new MyServlet();
        return new ServletRegistrationBean(myservlet,"/my","/my2");
    }
    @Bean
    public FilterRegistrationBean myListener(){
        MyFilter myFilter=new MyFilter();
        FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/my2"));
        return filterRegistrationBean;
//        return new FilterRegistrationBean(myFilter,myServlet());//拦截myServlet的路径,他是啥路径就拦截什么
    }
    @Bean
    public ServletListenerRegistrationBean mylistener(){
        MyServletContextListener myServletContextListener=new MyServletContextListener();
        return new ServletListenerRegistrationBean(myServletContextListener);
    }
}

数据库

数据库所需依赖添加。注意!!,虽然Spring Boot有版本仲裁,但是mysql的版本不要高于本机所安装的版本。
第一种直接引入依赖的具体版本。(利用的Maven的就近依赖原则)

<!--        jdbc开发-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
<!--        mysql数据库 本机是8.0.21-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>

第二种。
重新声明版本号,通过ctrl+spring-boot-starter-parent和ctrl+spring-boot-dependencies进去查看它的命名属性。例如mysql就是<mysql.version>8.0.21</mysql.version>,所以我们把这个重新声明即可。(利用的是Maven的就近优先原则)

		<properties>
			<mysql.version>8.0.21</mysql.version>
		</properties>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

Spring Boot底层配置了Hikari的。
在.yaml文件中配置。(mysql8.0以上)

# 配置数据库
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/xxxxxx?useSSL=false&serverTimezone=UTC
    username: xxxxxxx
    password: xxxxxxxx
    driver-class-name: com.mysql.cj.jdbc.Driver
    #开启sql监控和防火墙
    filters: stat,wall

测试是否与数据库连接上了,查询一下数据库中该表记录条数。

Long length= jdbcTemplate.queryForObject("select count(*) from city",Long.class);
System.out.println(length);

Druid

设置监控页面登录信息,监控Web的监控数据

@Configuration
public class MyDataSourceConfig implements WebMvcConfigurer {
    /**
     * 配置servlet的监控页
     * 添加监控页的登录信息
     * @return
     */
    @Bean
    public ServletRegistrationBean statViewServlet(){
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> servletRegistrationBean=
                new ServletRegistrationBean<StatViewServlet>(statViewServlet,"/druid/*");
        //添加登录页面的登录名和密码
        servletRegistrationBean.addInitParameter("loginUsername","syf");
        servletRegistrationBean.addInitParameter("loginPassword","123456");
        return servletRegistrationBean;
    }
    //给容器中放一个我们的数据源,以及配置属性
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource Druid() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        //开启监控功能 和 防火墙功能
//        druidDataSource.setFilters("stat,wall");
//        druidDataSource.setUsername("root");
//        druidDataSource.setPassword("19980605");
//        druidDataSource.setDriver(new Driver());
//        druidDataSource.setUrl("jdbc:mysql://localhost:3306/syfwfl?useSSL=false&serverTimezone=UTC");
        return druidDataSource;
    }
    /**
     * 配置WebStatFilter,用于采集web-jdbc关联监控的数据。
     * @return
     */
    @Bean
    public FilterRegistrationBean DruidWebStatFilter(){
        WebStatFilter webStatFilter=new WebStatFilter();
        FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(webStatFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}

servlet访问测试,访问界面为localhost:端口号/druid

    @Autowired
    JdbcTemplate jdbcTemplate;
    @ResponseBody//响应出去,就不跳转页面
    @GetMapping("/sql")
    public String sql(){
        Long length= jdbcTemplate.queryForObject("select count(*) from city",Long.class);
        assert length != null;
        return length.toString();
    }

以上都可在.yaml配置文件中设置,简化操作。

# 配置数据库
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/syfwfl?useSSL=false&serverTimezone=UTC
    username: root
    password: 19980605
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      #开启监控和防火墙
      filters: stat,wall # 底层开启功能,监控和防火墙
      #监控这个包下的所有东西
      aop-patterns: cqupt.boot.*  #监控SpringBean

      stat-view-servlet: #配置监控功能
        #默认是false所以需要自己打开
        enabled: true
        #监控页面的登录名和密码
        login-username: admin
        login-password: admin
        #重置按钮
        reset-enable: false

      web-stat-filter:  #监控web
        enabled: true
        url-pattern: /*
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"

      filter:
        stat: #对上面的filters详细配置
          #是否记录慢sql语句
          log-slow-sql: true
          slow-sql-millis: 1000
          enabled: true
        wall:  #对上面的filters详细配置
          enabled: true
          config:
            #相当于所有的更新数据库的操作全都会被拦截
            update-allow: false

整合Mybatis

1、引入依赖

    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot</artifactId>

2、编写mapper接口
3、编写sql映射文件并绑定mapper接口
4、在application.yaml指定mapper配置文件的位置,以及指定全局配置文件的信息(建议不写全局配置文件,直接在application.yaml的mybatis.configuration中配置)
注意:在实现里面加mapper的,在用到sql的地方加实现的@Autowire
可以通过注解也可以用mapper,混合使用。不用配置文件时,在方法上标注@Service
mapper

@Mapper
public interface CityMapper {
    @Select("select*from city where id=#{id}")
    @Option(useGeneratedKeys=true,keyProperty="id")//返回自增主键,相当于mapper里面的功能属性
    City Select(long id);
}

实现

@Service
public class CityImpl{
    @Autowired
    CityMapper cityMapper;
    public City Select(long id) {
        return cityMapper.Select(id);
    }
}

    @Autowired
    CityImpl city;

    @ResponseBody
    @RequestMapping("/acc")
    public City getById(@RequestParam("id")long id){
        return city.Select(id);
    }
#配置mybatis规则
mybatis:
#  config-location: classpath:mybatis/mybatis-config.xml   #全局配置文件位置
  mapper-locations: classpath:mybatis/mapper/*.xml        #sql映射文件位置
  #可以不写全局配置文件,所有的全局配置文件都放在configuration里面
  #configuration和上面的这两个不能同时存在
  configuration:
    map-underscore-to-camel-case: true

Redis

依赖

<!--        redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

redis的yaml文件配置

#redis
  redis:
    #redis连接设置 举例 user:用户名 password:密码  exacple.com:公网地址  63379:端口号
    url: redis://user:password@exacple.com:63379
    #不用上面的这种方式,还可以以这种方式
    host: exacple.com
    port: 63379
    password: user:password

单元测试

如果在测试单元标注了@Transactional标签,在测试完成后会自动回滚。在测试单元需要用到类,直接定义了之后@Autowire就行。

/**
 * SpringBootTest这个注解能让测试也拿到容器中的组件
 * ExtendWith(SpringExtension.class) 想用外部的
 */
@SpringBootTest
@DisplayName("junit5功能测试类")
public class Mytest {
    /**
     * @Disabled/ 使当前这个方法不运行
     *  @DisplayName 设置这个测试的名字
     */
    @Disabled
    @Test
    @DisplayName("测试DisplayName")
    void DisplayName(){
        System.out.println(1);
    }
    /**
     * 每个方法执行之前
     */
    @BeforeEach
    void testBeforeEach(){
        System.out.println("打印就要开始了");
    }
    /**
     * 每个方法执行完之后
     */
    @AfterEach
    void testAfterEach(){
        System.out.println("打印结束了");
    }
    /**
     * 所有执行完之前
     */
    @BeforeAll
    static void testBeforeAll(){
        System.out.println("所有都要开始了");
    }
    /**
     * 所有执行完之后
     */
    @AfterAll
    static void testAfterAll(){
        System.out.println("所有都要结束了");
    }
    /**
     * 规定方法超时间
     * @throws InterruptedException
     */
    @Timeout(value = 1000,unit = TimeUnit.MILLISECONDS)
    @Test
    void testTimeout() throws InterruptedException {
        Thread.sleep(1001);
    }

    /**
     * 重复测试5次
     */
    @RepeatedTest(5)
    @Test
    void testMany(){
        System.out.println("haha");
    }
}

断言测试

在这里插入图片描述

/**
     * 测试简单断言
     * 前面断言失败,后面的代码都不会实现
     */
    @Test
    @DisplayName("断言")
    void testSimpleAssertions(){
        int cal=jisuan(1,5);
        Assertions.assertEquals(6,cal,"业务逻辑失败");
        Object obj1=new Object();
        Object obj2=new Object();
        Assertions.assertEquals(obj1,obj2,"不是一个对象");
    }//模拟业务
    int jisuan(int i,int j){
        return i+j;
    }
    @Test
    @DisplayName("断言")
    void array(){
        Assertions.assertEquals(new int[]{1,2},new int[]{1,2},"数组不相同");
    }//模拟业务
    /**
     * 组合断言
     */
    @Test
    @DisplayName("组合断言")
    void All(){
        assertAll("test",()-> assertTrue(true&true),
                                 ()-> assertEquals(1,2));
    }
    /**
     * 异常断言
     */
    @Test
    @DisplayName("异常断言")
    void exception(){
        //断言要抛异常,成功断言了就没有异常,否则抛异常
       assertThrows(ArithmeticException.class,()->{int i=10/2;},"业务居然正常?");
    }
/**
 * 快速失败
 */
    @Test
    @DisplayName("快速失败")
    void testFail(){
        if (true)
            fail("测试失败");
    }

前置条件

    /**
     * 测试前置条件
     * 如果失败直接跳过当前要执行的
     */
    @DisplayName("测试假设是否为true")
    @Test
    void testassumption(){
        Assumptions.assumeTrue(false,"不为true");
        System.out.println("真的是");
    }

嵌套测试
外层的test不能驱动内层的BeforeEach/AfterEach还有all这种。
内层的test可以驱动外层的。
参数化测试

/**
     * 参数化测试
     * 直接给参数
     */
    @ParameterizedTest//表示当前为参数化测试
    @DisplayName("参数化测试")
    @ValueSource(ints = {1,2,3,4,5,6})//传值
    void testParameter(int num){
        System.out.print(num);
    }

    /**
     * 从方法中得到参数
     * @param num
     */
    @ParameterizedTest//表示当前为参数化测试
    @DisplayName("参数化测试")
    @MethodSource("stringProvider")//从方法中获得参数
    void testParameter2(String num){
        System.out.print(num);
    }

    static Stream<String> stringProvider(){
        return Stream.of("apple","banana","cqupt");
    }

Actuator

# actuator management是所有actuator的配置
# 访问路径 http://localhost:8081/actuator/*,改变*可以看相应的
# 例如:http://localhost:8081/actuator/beans
management:
  endpoints:
    enabled-by-default: true # 默认就是true
    web:
      exposure:
        #默认是info 和 health
        include: '*' # 以web方式暴露所有端点

Profile

可以选择对应的场景进行文件配置
在这里插入图片描述

server.port=8081
#激活生产环境,有同名项时,就看激活的配置文件里面的内容
#打包成jar包后还可以通过命令行修改
#java -jar xxx.jar --spring.profiles.active=test --person.name=haha就能直接修改启动
#spring.profiles.active=test  #指定这个配置文件生效 test为  application-test.yaml的-后面的内容
#也可以创组设定环境 每次启动就启动这个组别,以下就是启动myprod这个组,group后面那个为组名
spring.profiles.active=myprod
spring.profiles.group.myprod[0]=prod
spring.profiles.group.myprod[1]=syf
spring.profiles.group.mytest[0]=test

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
profile也可直接获取系统变量也是直接通过${}获得。
程序可通过这个代码查看:

        ConfigurableApplicationContext run = SpringApplication.run(ComBootProfileApplication.class, args);
        ConfigurableEnvironment environment=run.getEnvironment();
        Map<String,Object> systemEnvironment= environment.getSystemEnvironment();
        Map<String,Object> systemProperties= environment.getSystemProperties();
        System.out.println(systemEnvironment);
        System.out.println(systemProperties);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

syf_wfl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值