zoukankan      html  css  js  c++  java
  • springboot整合mybatis

    springboot整合mybatis

    使用idea开发工具进行测试

    对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。

    Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。

    Sping Data 官网:https://spring.io/projects/spring-data

    1.准备数据库表

    例如 user表:

    字段名 类型 描述
    id int 主键自增
    username varchar(32) 用户名
    password varchar(32) 密码
    email varchar(32) 邮箱

    数据N条

    2.创建springboot项目, 导入依赖如下:

    主要导入上述三个即可, 其余自愿

    3.创建实体类

    com.aaron.pojo.User

    以下三个注解包括了setter, getter, toString和有参无参构造(lombok)

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private Integer id;
        private String username;
        private String password;
        private String email;
    }
    

    4. 创建mapper接口

    com.aaron.dao.UserMapper

    注意, 如果不想加@Mapper注解, 可以在启动类上加@MapperScan("com.jt.demo.mapper"). 参数为指定dao接口的包, 他就会自动扫描包下的接口

    @Mapper
    // @Repository
    public interface UserMapper {
        
        // 查询所有数据
        List<User> findAll();
        
        // 删除多条数据
        int deleteObjects(@Param("ids") Integer ...ids);
    }
    

    5. 创建mapper配置文件

    resource/mapper/UserMapper.xml

    <?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.aaron.dao.UserMapper">
        <!-- 查询所有数据 -->
        <select id="findAll" resultType="com.aaron.pojo.User">
        	select * from user;
        </select>
        
        <!-- 删除的时候尽量防止误删, 如果写的代码不当可能会删除重要数据
     		一般也很少写删除业务, 经常使用更改状态来(假)删除数据
    	-->
        <delete id="deleteObjects">
    		delete from user
    		<where>
    			<if test="ids != null and ids.length != 0">
    				id in 
    				<foreach collection="ids" 
    					open="(" close=")" item="id" separator=",">
    						#{id}
    				</foreach>
    			</if>
    			or 1 = 2;
    		</where>
    	</delete>
    </mapper>
    

    6. 编写测试文件

    6.1. yal或yaml格式配置文件

    resource/application.yaml

    如果需要配置其他连接池, 可以使用spring.datasource.type进行配置

    # 数据源
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
        username: root
        password: 123456
    
    # *mapper.xml文件扫描
    mybatis:
      mapper-locations: classpath:mapper/*.xml
    
    # 打印sql语句
    logging:
      level:
        com:
          cy=DEBUG
    

    我们配置了spring.datasource.type这个属性之后, 使用的默认连接池是hikari, 因为它性能非常好

    我们就可以获取数据路的连接了, 例如:

    // 注入连接池对象, 默认id为dataSource
    @Autowired
    private DataSource dataSource;
    

    我们可以调用dataSource.getConnection()来获取jdbc的连接

    6.2 properties文件格式配置

    resource/application.properties

    注意: url上需要加上时区设置: serverTimezone=GMT%2B8

    如果需要配置其他连接池, 可以使用spring.datasource.type进行配置

    # 数据源
    spring.datasource.url: jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
    spring.datasource.username: root
    spring.datasource.password: 123456
    
    # *mapper.xml文件扫描
    mybatis.mapper-locations: classpath:mapper/*.xml
    
    # 打印sql语句
    logging.level.com.cy=DEBUG
    

    7.进行测试

    @SpringBootTest
    class MybootdemoApplicationTests {
        
        @Autowired
        private UserMapper userMapper;
    
        @Test
        void text1() {
            List<User> users = userMapper.findAll();
            for (User user : users) {
                System.out.println(user);
            }
            
            System.out.println("删除了" + userMapper.deleteByIds(1, 2) + "条数据");
        }
    }
    

    运行结果:

    User(id=1, username=root, password=123, email=112233@qq.com)
    User(id=2, username=sys, password=456, email=445566@qq.com)
    删除了2条数据
    

    完美!

    扩展: mybatis查询手动优化

    可以手动创建个map对象当做缓存池, 用来存储第一次查询出来的数据, 之后无序再从数据库查询, 直接从池中取数据

    假设这是service中的实现类

    // 缓存池
    private Map<Object, Object> cache = new HashMap<>();
    
    @Override
    public List<Goods> findObjects() {
        // 开始计时
        long start = System.currentTimeMillis();
        // 先从池中取数据
        List<Goods> list = (List<Goods>)cache.get("goodsKey");
        // 判定池中是否有数据, 有数据则跳过此判定
        if (list == null) {
            // 池中没有数据, 从数据库中查询, 然后放到池中
            list = goodsDao.findGoods();
            cache.put("goodsKey", list);
        }
        // 计时结束
        long end = System.currentTimeMillis();
        // 打印时间信息
        System.out.println("findObjects.time = " + (end - start));
        return list;
    }
    

    但是这样做有个缺点, 就是新增数据后, 可能还是从缓存池中取到的之前数据

    扩展: 整合Druid第三方连接池

    Druid简介

    Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。

    Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。

    Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。

    Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

    Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,我们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。

    Github地址:https://github.com/alibaba/druid/

    官方帮助文档: https://github.com/alibaba/druid/wiki/常见问题

    pom依赖

    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.21</version>
    </dependency>
    

    DruidDataSource配置参数

    com.alibaba.druid.pool.DruidDataSource

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

    切换数据源

    主要是spring.datasource.type的属性要指定自定义的数据源 yaml文件格式参考

    
    spring:
      datasource:
        username: root
        password: 123456
        url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
        driver-class-name: com.mysql.cj.jdbc.Driver
        # 自定义数据源
        type: com.alibaba.druid.pool.DruidDataSource
        
        #Spring Boot 默认是不注入这些属性值的,需要自己绑定
        #druid 数据源专有配置
        initialSize: 5
        minIdle: 5
        maxActive: 20
        # ...等等配置
    

    官方配置参考

    https://github.com/alibaba/druid/wiki/DruidDataSource配置

    配置数据监控

    ssm或servlet可参考官方文档

    https://github.com/alibaba/druid/wiki/配置_StatViewServlet配置

    Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看,类似安装 路由器 时,人家也提供了一个默认的 web 页面。所以页面我们也无需编写.

    所以第一步需要设置 Druid 的后台管理页面,比如 登录账号、密码 等;配置后台管理;

    //配置 Druid 监控管理后台的Servlet;
    //内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
    
        // 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet 
        // 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到
        Map<String, String> initParams = new HashMap<>();
        initParams.put("loginUsername", "admin"); //后台管理界面的登录账号
        initParams.put("loginPassword", "123456"); //后台管理界面的登录密码
    
        //后台允许谁可以访问
        //initParams.put("allow", "localhost"):表示只有本机可以访问
        //initParams.put("allow", ""):为空或者为null时,表示允许所有访问
        initParams.put("allow", "");
        //deny:Druid 后台拒绝谁访问
        //initParams.put("kuangshen", "192.168.1.20");表示禁止此ip访问
    
        //设置初始化参数
        bean.setInitParameters(initParams);
        return bean;
    }
    

    配置完毕后,我们可以选择访问 :http://localhost:8080/druid/login.html

    然后就会显示输入用户名和密码, 输入我们上面配置的即可

    配置 Druid web 监控 filter 过滤器

    //配置 Druid 监控 之  web 监控的 filter
    //WebStatFilter:用于配置Web和Druid数据源之间的管理关联监控统计
    @Bean
    public FilterRegistrationBean webStatFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
    
        //exclusions:设置哪些请求进行过滤排除掉,从而不进行统计
        Map<String, String> initParams = new HashMap<>();
        initParams.put("exclusions", "*.js,*.css,/druid/*,/jdbc/*");
        bean.setInitParameters(initParams);
    
        //"/*" 表示过滤所有请求
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
    

    平时在工作中,按需求进行配置即可,主要用作监控!

  • 相关阅读:
    2020年. NET Core面试题
    java Context namespace element 'component-scan' and its parser class ComponentScanBeanDefinitionParser are only available on JDK 1.5 and higher 解决方法
    vue 淡入淡出组件
    java http的get、post、post json参数的方法
    vue 父子组件通讯案例
    Vue 生产环境解决跨域问题
    npm run ERR! code ELIFECYCLE
    Android Studio 生成apk 出现 :error_prone_annotations.jar (com.google.errorprone:error) 错误
    记忆解析者芜青【总集】
    LwIP应用开发笔记之十:LwIP带操作系统基本移植
  • 原文地址:https://www.cnblogs.com/zpKang/p/13224246.html
Copyright © 2011-2022 走看看