Spring Boot3(注册Servlet三大组件 切换Servlet容器 SpringBoot 数据访问操作 整合Mybatis与Mybatis-Plus 切换druid数据源)

目录

一、注册Servlet三大组件 Servlet/Filter/Listener

二、切换为其他嵌入式Servlet容器 

三、SpringBoot 数据访问操作 

四、SpringBoot整合Mybatis与Mybatis-Plus

1. SpringBoot整合Mybatis

总结

2. SpringBoot整合Mybatis-Plus

新增

修改id

​编辑​编辑修改name

​编辑​编辑查询ID

​编辑查询IDS

​编辑查询count

​编辑查询list

分页

​编辑逻辑删除

总结

五、SpringBoot切换druid数据源 

1. DRUID配置参数 

2. Druid监控平台

总结


一、注册Servlet三大组件 Servlet/Filter/Listener

首先使用传统 @WebFilter...实现注册

条件:

  • 1.一定是自定义组件
  • 2.启动类添加@ServletComponentScan

MyServlet.class

@WebServlet("/myServlet")
public class MyServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入servlet");
        resp.getWriter().println("<h1>hello</h1>");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
}

MyFilter.class

@WebFilter(urlPatterns = {"/*"})
public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("============请求过滤");

        servletRequest.setCharacterEncoding("utf-8");
        //分水岭
        filterChain.doFilter(servletRequest, servletResponse);

        servletResponse.setCharacterEncoding("utf-8");

        System.out.println("============响应过滤");
    }
}

MyListener.class

@WebListener
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContextListener.super.contextInitialized(sce);
        System.out.println("-------------MyListener inited !");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        ServletContextListener.super.contextDestroyed(sce);
        System.out.println("----------------MyListener Destroy !");
    }
}

访问该页面


而由于 Spring Boot 默认是以 jar 包的方式运行嵌入式Servlet容器来启动应用,没有web.xml文件, Spring提供以下Bean来注册三大组件

  • ServletRegistrationBean 注册自定义Servlet
  • FilterRegistrationBean 注册自定义Filter
  • ServletListenerRegistrationBean 注册自定义Listener

在上面的基础上 自定义类的注解就不需要了 统一写在配置类里

MyMvcConfig.class

@Configuration
public class MyMvcConfig {
    //注册Servlet
    //替换:@WebServlet(urlPatterns = "/myServlet")
    @Bean
    public ServletRegistrationBean doServlet() {
        ServletRegistrationBean<MyServlet> bean = new ServletRegistrationBean<MyServlet>();
        bean.setServlet(new MyServlet());
        bean.setUrlMappings(Arrays.asList("/myServlet"));
        bean.setLoadOnStartup(1);
        return bean;
    }


    //注册Filter
    @Bean
    public FilterRegistrationBean doFilter(){
        FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new MyFilter());
        filter.addUrlPatterns("/*");
        return filter;
    }

    //注册Listener
    @Bean
    public ServletListenerRegistrationBean doListener(){
        //关闭监听器切记不要直接点击红色按钮,太暴力,点击控制台左侧exist
        ServletListenerRegistrationBean listener = new ServletListenerRegistrationBean();
        listener.setListener(new MyListener());
        return listener;
    }
}

二、切换为其他嵌入式Servlet容器 

SpringBoot 默认针对Servlet容器提供以下支持:

  • Tomcat(默认使用)
  • Jetty :支持长连接项目(如:聊天页面)[ˈdʒeti]
  • Undertow : 不支持 JSP , 但是并发性能高,是高性能非阻塞的容器[ˈʌndətəʊ]

默认Tomcat容器

在spring-boot-starter-web启动器中默认引入了tomcat容器   
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-tomcat</artifactId>
 <version>2.1.0.RELEASE</version>
 <scope>compile</scope>
 </dependency

切换 Jetty 容器

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除坐标 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入其他的Servlet容器 -->
<dependency>
<artifactId>spring-boot-starter-jetty</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>

可以在运行日志里面看到更改成功使用外置Servlet容器Tomcat9.x

嵌入式Servlet容器:运行启动类就可启动,或将项目打成可执行的 jar 包

  • 优点:简单、快捷;
  • 缺点:默认不支持JSP、优化定制比较复杂使用定制器, 还需要知道 每个功能的底层原理

外置Servlet容器:配置 Tomcat, 将项目部署到Tomcat中运行

三、SpringBoot 数据访问操作 

四、SpringBoot整合Mybatis与Mybatis-Plus

1. SpringBoot整合Mybatis

