Mybatis是Apache的一个Java开源项目,是一个支持动态Sql语句的持久层框架。Mybatis可以将Sql语句配置在XML文件中,避免将Sql语句硬编码在Java类中。与JDBC相比:
web模块开发需要的相关jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
mybatis相关包
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
sqlserver包
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
(1) 添加数据库配置
spring:
datasource:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://localhost;DatabaseName=lss0555
username: sa
password: 888888
(2) mybatis配置
mybatis:
configuration:
mapUnderscoreToCamelCase: false
type-aliases-package: com.example.test2.dao
mapper-locations: classpath*:mapping/*.xml
mapUnderscoreToCamelCase
使用驼峰命名法转换字段 mybatis可以自动处理,可以自动进行映射表中的列和类中的属性,比如数据库是user_name 属性是userName
type-aliases-package
设置这个以后再Mapper配置文件中在parameterType 的值就不用写成全路径名了,parameterType="com.example.mybatisdemo.model.User"可以写成parameterType = “User”
mapper-locations
mapper.xml的路径
直接在启动文件SpringbootApplication.java的类上配置@MapperScan,这样就可以省去,
单独给每个Mapper上标识@Mapper的麻烦
@MapperScan(value = "com.example.mybatisdemo.dao")
(1)model层
public class User implements Serializable {
private int id;
private String username;
private String password;
}
(2).Dao层
public interface UserDaoMapper {
List<User> userList();
}
(3)mapping层
<?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.example.test2.dao.UserDaoMapper">
<select id="userList" resultType="com.example.test2.model.User">
select * from [USER]
</select>
</mapper>
1.连接池介绍
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。通过数据库连接池能明显提高对数据库操作的性能。
连接池中提前预先建立了多个数据库连接对象,然后将连接对象保存到连接池中,当客户请求到来时,直接从池中取出一个连接对象为客户服务,当请求完成之后,客户程序调用close()方法,将连接对象放回池中。数据库连接池的意义在于,能够重复利用数据库连接(有点类似线程池的部分意义),提高对请求的响应时间和服务器的性能。
2.Druid数据源
druid为阿里巴巴的数据源,(数据库连接池),集合了c3p0、dbcp、proxool等连接池的优点,还加入了日志监控,有效的监控DB池连接和SQL的执行情况,相比spring推荐的DBCP和hibernate推荐的C3P0、Proxool数据库连接池,Druid在市场上占有绝对的优势;
通过Druid连接池中间件, 我们可以实现:
1.可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
2.替换传统的DBCP和C3P0连接池中间件。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
3.数据库密码加密。直接把数据库密码写在配置文件中,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
4.SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
5.扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter-Chain机制,很方便编写JDBC层的扩展插件
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://localhost;DatabaseName=lss0555;autoReconnect=true;characterEncoding=UTF-8
username: sa
password: 888888
druid:
#属性类型是字符串,通过别名的方式配置扩展插件,
#常用的插件有:
#监控统计用的filter:stat
#日志用的filter:log4j
# 防御sql注入的filter:wall wall用于防火墙
filters: stat,wall,log4j,config
#最大连接数
max-active: 100
#初始化大小
initial-size: 1
#获取连接最大等待时间
max-wait: 60000
min-idle: 1
#间隔多久检测一次需要关闭的空闲连接 毫秒
time-between-eviction-runs-millis: 60000
#连接在连接池中最小生存的时间,毫秒
min-evictable-idle-time-millis: 300000
# 用来检测连接是否为有效的sql,要求是一个查询语句
validation-query: select 'x'
#当连接空闲时,是否执行连接测试
test-while-idle: true
# 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
test-on-borrow: false
# 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
test-on-return: false
pool-prepared-statements: true
# 打开PSCache,并且指定每个连接上PSCache的大小
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
后台数据监控访问
http://localhost:8085/druid/login.html
// druid监控视图配置
@Configuration
public class DruidConfiguration {
//http://localhost:8084/druid/login.html
@Bean
public ServletRegistrationBean statViewServle(){
ServletRegistrationBean servletRegistrationBean=new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
//// 添加IP白名单 空的,为默认所有
servletRegistrationBean.addInitParameter("allow","");
//IP黑名单
servletRegistrationBean.addInitParameter("deny","192.168.4.23"); //IP黑名单 (存在共同时,deny优先于allow)
//控制台用户
servletRegistrationBean.addInitParameter("loginUsername","admin");
servletRegistrationBean.addInitParameter("loginPassword","888888");
//是否能够重置数据
servletRegistrationBean.addInitParameter("resetEnable","false");
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean statFilter(){
FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(new WebStatFilter());
//添加过滤规则
filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
PageHelper是国内非常优秀的一款开源的mybatis分页插件, 它支持基本主流与常用的数据库, 例如mysql、 oracle、 mariaDB、 DB2、 SQLite、 Hsqldb等
PageHelper首先将前端传递的参数保存到page这个对象中,接着将page的副本存放入ThreadLoacl中,在多线程环境下,各个Threadlocal之间相互隔离,可以实现,不同thread使用不同的数据源或不同的Thread中执行不同的SQL语句,所以,PageHelper利用这一点通过拦截器获取到同一线程中的预编译好的SQL语句之后将SQL语句包装成具有分页功能的SQL语句,并将其再次赋值给下一步操作,所以实际执行的SQL语句就是有了分页功能的SQL语句
(1)添加pom.xml包
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
(2) 添加配置
pagehelper:
helperDialect: sqlserver
reasonable: true
supportMethodsArguments: false
params: count=countSql
offset-as-page-num: false
row-bounds-with-count: false
主要参数介绍:
helperDialect
指定分页插件使用哪种方言
reasonable
分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
supportMethodsArguments
支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。
(3)实例
(1)分页方式1
PageHelper.offsetPage(currentPage,pageSize); 代码侵入性小
@GetMapping("/userListPage")
public TResult userListPage(Integer currentPage, Integer pageSize){
TResult<User> userTResult = new TResult<>();
try {
PageHelper.offsetPage(currentPage,pageSize);
List<User> userList = userDaoMapper.userList();
userTResult.setData(userList);
}catch (Exception e){
userTResult.setErrorCode(-1);
userTResult.setErrorMsg(e.getMessage());
}
return userTResult;
}
(2)分页方式2
通过Mapper接口传递参数分页,需要设置supportMethodsArguments 为true
dao层,mapping不用对分页参数进行处理
List<User> userListByPage(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
controller层
@GetMapping("/userListPage")
public TResult userListPage(Integer currentPage, Integer pageSize){
TResult<User> userTResult = new TResult<>();
try {
List<User> userList = userDaoMapper.userListByPage(currentPage,pageSize);
userTResult.setData(userList);
}catch (Exception e){
userTResult.setErrorCode(-1);
userTResult.setErrorMsg(e.getMessage());
}
return userTResult;
}
如果对页面数量等有需求,需要分页的基本信息,可以使用PageInfo,PageInfo中是分页的一些信息,包括总页数,当前页,总数据等
@GetMapping("/userListPage1")
public PageInfo userListPage1(Integer currentPage, Integer pageSize) {
PageHelper.startPage(currentPage, pageSize);
List<User> userList = userDaoMapper.userList();
PageInfo<User> appsPageInfo = new PageInfo<>(userList);
return appsPageInfo;
}
分页详细信息如下:
{
“pageNum”: 3,
“pageSize”: 2,
“size”: 2,
“startRow”: 5,
“endRow”: 6,
“total”: 20,
“pages”: 10,
“list”: [
{
“id”: 5,
“username”: “5”,
“password”: “5”
},
{
“id”: 6,
“username”: “6”,
“password”: “6”
}
],
“prePage”: 2,
“nextPage”: 4,
“isFirstPage”: false,
“isLastPage”: false,
“hasPreviousPage”: true,
“hasNextPage”: true,
“navigatePages”: 8,
“navigatepageNums”: [
1,
2,
3,
4,
5,
6,
7,
8
],
“navigateFirstPage”: 1,
“navigateLastPage”: 8,
“firstPage”: 1,
“lastPage”: 8
}