javascript
Spring Boot数据库操作原理及整合druid数据源和mybatis
在Spring Boot中如果需要訪問數據庫,我需要導入以下兩個依賴:
<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: rootpassword: 123456url: jdbc:mysql://192.168.15.22:3306/jdbcdriver‐class‐name: com.mysql.jdbc.Driver之后直接使用JdbcTemplate來操作數據庫即可,默認是用org.apache.tomcat.jdbc.pool.DataSource作為數據源。那么這些是如何完成的呢?可以接著往下看。注意:我使用的是Spring Boot 2.1.7版本,不同版本可能源碼有不同。
在Spring Boot的autoconfigure包下有一個叫jdbc的包,其中幫我們做好了數據庫的配置,可以查看DataSourceConfiguration,根據配置創建數據源,默認使用Tomcat連接池;可以使用spring.datasource.type指定自定義的數據源類型,如果沒有指定的話,就使用org.apache.tomcat.jdbc.pool.DataSource數據源了,默認支持org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource這些數據源。在該文件的最后還有這么一段:
/*** Generic DataSource configuration.*/@Configuration@ConditionalOnMissingBean(DataSource.class)@ConditionalOnProperty(name = "spring.datasource.type")static class Generic {@Beanpublic DataSource dataSource(DataSourceProperties properties) {return properties.initializeDataSourceBuilder().build();}}它的意思是,如果我們配置的spring.datasource.type不是上面任意一個數據源,就使用這種方式創建數據源,其原理是使用DataSourceBuilder創建數據源,利用反射創建type指定的數據源,并且綁定相關屬性。此外,Spring Boot還可以幫我自動運行建表和數據創建.sql腳本。這又是如何實現的呢?接著往下看。
在jdbc包下還有一個DataSourceInitializerInvoker類,它繼承了ApplicationListener,所以它是一個監聽器,監聽什么呢?這個類的注釋中給出了解釋:
/*** Bean to handle {@link DataSource} initialization by running {@literal schema-*.sql} on* {@link InitializingBean#afterPropertiesSet()} and {@literal data-*.sql} SQL scripts on* a {@link DataSourceSchemaCreatedEvent}.** @author Stephane Nicoll* @see DataSourceAutoConfiguration*/也就是說,如果InitializingBean#afterPropertiesSet()發生時運行schema-.sql腳本,發生DataSourceSchemaCreatedEvent時運行data-.sql 腳本。所以如果當你需要在程序運行的時候建表,直接在classpate下創建schema-.sql建表文件即可。如果你還需要插入數據,直接在classpate下創建data-.sql插入數據文件即可。不過Spring Boot也支持你直接在數據庫中聲明schema文件的位置和名稱,如:
Spring:datasource:schema:‐ classpath:department.sql最后需要注意的是,如果你在classpate下創建了schema-*.sql建表文件,那么每次啟動程序都會運行這個腳本,所以當你不需要建表的時候,注意要及時刪除。
最后,在JdbcTemplateAutoConfiguration文件還自動幫我創建好了JdbcTemplate,使用的時候直接自動注入即可:
@Bean @Primary @ConditionalOnMissingBean(JdbcOperations.class) public JdbcTemplate jdbcTemplate() {JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);JdbcProperties.Template template = this.properties.getTemplate();jdbcTemplate.setFetchSize(template.getFetchSize());jdbcTemplate.setMaxRows(template.getMaxRows());if (template.getQueryTimeout() != null) {jdbcTemplate.setQueryTimeout((int) template.getQueryTimeout().getSeconds());}return jdbcTemplate; }以上就是Spring Boot默認的數據訪問時的配置了。
在實際開發的時候,我們很少使用org.apache.tomcat.jdbc.pool.DataSource作為我們的數據源,這里我給出之前提到過的切換數據源的操作,這里我切換到druid數據源,這個數據源有很方便的監控的功能,讀者可以作為參照。
首先我們需要在依賴中引入druid數據源:
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.8</version> </dependency>而后,指定我們的數據源類型,并且進行數據源的配置:
spring:datasource: # 數據源基本配置username: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/ssm_crudtype: com.alibaba.druid.pool.DruidDataSource # 數據源其他配置initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true # 配置監控統計攔截的filters,去掉后監控界面sql無法統計,'wall'用于防火墻 filters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500這里需要注意的時,這里有很多屬性的配置是無法自動配置到DataSourceProperties中的。也就無法被我們的druid數據源使用到,這里我們可以編寫我們自己的配置類:
package com.chester.webdemo.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 javax.sql.DataSource; import java.util.Arrays; import java.util.HashMap; import java.util.Map;@Configuration public class DruidConfig {//這個注解引入我們在上面yml文件中配置的參數到DruidDataSource數據源中@ConfigurationProperties(prefix = "spring.datasource")@Beanpublic DataSource druid(){return new DruidDataSource();}//配置Druid監控//1.配置一個管理后臺的Servlet@Beanpublic ServletRegistrationBean statViewServlet(){ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet());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@Beanpublic 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;} }如果這個數據源被注入到了容器中,上面說的org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource這些數據源就不會繼續注入了,因為這些數據源在自動注入容器的時候有@ConditionalOnMissingBean(DataSource.class)這樣一個注解。這個時候我們可以訪問http://localhost:8081/druid 進入druid的監控界面,填入我們配置好的用戶名,密碼即可。
最后我們整合mybatis,首先我們需要引入mybatis:
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version></dependency>從名字中我們可以知道,這個包并非Spring官方出品,因為Spring的名字更像是這樣spring‐boot‐starter‐*。這個包實際上是mybatis出的適配Spring Boot的。接下來的工作就很簡單了,因為Spring Boot已經幫我配置好了,這里依舊給出使用mybatis的示例:
1. 首先創建實體類:
package com.chester.springboot.bean;public class Department {private Integer id;private String departmentName;public void setId(Integer id) {this.id = id;}public void setDepartmentName(String departmentName) {this.departmentName = departmentName;}public Integer getId() {return id;}public String getDepartmentName() {return departmentName;} }2. 創建mapper
package com.chester.springboot.mapper;import com.chester.springboot.bean.Department; import org.apache.ibatis.annotations.*;//指定這是一個操作數據庫的mapper @Mapper public interface DepartmentMapper {@Select("select * from department where id=#{id}")public Department getDeptById(Integer id);@Delete("delete from department where id=#{id}")public int deleteDeptById(Integer id);//Options的注解的意思是插入后將生成的id封裝到department中,方便我們之后的使用@Options(useGeneratedKeys = true,keyProperty = "id")@Insert("insert into department(department_name) values(#{departmentName})")public int insertDept(Department department);@Update("update department set department_name=#{departmentName} where id=#{id}")public int updateDept(Department department); }這里@Mapper也可以轉換為直接在主類上寫@MapperScan(value = “com.chester.springboot.mapper”)這個注解,這樣一來com.chester.springboot.mapper這個包下的接口就會自動轉換為mapper。
最后編寫cotroller使用即可
package com.chester.springboot.controller;import com.atguigu.springboot.bean.Department; import com.atguigu.springboot.bean.Employee; import com.atguigu.springboot.mapper.DepartmentMapper; import com.atguigu.springboot.mapper.EmployeeMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;@RestController public class DeptController {@AutowiredDepartmentMapper departmentMapper;@GetMapping("/dept/{id}")public Department getDepartment(@PathVariable("id") Integer id){return departmentMapper.getDeptById(id);}@GetMapping("/dept")public Department insertDept(Department department){departmentMapper.insertDept(department);return department;} }最后如果我們希望可以對MyBatis做一些自定義的配置,我們可以像下面這樣寫一個自動配置類,這里以開啟駝峰命名法為例,或者直接在配置文件中配置:
package com.chester.springboot.config;import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer; import org.springframework.context.annotation.Bean;@Configuration public class MyBatisConfig {@Beanpublic ConfigurationCustomizer configurationCustomizer(){return new ConfigurationCustomizer(){@Overridepublic void customize(Configuration configuration) {configuration.setMapUnderscoreToCamelCase(true);}};} }總結:
在上面的描述中我們討論了Spring Boot的數據源的自動配置原理,以及自動執行.sql的原理,我們還講到如何將數據源切換到druid,并做好配置,最后我們還講述了如何利用注解使用mybatis。
總結
以上是生活随笔為你收集整理的Spring Boot数据库操作原理及整合druid数据源和mybatis的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Boot错误处理机制以及定
- 下一篇: Spring Boot使用缓存功能