步骤①:创建模块时勾选要使用的技术,MyBatis,由于要操作数据库,还要勾选对应数据库。

导入坐标

<dependencies>
  <!--1.导入对应的starter-->
  <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
  </dependency>

  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
  </dependency>
</dependencies>

步骤②:配置数据源相关信息,没有这个信息你连接哪个数据库都不知道

配置yml文件

#数据源
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/javaee2404?serverTimezone=GMT
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis:
  configuration:
    map-underscore-to-camel-case: true   #自动驼峰映射
  type-aliases-package: com.zkt.pojo  #起别名
#javaBean         db
#stuId            stu_id
#stuName          stu_name

SpringBoot把配置中所有可能出现的通用配置都简化了。下面就可以写一下MyBatis程序运行需要的Dao(或者Mapper)就可以运行了

这里使用一个插件 lombok

点击settings -》plugins 搜索lombok

安装即可 也可以在官网自己下载 Lombok - IntelliJ IDEs Plugin | Marketplace

然后在pom.xml 中导入坐标即可

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

然后就是使用他的注解了

实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("student")
public class Student implements Serializable {
    @TableId(value = "stu_id",type = IdType.AUTO)
    private int studId;
    @TableField("stu_name")
    private  String stuName;
    @TableField("stu_nick")
    private String stuNick;
    @TableField("stu_hobby")
    private String stuHobby;
    @TableLogic(value = "0",delval = "1")
    private int isdeleted;

    @TableField(exist = false)
    private MultipartFile pic;

    public Student(String stuName, String stuNick, String stuHobby) {
        this.stuName = stuName;
        this.stuNick = stuNick;
        this.stuHobby = stuHobby;
    }
}

@Data 代表的是get set 方法

@NoArgsConstructor @AllArgsConstructor是无参构造 和有参构造

@TableId(value = "stu_id",type = IdType.AUTO) 这个是主键 同时自增

TableField("stu_name") 属性映射 

数据库对应字段

映射接口(Dao)

@Mapper//逐个注入
public interface StudentMapper extends BaseMapper<Student> {
    @Select("select * from student ")
    public List<Student> findAll();
}

测试类

@SpringBootTest
public class Test01 {
    @Autowired(required = false)
    StudentMapper mapper;

    //mybatis
    @Test
    void contextLoads() {
        List<Student> list = mapper.findAll();
        for (int i = 0; i < list.size(); i++) {
            Student student = list.get(i);
            System.out.println(student);
        }
    }
}

注意:当前使用的SpringBoot版本是2.5.4,对应的坐标设置中Mysql驱动使用的是8x版本。当SpringBoot2.4.3(不含)版本之前会出现一个小BUG,就是MySQL驱动升级到8以后要求强制配置时区,如果不设置会出问题。解决方案很简单,驱动url上面添加上对应设置就行了

此外在运行程序时还会给出一个提示,说数据库驱动过时的警告,根据提示修改配置即可,弃用com.mysql.jdbc.Driver,换用com.mysql.cj.jdbc.Driver。前面的例子中已经更换了驱动了,在此说明一下。

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

总结

  1. 整合操作需要勾选MyBatis技术,也就是导入MyBatis对应的starter
  2. 数据库连接相关信息转换成配置
  3. 数据库SQL映射需要添加@Mapper被容器识别到
  4. MySQL 8.X驱动强制要求设置时区
    • 修改url,添加serverTimezone设定
    • 修改MySQL数据库配置
  1. 驱动类过时,提醒更换为com.mysql.cj.jdbc.Driver

2. SpringBoot整合Mybatis-Plus

整合究竟哪些是核心?总结下来就两句话

  • 导入对应技术的starter坐标
  • 根据对应技术的要求做配置

接下来在MyBatis的基础上再升级一下,整合MyBaitsPlus(简称MP)

步骤①:导入对应的starter 导入坐标 同时将mybatis注掉

 <!-- mybatis+mp -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>

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

步骤②:配置数据源相关信息 配置yml

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true #自动驼峰映射(默认开启)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #日志

剩下的就是写MyBaitsPlus的程序了

映射接口(Dao)

@Mapper//逐个注入
public interface StudentMapper extends BaseMapper<Student> {
    @Select("select * from student ")
    public List<Student> findAll();
}

核心在于Dao接口继承了一个BaseMapper的接口,这个接口中帮助开发者预定了若干个常用的API接口,简化了通用API接口的开发工作。

测试类

新增

/**
 * @author zkt
 * @Version 1.0
 * @since 2024/7/20
 */
