一、JDBC方式
- 引入starter。
<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>
- 配置application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.cj.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test spring.datasource.username=root spring.datasource.password=root
- 配置后默认使用org.apache.tomcat.jdbc.pool.DataSource作为数据源;数据源的相关配置都在org.springframework.boot.autoconfigure.jdbc.DataSourceProperties里面。
( prefix="spring.datasource") publicclassDataSourcePropertiesimplementsBeanClassLoaderAware, InitializingBean { privateClassLoaderclassLoader; privateStringname; privatebooleangenerateUniqueName; privateClass<?extendsDataSource>type; privateStringdriverClassName; privateStringurl; privateStringusername; privateStringpassword; privateStringjndiName; privateDataSourceInitializationModeinitializationMode; privateStringplatform; privateList<String>schema; privateStringschemaUsername; privateStringschemaPassword; privateList<String>data; privateStringdataUsername; privateStringdataPassword; privatebooleancontinueOnError; privateStringseparator; privateCharsetsqlScriptEncoding; privateEmbeddedDatabaseConnectionembeddedDatabaseConnection; privateDataSourceProperties.Xaxa; privateStringuniqueName; ..... }
- 自动配置原理
根据org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration,根据配置去创建数据源,默认使用tomcat连接池。 - SpringBoot默认支持的数据源类型:
- "com.zaxxer.hikari.HikariDataSource",
- "org.apache.tomcat.jdbc.pool.DataSource",
- "org.apache.commons.dbcp2.BasicDataSource"
- 可以使用spring.datasource.type指定数据源类型。因为springboot在创建数据源的时候就是根据这个来选择要创建的数据源的类型的。
abstractclassDataSourceConfiguration { DataSourceConfiguration() { } protectedstatic<T>TcreateDataSource(DataSourcePropertiesproperties, Class<?extendsDataSource>type) { returnproperties.initializeDataSourceBuilder().type(type).build(); } DataSource.class}) ({ ( name= {"spring.datasource.type"} ) staticclassGeneric { Generic() { } publicDataSourcedataSource(DataSourcePropertiesproperties) { returnproperties.initializeDataSourceBuilder().build(); } } BasicDataSource.class}) ({DataSource.class}) ({ ( name= {"spring.datasource.type"}, havingValue="org.apache.commons.dbcp2.BasicDataSource", matchIfMissing=true ) staticclassDbcp2 { Dbcp2() { } ( prefix="spring.datasource.dbcp2" ) publicBasicDataSourcedataSource(DataSourcePropertiesproperties) { return (BasicDataSource)DataSourceConfiguration.createDataSource(properties, BasicDataSource.class); } } HikariDataSource.class}) ({DataSource.class}) ({ ( name= {"spring.datasource.type"}, havingValue="com.zaxxer.hikari.HikariDataSource", matchIfMissing=true ) staticclassHikari { Hikari() { } ( prefix="spring.datasource.hikari" ) publicHikariDataSourcedataSource(DataSourcePropertiesproperties) { HikariDataSourcedataSource= (HikariDataSource)DataSourceConfiguration.createDataSource(properties, HikariDataSource.class); if (StringUtils.hasText(properties.getName())) { dataSource.setPoolName(properties.getName()); } returndataSource; } } org.apache.tomcat.jdbc.pool.DataSource.class}) ({DataSource.class}) ({ ( name= {"spring.datasource.type"}, havingValue="org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing=true ) staticclassTomcat { Tomcat() { } ( prefix="spring.datasource.tomcat" ) publicorg.apache.tomcat.jdbc.pool.DataSourcedataSource(DataSourcePropertiesproperties) { org.apache.tomcat.jdbc.pool.DataSourcedataSource= (org.apache.tomcat.jdbc.pool.DataSource)DataSourceConfiguration.createDataSource(properties, org.apache.tomcat.jdbc.pool.DataSource.class); DatabaseDriverdatabaseDriver=DatabaseDriver.fromJdbcUrl(properties.determineUrl()); StringvalidationQuery=databaseDriver.getValidationQuery(); if (validationQuery!=null) { dataSource.setTestOnBorrow(true); dataSource.setValidationQuery(validationQuery); } returndataSource; } } }
- 自定义数据源类型。
DataSource.class) (name="spring.datasource.type") (staticclassGeneric{ publicDataSourcedataSource(DataSourcePropertiesproperties){ //使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并绑定相关属性returnproperties.initializeDataSourceBuilder().build(); } }
- 自动运行建表语句原理
自动运行建表语句依赖于org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer这个类,在应用启动的时候,会去寻找字段建表语句并运行。
classDataSourceInitializer { privatestaticfinalLoglogger=LogFactory.getLog(DataSourceInitializer.class); privatefinalDataSourcedataSource; privatefinalDataSourcePropertiesproperties; privatefinalResourceLoaderresourceLoader; DataSourceInitializer(DataSourcedataSource, DataSourcePropertiesproperties, ResourceLoaderresourceLoader) { this.dataSource=dataSource; this.properties=properties; this.resourceLoader= (ResourceLoader)(resourceLoader!=null?resourceLoader : newDefaultResourceLoader()); } DataSourceInitializer(DataSourcedataSource, DataSourcePropertiesproperties) { this(dataSource, properties, (ResourceLoader)null); } publicDataSourcegetDataSource() { returnthis.dataSource; } publicbooleancreateSchema() { List<Resource>scripts=this.getScripts("spring.datasource.schema", this.properties.getSchema(), "schema"); if (!scripts.isEmpty()) { if (!this.isEnabled()) { logger.debug("Initialization disabled (not running DDL scripts)"); returnfalse; } Stringusername=this.properties.getSchemaUsername(); Stringpassword=this.properties.getSchemaPassword(); this.runScripts(scripts, username, password); } return!scripts.isEmpty(); } publicvoidinitSchema() { List<Resource>scripts=this.getScripts("spring.datasource.data", this.properties.getData(), "data"); if (!scripts.isEmpty()) { if (!this.isEnabled()) { logger.debug("Initialization disabled (not running data scripts)"); return; } Stringusername=this.properties.getDataUsername(); Stringpassword=this.properties.getDataPassword(); this.runScripts(scripts, username, password); } } privatebooleanisEnabled() { DataSourceInitializationModemode=this.properties.getInitializationMode(); if (mode==DataSourceInitializationMode.NEVER) { returnfalse; } else { returnmode!=DataSourceInitializationMode.EMBEDDED||this.isEmbedded(); } } privatebooleanisEmbedded() { try { returnEmbeddedDatabaseConnection.isEmbedded(this.dataSource); } catch (Exceptionvar2) { logger.debug("Could not determine if datasource is embedded", var2); returnfalse; } } //查找要自动运行的语句privateList<Resource>getScripts(StringpropertyName, List<String>resources, Stringfallback) { if (resources!=null) { returnthis.getResources(propertyName, resources, true); } else { Stringplatform=this.properties.getPlatform(); List<String>fallbackResources=newArrayList(); fallbackResources.add("classpath*:"+fallback+"-"+platform+".sql"); fallbackResources.add("classpath*:"+fallback+".sql"); returnthis.getResources(propertyName, fallbackResources, false); } } //运行语句privatevoidrunScripts(List<Resource>resources, Stringusername, Stringpassword) { if (!resources.isEmpty()) { ResourceDatabasePopulatorpopulator=newResourceDatabasePopulator(); populator.setContinueOnError(this.properties.isContinueOnError()); populator.setSeparator(this.properties.getSeparator()); if (this.properties.getSqlScriptEncoding() !=null) { populator.setSqlScriptEncoding(this.properties.getSqlScriptEncoding().name()); } Iteratorvar5=resources.iterator(); while(var5.hasNext()) { Resourceresource= (Resource)var5.next(); populator.addScript(resource); } DataSourcedataSource=this.dataSource; if (StringUtils.hasText(username) &&StringUtils.hasText(password)) { dataSource=DataSourceBuilder.create(this.properties.getClassLoader()).driverClassName(this.properties.determineDriverClassName()).url(this.properties.determineUrl()).username(username).password(password).build(); } DatabasePopulatorUtils.execute(populator, dataSource); } } }
所以。如果ROM要初始化一些数据库脚本,可以按照规则,将要初始化的数据库脚本命名为schema-*.sql 、data-*.sql这种格式,比如schema.sql,sachema-all.sql等,也可以在配置文件中指定位置。
schema classpath:department.sql
二、整合Druid数据源
- 引入druid依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency>
- 编写druid的配置类
//导入druid数据源publicclassDruidConfig { prefix="spring.datasource") (publicDataSourcedruid(){ returnnewDruidDataSource(); } //配置druid管理监控//1.配置一个管理后台的ServletpublicServletRegistrationBeanstatViewServlet(){ ServletRegistrationBeanbean=newServletRegistrationBean( newStatViewServlet(),"/druid/*" ); Map<String,String>initParams=newHashMap<>(); initParams.put("loginUsername","admin"); initParams.put("loginPassword","123456"); //允许所有访问initParams.put("allow",""); initParams.put("deny","192.168.12.34"); bean.setInitParameters(initParams); returnbean; } //2.配置一个web监控的filterpublicFilterRegistrationBeanwebStateFilter(){ FilterRegistrationBeanbean=newFilterRegistrationBean(); bean.setFilter(newWebStatFilter()); Map<String,String>initParams=newHashMap<>(); initParams.put("exclusions","*.js,*.css,/druid/*"); bean.setInitParameters(initParams); bean.setUrlPatterns(Arrays.asList("/*")); returnbean; } }
三、整合Mybatis
- 引入mybatis依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mybaties</artifactId></dependency>
- 配置数据源属性(同上)
- 自定义MyBatis的配置规则
要想自定义mybatis的匹配规则只需要容器中添加一个ConfigurationCustomizer即可。
publicclassMyBatisConfig { publicConfigurationCustomizerconfigurationCustomeizer(){ returnnewConfigurationCustomizer(){ publicvoidcustomize(Configurationconfiguration){ configuration.setMapUnderscoreToCamelCase(true); } }; } }
- 使用MapperScan批量扫描所有Mapper接口
value="com.desperado.mapper") (publicclassProjectDemoApplication { publicstaticvoidmain(String[] args) { SpringApplication.run(ProjectDemoApplication.class, args); } }
- 使用配置文件扫描
mybatis.config-locations=classpath:mybatis/mybatis-config.xml mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
四、整合SpringData JPA
- 编写一个实体类和数据表进行映射,并且配置好映射关系。
// 使用JPA注解配置映射关系// 标识这是一个JPA的实体类(和数据表映射的类)name="tbl_user") // 指定和数据库对应的表,如果省略默认表名就是类名小写 (publicclassUser { // 标识这是一个主键strategy=GenerationType.IDENTITY)//指定主键的生成方式 (privateIntegerid; name="name",length=50) //指定和数据表对应的列 (privateStringname; // 如果忽略名称,那么需要字段名称和数据表字段名称一致privateStringemail; }
- 编写一个Dao接口来操作实体类对应的数据表。
// 继承JpaRepository来完成对数据库的操作publicinterfaceUserRepositoryextendsJpaRepository<User,Integer> { }
- 基本配置
# 更新或者创建数据表结构 spring.jpa.hibernate.ddl-auto=update # 控制台显示sql spring.jpa.hibernate.show-sql=true