Spring+jdbc
使用idea 创建springboot项目的时候选中mysql 勾上mysql 和jdbc 然后我们进行演示
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://104.224.142.102:3306/test
username: root
password: 1234
yml/properties 中配置上数据库连接配置
package com.zzq.springboot06jdbc;
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 javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBoot06JdbcApplicationTests {
@Autowired
DataSource dataSource ;
@Test
public void contextLoads() throws SQLException {
System.out.println(dataSource.getClass());
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
}
获取连接池类型, 和连接对象connection
class com.zaxxer.hikari.HikariDataSource
2018-09-04 09:56:25.040 INFO 10792 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2018-09-04 09:56:28.653 INFO 10792 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
HikariProxyConnection@1488352537 wrapping com.mysql.jdbc.JDBC4Connection@281ce6bb
2018-09-04 09:56:28.678 INFO 10792 --- [ Thread-2] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@38467116: startup date [Tue Sep 04 09:56:15 CST 2018]; root of context hierarchy
2018-09-04 09:56:28.681 INFO 10792 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2018-09-04 09:56:28.686 INFO 10792 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
我们可以看到springboot 使用的是HikaridataSource 这个连接池, 我之前也是没有听说过,是我孤陋寡闻,springboot2.0之前的默认连接池是tomcat 连接池, springboot2.0 换成了hikaridate 是有原因的 我们看下网上评价
https://blog.csdn.net/qq_31125793/article/details/51241943
我个人觉得使用druid 还是比较好
数据源的配置在 DataSourceProperties中
自动配置原理在org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 中
DataSourceConfiguration
数据源的配置 ,根据各种配置创建数据源,默认是使用 HikariDataSource
springboot 默认支持的数据源有 :
org.apache.tomcat.jdbc.pool.DataSource dataSource
com.zaxxer.hikari.HikariDataSource
org.apache.commons.dbcp2.BasicDataSource
/**
* Generic DataSource configuration.
*/
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {
@Bean
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}
也可以自定义数据源类型,使用build()创建数据源的,用反射创建type 数据源绑定相关属性
springboot 配置自动配置jdbc配置类
*/
public void initSchema() {
List<Resource> scripts = getScripts("spring.datasource.data",
this.properties.getData(), "data");
if (!scripts.isEmpty()) {
if (!isEnabled()) {
logger.debug("Initialization disabled (not running data scripts)");
return;
}
String username = this.properties.getDataUsername();
String password = this.properties.getDataPassword();
runScripts(scripts, username, password);
}
}
在创建完连接池之后执行了,runscripts 方法这个方式是用来初始化sql 表的,可以吧建表语句写在文件中,然后springboot项目启动的时候自动创建
这个方法三个参数,
private void runScripts(List<Resource> resources, String username, String password) {
resource 里面就是放的配置的sql文件地址
它里面还有一个方法
private List<Resource> getScripts(String propertyName, List<String> resources,
String fallback) {
if (resources != null) {
return getResources(propertyName, resources, true);
}
String platform = this.properties.getPlatform();
List<String> fallbackResources = new ArrayList<>();
fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
fallbackResources.add("classpath*:" + fallback + ".sql");
return getResources(propertyName, fallbackResources, false);
}
他是先从我们properties/yml中找有没有我们配置的,如果有就按照我们的加载,如果没有就
public boolean createSchema() {
List<Resource> scripts = getScripts("spring.datasource.schema",
this.properties.getSchema(), "schema");
if (!scripts.isEmpty()) {
if (!isEnabled()) {
logger.debug("Initialization disabled (not running DDL scripts)");
return false;
}
String username = this.properties.getSchemaUsername();
String password = this.properties.getSchemaPassword();
runScripts(scripts, username, password);
}
return !scripts.isEmpty();
}
这里看到fallback 就是schema 字符串 所以他默认会加载根目录下的schema.sql文件
/**
* Platform to use in the DDL or DML scripts (such as schema-${platform}.sql or
* data-${platform}.sql).
*/
private String platform = "all";
或者是制定platform 参数然后data-${platform}.sql文件或者schema-${platform}.sql 文件
在springboot1.5 中会自动加载,但是springboot2.0 可能不会,我们需要配上一个参数
initialization-mode: always
这个是干什么? 点开看看
/**
* Initialize the datasource with available DDL and DML scripts.
*/
private DataSourceInitializationMode initializationMode = DataSourceInitializationMode.EMBEDDED;
/**
看描述 是初始化可以可用的ddl dml 数据源脚本文件
默认类型是embedded类型 ,点开
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.jdbc;
/**
* Supported {@link javax.sql.DataSource} initialization modes.
*
* @author Vedran Pavic
* @author Stephane Nicoll
* @since 2.0.0
* @see AbstractDataSourceInitializer
*/
public enum DataSourceInitializationMode {
/**
* Always initialize the datasource.
*/
ALWAYS,
/**
* Only initialize an embedded datasource.
*/
EMBEDDED,
/**
* Do not initialize the datasource.
*/
NEVER
}
枚举类,第一个是初始化所有的数据源, 第二个是,初始化嵌入式的数据源, 第三个是初始化数据源
我们把他调成always 就可以了
JDBCTemplate
spring 提供的听哈用的
package com.zzq.springboot06jdbc.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* @author ZZQ
* @date 2018/9/4 11:44
*/
@RestController
public class helloWorldController {
@Autowired
private JdbcTemplate jdbcTemplate;
@GetMapping("/jdbc")
public Map hello(){
List<Map<String, Object>> maps = jdbcTemplate.queryForList("select * from department");
return maps.get(0);
}
}
springboot使用druiddatasource 实现监控,防火墙等
1)引入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
2)配置properties
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:my...
username: root
password: 1234
#支持的是list
schema:
- classpath:department.sql
- classpath:employee.sql
initialization-mode: always
type: com.alibaba.druid.pool.DruidDataSource
只要type 改变spring 使用的连接池也就发生了变化
这样切换了, 但是druid 有更厉害的功能监控之类的这个需要我们自己定义datasource 不能使用springboot的反射创建的datasource 写一个自己的配置类和配置文件对应
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://104.224.142.102:3306/test
username: root
password: 1234
#支持的是list
schema:
- classpath:department.sql
- classpath:employee.sql
initialization-mode: always
type: com.alibaba.druid.pool.DruidDataSource
# 数据源其他配置 (一下默认是不起作用的)
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
package com.zzq.springboot06jdbc.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.ServletContextLiveBeansView;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* @author ZZQ
* @date 2018/9/4 12:42
*/
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid(){
return new DruidDataSource();
}
//配置Druid的监控
//1、配置一个管理后台的Servlet
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String,String> initParams = new HashMap<>();
initParams.put("loginUsername","admin");
initParams.put("loginPassword","123456");
initParams.put("allow","");//默认就是允许所有访问
initParams.put("deny","192.168.15.21");
bean.setInitParameters(initParams);
return bean;
}
//2、配置一个web监控的filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String,String> initParams = new HashMap<>();
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
这样配置即可
Springboot 整合Mybatis
注解版
直接引入mybatis-spring- starter 然后然后druid 连接池配置好,编写mapper文件
package com.zzq.springboot06mybatis.mapper;
import com.zzq.springboot06mybatis.entity.Department;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @author ZZQ
* @date 2018/9/4 16:47
*/
@Mapper
public interface DepartmentMapper {
@Select("select * from department where id=#{id}")
public Department getDeptById(Integer id );
@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into department(departmentName) values(#{departmentName})")
public int insertDept( Department department);
}
这里@Options 这个注解是用来标识自增主键,他的结果会自动的封装进department 中,然后返回
这里我们的字段和数据库中的字段是对应的, 数据中也是驼峰命名,但是数据库如果是以_隔开, 我们要自己配置命名规则,写配置类
package com.zzq.springboot06mybatis.config;
import ch.qos.logback.classic.gaffer.ConfigurationContributor;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @author ZZQ
* @date 2018/9/4 17:18
*/
@Configuration
public class MybatisConfig {
/**
* @author ZZQ
* @date 2018/9/4
* @description
* 开启mybatis 驼峰命名法
*/
public ConfigurationCustomizer configurationCustomizer(){
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
configuration.setMapUnderscoreToCamelCase(true);
}
};
}
}
如果很多mapper的话我们可以采用包扫描的方式加入mapper
@MapperScan(basePackages = {"com.zzq.springboot06mybatis.mapper"})
可以传入多个位置,这里是数组
配置版
使用xml配置,复杂的sql 让java 代码变得臃肿不适合写注解
使用配置
1)创建全局配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
2)然后再springboot全局配置文件中配置 mapper 接口文件和mapper 映射文件的位置
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*.xml
然后其他就和我们正常写的一样了
--------------------------------------------
Mybatis +Springboot 之后如何打印输出打印sql ?
logging:
level:
com.zzq.springboot06mybatis.mapper: DEBUG
这里的com.zzq.springboot06mybatis.mapper 就是接口文件的位置