springdata
集成JDBC
-
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
-
数据库配置
spring: datasource: username: root 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: org.springframework.jdbc.datasource.DriverManagerDataSource
-
测试
@SpringBootTest class TeststartApplicationTests { @Autowired private DataSource dataSource; @Test void contextLoads() throws SQLException { Connection connection = dataSource.getConnection(); System.out.println(connection+"========"); } }
- 如果我们不配置数据源类型,springboot提供了默认的数据源class com.zaxxer.hikari.HikariDataSource
- Hikari是一款十分优秀的数据源,号称web应用中连接速度最快。
其他常见的数据源还有
- druid
- Dbpc
- c3p0
- ibatis
如果我们需要整合其他类型的数据源,只需要更换pom依赖和数据源配置即可
原生jdbc语句操作数据库
我们配置了数据源,并且利用数据源和数据库建立了连接,这个时候我们就可以使用原生的jdbc语句来对数据库进行操作。
@SpringBootTest
class TeststartApplicationTests {
@Autowired
private DataSource dataSource;
@Test
void contextLoads() throws SQLException {
Connection connection = dataSource.getConnection();
System.out.println(connection+"========");
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery("select * from user");
while (set.next()) {
System.out.println(set.getString("id") + "\t" + set.getString("name"));
}
statement.close();
connection.close();
}
}
JdbcTemplate
spring除了提供了一个默认的数据源外,他还对原始的jdbc语句进行了简单的封装。
那就是JdbcTemplate,通过这个,我们可以更简单的实现数据库的操作
JdbcTemplate的一些常用方法
- execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
- update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate
方法用于执行批处理相关语句; - query方法及queryForXXX方法:用于执行查询相关语句;
- call方法:用于执行存储过程、函数相关语句。
来测试一下
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
void contextLoads1() throws SQLException {
List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from user");
System.out.println(list);
}
第三方框架
除了原生的jdbc语句和spring为我们封装的轻量级的JdbcTemplate,我们也可以通过第三方的框架mybatis等方式来更方便的操作我们的语句。
集成Druid
德鲁伊是一款及其优秀的数据源,只要导入依赖并且更换数据源的方式我们就可以使用它来进行数据库操作。并且Druid还很好的提供了监控 DB 池连接和 SQL 的执行情况的功能。
更换Druid数据源
-
导入依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--数据库连接--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--druidDataResource需要日志功能的支持--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <!--jdbc支持--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
-
配置数据源
spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/mybatis?&serverTimezone=GMT&useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource
-
测试
@SpringBootTest class Springboot02ApplicationTests { @Autowired DataSource dataSource; @Test void contextLoads() throws SQLException { //查看默认的数据源 System.out.println(dataSource.getClass()); //获得数据库连接 Connection connection = dataSource.getConnection(); System.out.println(connection); connection.close(); } }
数据源切换成功
-
添加数据连接池其他配置
springboot为我们提供的数据源配置有些单调,我们需要配置最大连接数,超时自动断开连接怎么配置呢?
druid它以类代理模式的思想在它原有的功能基础上增加功能。
它提供一个DruidDataSource类,这个类中有个方法configFromProperties可以读取并为数据源配置参数,只需要我们在配置类中将DruidDataSource注入SpringIOC容器中,并且为它绑定前缀,就可以在yml文件中配置这些参数。
相当于给我们写好了配置文件,只等我们注入和绑定前缀了。
看一下这个配置文件DruidDataSource和其方法。
public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable, Closeable, Cloneable, ConnectionPoolDataSource, MBeanRegistration { public void configFromPropety(Properties properties) { { String property = properties.getProperty("druid.name"); if (property != null) { this.setName(property); } } { String property = properties.getProperty("druid.url"); if (property != null) { this.setUrl(property); } } { String property = properties.getProperty("druid.username"); if (property != null) { this.setUsername(property); } } { String property = properties.getProperty("druid.password"); if (property != null) { this.setPassword(property); } }
配置方法
将DruidDataSource注入SpringIOC容器中并绑定前缀(在任意配置类均可,直接加组件也可以)
@Configuration public class DruidConfig { @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druidDataSource() { return new DruidDataSource(); } }
测试
@Autowired DataSource dataSource; @Test void contextLoads() throws SQLException { Connection connection = dataSource.getConnection(); DruidDataSource druidDataSource = (DruidDataSource) dataSource; System.out.println("druidDataSource 数据源最大连接数:" + druidDataSource.getMaxActive()); System.out.println("druidDataSource 数据源初始化连接数:" + druidDataSource.getInitialSize()); connection.close(); }
- druid并不会去改变默认的那些参数值的注入,只会以拓展的形式来增加配置。
- 前缀必须为spring.datasource
druid基本配置参数如下:
配置 | 缺省值 | 说明 |
---|---|---|
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/%E4%BD%BF%E7%94%A8ConfigFilter | |
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,是组合关系,并非替换关系 |
配置监控服务
-
druid提供了对数据连接的监控,并且提供了可视化页面。
-
它提供了ServletRegistrationBean的方式,只需要将配置好的类注入到SpringIOC容器中即可生效
配置注册ServletRegistrationBean
@Configuration
public class DruidConfig {
@Bean
public ServletRegistrationBean myServletRegistrationBean(){
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
HashMap<String, String> initParameters = new HashMap<>();
//配置登录名和密码
initParameters.put("loginUsername","admin");
initParameters.put("loginPassword","123456");
//允许谁可以访问
initParameters.put("allow",""); //参数为空,所有人可以访问
//禁止谁可以访问。
//initParameters.put("lyj","192.168.111");
//后台需要有人配置登录密码用户
bean.setInitParameters(initParameters); //初始化参数
return bean;
}
}
登录
http://localhost:8080/druid/login.html
就可以访问监控的可视化界面。
配置监控器的过滤规则
- 如果不配置监控器的过滤规则,它将监控js,css,等所有请求。这将造成资源浪费
- 配置一个配套的过滤器FilterRegistrationBean对其过滤。
@Configuration
public class DruidConfig {
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
//可以过滤哪些请求
HashMap<String,String> initParamters = new HashMap<>();
//exclusion排除不再统计。
initParamters.put("exclusions","*.js,*.css,*.jpg,/druid/**");
bean.setInitParameters(initParamters);
return bean;
}
}
监控配置完成。
整合mybatis
文件目录结构如下
-
引入jar包
<!--mybatis-starter整合了jdbc--> <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> </dependency>
-
配置数据源(如果增加其他配置,需整合druid)
spring.datasource.username=root spring.datasource.password=123456 spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-
创建实体类User
@Data @AllArgsConstructor @NoArgsConstructor public class User { private int id; private String name; private String pwd; }
-
创建mapper接口
//注解表示这是一个Mybatis的mapper类 @Mapper @Repository public interface UserMapper { List<User> queryUserList(); User queryUserById(Integer id); int addUser(User user); int updateUser(User user); int deleteUserById(Integer id); }
除了在类中写@Mapper,还可以在启动类中用@MapperScan(“com.lyj.mapper”)的方式声明
-
创建mapper配置文件(resources/mybatis/mapper)
<?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.lyj.mapper.UserMapper"> <select id="queryUserById" resultType="com.lyj.pojo.User"> select * from user where id=#{id} </select> <select id="queryUserList" resultType="com.lyj.pojo.User"> select * from user </select> <update id="updateUser" parameterType="com.lyj.pojo.User"> update user set name=#{name},pwd=#{name} where id=#{id} </update> <insert id="addUser" parameterType="com.lyj.pojo.User"> insert into user(id,name,pwd) values(#{id},#{name},#{pwd}) </insert> <delete id="deleteUserById" parameterType="integer"> delete from user where id=#{id} </delete> </mapper>
-
设置mepper资源映射路径和别名设置,properties配置文件中配置
mybatis.type-aliases-package=com.lyj.pojo mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
-
写接口测试
@RestController public class UserController { @Autowired private UserMapper userMapper; @RequestMapping("/queryUserList") public List<User> queryUserList(){ List<User> userList = userMapper.queryUserList(); return userList; } @RequestMapping("/queryUserById/{id}") public User queryUserById(@PathVariable("id") Integer id){ return userMapper.queryUserById(id); } @RequestMapping("/updateUser/{id}") public int updateUser(@PathVariable("id") Integer id){ User user = new User(); user.setId(id); user.setName("奥特曼"); user.setPwd("666666"); return userMapper.updateUser(user); } }