@SpringBootTest
public class Test02 {
    @Autowired(required = false)
    StudentMapper mapper;

    //新增
    @Test
    public void show1() {
        Student student = new Student("zkt2", "god", "sleep");
        int row = mapper.insert(student);
        System.out.println("主键回填id" + student.getStudId());
        System.out.println("影响行数" + row);
    }
}

 
 

修改id

//修改ID
    @Test
    public void test02() {
        Student stu = new Student();
        stu.setStudId(3);
        stu.setStuHobby("网抑云");
        int row = mapper.updateById(stu);
        System.out.println("影响行数" + row);
    }

修改name

//修改Name
    @Test
    public void test03() {
        //修改数据
        Student stu = new Student();
        stu.setStuHobby("撸铁");
        //创建条件
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.eq("stu_name", "zkt");
        int row = mapper.update(stu, wrapper);
        System.out.println("影响行数" + row);
    }

查询ID

//查询ID
    @Test
    public void test04() {
        Student student = mapper.selectById(2);
        System.out.println(student);
    }

查询IDS

//查询IDS
    @Test
    public void test05() throws Exception {
        List<Student> list = mapper.selectBatchIds(Arrays.asList(1, 3));
        for (int i = 0; i < list.size(); i++) {
            Student student = list.get(i);
            System.out.println(student);
        }
    }

查询count

 //查询count
    @Test
    public void test06(){
        Integer count = mapper.selectCount(null);
        System.out.println(count);
    }

查询list

//查询list
    @Test
    public void test07(){
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stu_name","zkt").or().eq("stu_hobby","撸铁");
        List<Student> list = mapper.selectList(queryWrapper);
        for (int i = 0; i <list.size() ; i++) {
            Student student = list.get(i);
            System.out.println(student);
        }
    }

分页

/**
     * mp分页使用
     * 注意:
     * 1.page.setCurrent(2);当前页码从1开始
     * 2.分页需要配置插件
     * */
    @Test
    public void test08(){

        //1.定义分页规则
        Page<Student> page = new Page<>();
        page.setSize(2);//每页记录数
        page.setCurrent(1);//当前页码

        //2.查询条件(可选)
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("stu_sex","man");

        //这里没有选条件 因为表中数据太少了 只为了测试
        Page<Student> iPage = mapper.selectPage(page, null);
        List<Student> list = iPage.getRecords();//分页结果
        System.out.println("总记录数"+iPage.getTotal());
        System.out.println("总记页数"+iPage.getPages());

        for (int i = 0; i <list.size() ; i++) {
            Student student = list.get(i);
            System.out.println(student);
        }
    }

逻辑删除

 /**
     * 物理删除:业务数据从数据库中丢弃,执行的是delete操作
     * 逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,
     *         数据保留在数据库中,执行的是update操作
     *         实现步骤:
     *          步骤1:修改数据库表添加`deleted`列,比如`0`代表正常,`1`代表删除,可以在添加列的同时设置其默认值为`0`正常。
     *          步骤2:实体类添加属性以及注解
     *          @TableLogic(value="0",delval="1")
     *          private Integer deleted;
     *              value为正常数据的值,delval为删除数据的值
     * */

    //逻辑删除
    @Test
    public void test09(){
        int row = mapper.deleteById(4);
        System.out.println("影响行数" + row);
    }

这个时候如果使用mybatis 查询 还在如果使用mp查询的话 会自带条件查询 不在

 @Test
    public void test10(){
        List<Student> list = mapper.selectList(null);
//        System.out.println(list);
        for (int i = 0; i <list.size() ; i++) {
            Student student = list.get(i);
            System.out.println(student);
        }
    }

总结

==================mybatis-plus===================
步骤:
    1.坐标     

   <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.1.1</version>
         </dependency>

  注意:mp坐标添加后,mybatis坐标移除
2.编写注解配置实体类与关系表映射关系(truncate清空表以及主键)
        @TableName(value = "关联表名称")=========================》修饰在类
        @TableField(value = "关联字段名称")======================》修饰在属性
                    exist = "忽略字段"
        @TableId(type="指定主键生成策略,默认雪花算法")=============》修饰在属性
                    AUTO(0),
                    NONE(1),
                    INPUT(2),
                    ASSIGN_ID(3),
                    ASSIGN_UUID(4);


3.使用
        BaseMapper===========》公共的数据访问层
        IService/ServiceImp==》公共的业务层

