笔记
笔记
mrdoc网站使用教程
k8s
笔记2
JAVA
连接池
spring cloud
ribbon
Feign
Netflix
JAVA题库V1.0
MrDoc数据迁移
MrDoc删除自带广告
优秀的博客
书签
雪花特效
雪花特效1
雪花特效2
雪花特效3
飞花特效
妙笔生花js
常用网站
页面新型效果特效篇
粒子球特效
linux 三剑客
mrdoc 精简附件和图片目录
系统换源
-
+
首页
连接池
#### 00-企业级开发过程中通用后端处理 ##### 1.常见连接池介绍 HiKariCP和Druid 我们所熟知的C3P0,DBCP,Druid, HiKariCP为我们所常用的数据库连接池, 其中C3P0已经很久没有更新了。DBCP更新速度很慢,基本处于不活跃状态,而Druid和HikariCP处于活跃状态的更新中,这就是我们说的二代产品了。 ##### 2.HiKariCP连接池 ###### 2.1 特点 - 字节码精简 :优化代码,直到编译后的字节码最少,这样,CPU缓存可以加载更多的程序代码; - 优化代理和拦截器 :减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP的十分之一; - 自定义数组类型(FastStatementList)代替ArrayList :避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描; - 自定义集合类型(ConcurrentBag :提高并发读写的效率; - 其他针对BoneCP缺陷的优化。 注意:HiKari在springboot2.0上默认使用无需配置 ##### 3.Druid连接池 ###### 3.1Druid 相对于其他数据库连接池的优点 Druid提供性能卓越的连接池功能外,还集成了SQL监控,黑名单拦截等功能, 强大的监控特性,通过Druid提供的监控功能,可以清楚知道连接池和SQL的工作情况。 a. 监控SQL的执行时间、ResultSet持有时间、返回行数、更新行数、错误次数、错误堆栈信息; b. SQL执行的耗时区间分布。什么是耗时区间分布呢?比如说,某个SQL执行了1000次,其中0~1毫秒区间50次,1~10毫秒800次,10~100毫秒100次,100~1000毫秒30次,1~10秒15次,10秒以上5次。通过耗时区间分布,能够非常清楚知道SQL的执行耗时情况; c. 监控连接池的物理连接创建和销毁次数、逻辑连接的申请和关闭次数、非空等待次数、PSCache命中率等。 方便扩展。Druid提供了Filter-Chain模式的扩展API,可以自己编写Filter拦截JDBC中的任何方法,可以在上面做任何事情,比如说性能监控、SQL审计、用户名密码加密、日志等等。 ###### 3.2 Druid集合了开源和商业数据库连接池的优秀特性,并结合阿里巴巴大规模苛刻生产环境的使用经验进行优化。 1. 替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。 2. 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。 3. 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。 4. SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。 5. 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。 ##### 4.Spring Boot集成MyBatis实现通用Mapper ###### 4.1 MyBatis 关于MyBatis,大部分人都很熟悉。MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。 不管是DDD(Domain Driven Design,领域驱动建模)还是分层架构的风格,都会涉及到对数据库持久层的操作,在此会讲解Spring Boot集成MyBatis如何实现通用Mapper。 ###### 4.2 Spring Boot集成MyBatis 引入依赖 ``` <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <!--<scope>runtime</scope>--> <version>5.1.32</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/tk.mybatis/mapper-spring-boot-starter --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> ``` ###### 4.3 通用Mapper的使用 引入依赖 ``` <!-- https://mvnrepository.com/artifact/tk.mybatis/mapper-spring-boot-starter --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.5</version> </dependency> ``` 4.3xx 环境配置 ``` spring.datasource.hikari.connection-test-query=select 1 spring.datasource.hikari.minimum-idle=1 spring.datasource.hikari.maximum-pool-size=5 spring.datasource.hikari.pool-name=poolx spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.username=root spring.datasource.password=root123 spring.datasource.url=jdbc:mysql://localhost:3306/myrbac?characterEncoding=utf-8 spring.datasource.type=com.zaxxer.hikari.HikariDataSource mybatis.configuration.map-underscore-to-camel-case=true ``` 配置通用Mapper 在配置中,设定了指定路径下的dao,并指定了通用dao。 需要注意的是,`MapperScannerConfigurer`来自于`tk.mybatis.spring.mapper`包下。 4.3.x 配置通用mapper接口扫描器 ``` @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); mapperScannerConfigurer.setBasePackage("com.jeffrey.mapper"); Properties properties = new Properties(); properties.setProperty("mappers","com.jeffrey.config.BaseDao");//通用dao properties.setProperty("notEmpty","false"); properties.setProperty("IDENTITY","MYSQL"); mapperScannerConfigurer.setProperties(properties); return mapperScannerConfigurer; } ``` ###### 4.4 BaseDao ``` import tk.mybatis.mapper.common.Mapper; import tk.mybatis.mapper.common.MySqlMapper; public interface BaseDao<T> extends Mapper<T>,MySqlMapper<T>{ } ``` 通用Mapper接口,其他接口继承该接口即可。 ###### 4.5 创建实体 我们需要添加dept表对应的实体。 ``` package com.jeffrey.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import javax.persistence.*; /** * Created by jeffrey on 2019/11/17. */ @Data @AllArgsConstructor @NoArgsConstructor @ToString @Table(name="DEPT") public class Dept { @Id @Column(name="deptno") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer deptno; private String dname; private String loc; } ``` 其中,`@Table(name = "DEPT")`注解指定了该实体对应的数据库表名。 配置文件 ``` mybatis.configuration.map-underscore-to-camel-case=true ``` ###### 4.6 DeptDao编写 ``` package com.jeffrey.mapper; import com.fasterxml.jackson.databind.ser.Serializers; import com.jeffrey.config.BaseDao; import com.jeffrey.model.Dept; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.mybatis.spring.annotation.MapperScan; import java.util.List; /** * Created by jeffrey on 2019/11/17. */ public interface DeptDao extends BaseDao<Dept> { @Select("select * from dept") public List<Dept> findAll(); @Insert("insert into dept values(#{deptno},#{dname},#{loc})") public int addDept(Dept dept); } ``` `DeptDao`继承自`BaseDao`,并指定了泛型为对应的`Dept`。`DeptDao`包含继承的方法,如: ``` int deleteByPrimaryKey(Integer deptno); int insert(Dept dept); int insertSelective(Dept dept); Dept selectByPrimaryKey(Integer deptno); int updateByPrimaryKeySelective(Dept dept); int updateByPrimaryKey(Dept dept); 。。。。 ``` ###### 4.7 测试结果 ``` package com.jeffrey; import com.jeffrey.mapper.DeptDao; import com.jeffrey.model.Dept; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class JeffreySpcMapperApplicationTests { @Autowired private DeptDao deptMapper; @Test public void contextLoads() { List<Dept> all = deptMapper.findAll(); for (Dept dept: all ) { log.info(dept.toString()); } } @Test public void testAdd(){ Dept dept = new Dept(); dept.setDname("zhangsn"); dept.setLoc("xxx"); int i =deptMapper.addDept(dept); log.info(dept.toString()+" "+i); } } ``` ##### 5. **集成PageHelper实现分页** ###### **5.1依赖包** ``` <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> ``` ###### 5.2**添加PageHelper配置类** 在前文配置类中添加以下代码: ``` //注册mybatis分页插件PageHelper @Bean public PageHelper pageHelper(){ PageHelper pageHelper = new PageHelper(); Properties properties = new Properties(); properties.setProperty("offsetAsPageNum","true"); properties.setProperty("rowBoundsWithCount","true"); properties.setProperty("reasonable","true"); pageHelper.setProperties(properties); return pageHelper; } ``` 这时就可以使用PageHelp插件了,在service中直接使用。 ###### 5.3 service层分页实现 ``` package com.jeffrey.service.impl; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.jeffrey.mapper.DeptDao; import com.jeffrey.model.Dept; import com.jeffrey.service.DeptService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.s
JRT
2021年12月2日 22:55
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码