五、SpringBoot切换druid数据源 

        前面整合MyBatis和MP的时候,使用的数据源对象都是SpringBoot默认的数据源对象,下面我们手工控制一下,自己指定了一个数据源对象,Druid。

在没有指定数据源时,我们的配置如下:

#数据源
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/javaee2404?serverTimezone=GMT
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

此时虽然没有指定数据源,但是根据SpringBoot默认使用了HiKari

更换数据源,只需要两步

  1. 导入对应的技术坐标
  2. 配置使用指定的数据源类型

下面就切换一下数据源对象

步骤①:导入对应的坐标(注意,是坐标,此处不是starter)

<!-- druid坐标 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>

步骤②:修改配置,在数据源配置中有一个type属性,专用于指定数据源类型

#数据源
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/javaee2404?serverTimezone=GMT
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    filters: stat,wall

测试切换成功

1. DRUID配置参数 

配置缺省值说明
name配置这个属性的意义在于,在存在多个数据源、监控的时候可以通过名字来区分开。如果没有配置,将会生成一个名字,格式是:“DataSource-”+ System.identityHashCode(this)
jdbcUrl连接数据库的url,不同数据库不一样,例如:mysql:jdbc:mysql://10.20.153.43:306/druid2 oracle:jdbc:oracle:thin:@10.20.149.85:152:ocnauto
username连接数据库的用户名
password连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter,详细看这里:http://git.hub.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter
driverClassName根据url自动识别这一项可配可不配。如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassNam(建议配置下)
initialSize0初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive8最大连接池数量
maxIdle8已经不再使用。配置了也没效果
minIdle最小连接池数量
maxWait获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降。如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
poolPreparedStatementsfalse是否缓存PreparedStatement,也就是PSCache。PSCache对支持持游标的数据库性能能提升巨大,比如说Oracle,在mysql下建议关闭。
maxOpenPreparedStatements-1要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
validationQuery用来检测连接是否有效的sql,要求是一个查询语句,如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
testOnBorrowtrue申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturnfalse归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testWhileIdlefalse建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测是否有效。
timeBetweenEvictionRunsMillis有二个含义:1) Destroy线程会检测连接的间隔时间2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
numTestsPerEvictionRun不再使用,一个DruidDataSource只支持一个EvictionRun
minEvictableIdleTimeMillisconnectionInitSqls物理连接初始化的时候执行的sql
exceptionSorter根据dbType自动识别当数据库抛出一些不可恢复的异常时,抛弃连接
filters监控统计用的filter:stat日志用的filter:log4j防护注入的filter:wall
proxyFilters类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

2. Druid监控平台

@Configuration
public class DruidConfig {

    //1.注入数据源
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource(){
        return new DruidDataSource();
    }

    //2.配置servlet
    @Bean
    public ServletRegistrationBean registrationBean(){
        //1.创建servlet注册类
        ServletRegistrationBean<StatViewServlet>  servletRegistrationBean =  new ServletRegistrationBean<StatViewServlet>();
        //2.创建制作页面的servlet
        StatViewServlet statViewServlet = new StatViewServlet();
        //3.绑定servlet
        servletRegistrationBean.setServlet(statViewServlet);
        servletRegistrationBean.setUrlMappings(Arrays.asList("/druid/*"));
        //4.参数绑定
        Map<String,String> maps = new HashMap<String,String>();
        maps.put(StatViewServlet.PARAM_NAME_USERNAME,"admin");
        maps.put(StatViewServlet.PARAM_NAME_PASSWORD,"123");
        maps.put(StatViewServlet.PARAM_NAME_ALLOW,"");//白名单
        maps.put(StatViewServlet.PARAM_NAME_DENY,"192.168.0.12");//黑名单
        servletRegistrationBean.setInitParameters(maps);

        return servletRegistrationBean;
    }

    //3.配置filter
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){

        FilterRegistrationBean<WebStatFilter> bean = new FilterRegistrationBean<WebStatFilter>();
        bean.setFilter(new WebStatFilter());
        //所有请求进行监控处理
        bean.setUrlPatterns(Arrays.asList("/*"));

        Map<String, String> initPrams = new HashMap<>();
        //添加不需要忽略的格式信息
        initPrams.put(WebStatFilter.PARAM_NAME_EXCLUSIONS, "*.js,*.css,/druid/*");
        bean.setInitParameters(initPrams);

        return bean;
    }

总结

 ======》数据源切换
1.加坐标
2.做配置 

  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冯诺依曼转世

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

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

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

打赏作者

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

抵扣说明:

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

余额充值