国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

做網(wǎng)絡(luò)銷售都做什么網(wǎng)站饑餓營銷的十大案例

做網(wǎng)絡(luò)銷售都做什么網(wǎng)站,饑餓營銷的十大案例,深圳龍華做網(wǎng)站公司,做淘寶一樣的網(wǎng)站文章目錄 前言第10章 SpringBoot整合JDBC10.1 SpringBoot整合JDBC的項目搭建10.1.1 初始化數(shù)據(jù)庫10.1.2 整合項目10.1.2.1 導(dǎo)入JDBC和MySQL驅(qū)動依賴10.1.2.2 配置數(shù)據(jù)源 10.1.3 編寫業(yè)務(wù)代碼10.1.3.1 編寫與t_user表對應(yīng)的實體類User10.1.3.2 編寫Dao層代碼10.1.3.3 編寫Servic…

文章目錄

  • 前言
  • 第10章 SpringBoot整合JDBC
    • 10.1 SpringBoot整合JDBC的項目搭建
      • 10.1.1 初始化數(shù)據(jù)庫
      • 10.1.2 整合項目
        • 10.1.2.1 導(dǎo)入JDBC和MySQL驅(qū)動依賴
        • 10.1.2.2 配置數(shù)據(jù)源
      • 10.1.3 編寫業(yè)務(wù)代碼
        • 10.1.3.1 編寫與t_user表對應(yīng)的實體類User
        • 10.1.3.2 編寫Dao層代碼
        • 10.1.3.3 編寫Service層代碼
      • 10.1.4 編寫主啟動類
      • 10.1.5 測試結(jié)果
    • 10.2 整合JDBC后的自動裝配
      • 10.2.1 配置數(shù)據(jù)源
        • 10.2.1.1 DataSourceInitializerInvoker
          • (1)createSchema
          • (2)initialize
        • 10.2.1.2 DataSourceInitializerPostProcessor
      • 10.2.2 創(chuàng)建JdbcTemplate
      • 10.2.3 配置事務(wù)管理器

前言

在實際SpringBoot項目中,通常都離不開與數(shù)據(jù)庫的交互,更多的選擇是使用持久層框架MyBatis或SpringData等,而不是原生的spring-jdbc。

但學(xué)習(xí)SpringBoot整合JDBC場景下的組件裝配,以及注解聲明式事務(wù)的生效原理、控制流程、事務(wù)傳播行為等,依舊是必要的,對后續(xù)學(xué)習(xí)SpringBoot整合持久層框架具有很大幫助。

第10章 SpringBoot整合JDBC

10.1 SpringBoot整合JDBC的項目搭建

10.1.1 初始化數(shù)據(jù)庫

選擇MySQL作為本項目的數(shù)據(jù)源,創(chuàng)建一個新的數(shù)據(jù)庫springboot_demo和一個新表t_user:

CREATE DATABASE springboot_demo CHARACTER SET 'utf8mb4';CREATE TABLE t_user(id INT(11) NOT NULL AUTO_INCREMENT,NAME VARCHAR(20) NOT NULL,tel VARCHAR(20) NULL,PRIMARY KEY (id)
);

10.1.2 整合項目

10.1.2.1 導(dǎo)入JDBC和MySQL驅(qū)動依賴
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency>
</dependencies>
10.1.2.2 配置數(shù)據(jù)源

在resources目錄下新建application.properties文件,并配置數(shù)據(jù)源:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot_demo?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456

10.1.3 編寫業(yè)務(wù)代碼

10.1.3.1 編寫與t_user表對應(yīng)的實體類User
public class User {private Integer id;private String name;private String tel;// getter setter toString ...
}
10.1.3.2 編寫Dao層代碼
@Repository
public class UserDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public void save(User user) {jdbcTemplate.update("insert into t_user (name, tel) values (?, ?)",user.getName(), user.getTel());}public List<User> findAll() {return jdbcTemplate.query("select * from t_user",BeanPropertyRowMapper.newInstance(User.class));}}
10.1.3.3 編寫Service層代碼
@Service
public class UserService {@Autowiredprivate UserDao userDao;@Transactional(rollbackFor = Exception.class)public void test() {User user = new User();user.setName("齊天大圣");user.setTel("12306");userDao.save(user);List<User> userList = userDao.findAll();userList.forEach(System.out::println);}}

10.1.4 編寫主啟動類

主啟動類注意兩點:第一是要獲取IOC容器,并提取出UserService類調(diào)用其test方法;第二是要標注@EnableTransactionManagement注解開啟注解式聲明式事務(wù)。

@SpringBootApplication
@EnableTransactionManagement
public class JDBCApp {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(JDBCApp.class, args);UserService userService = context.getBean(UserService.class);userService.test();}}

10.1.5 測試結(jié)果

運行主啟動類,控制臺可以正確打印出一條用戶信息,說明SpringBoot整合JDBC場景順利完成。

User{id=1, name='齊天大圣', tel='12306'}

10.2 整合JDBC后的自動裝配

由 10.1 節(jié)可知,對于原生的JDBC整合后,主啟動類中并沒有聲明與之相關(guān)的注解,因此有關(guān)JDBC的組件裝配都是以自動配置類的方式實現(xiàn)的。

借助IDEA通過spring-boot-autoconfigure依賴的spring.factories文件可以找到有關(guān)JDBC的自動配置類:

源碼1:spring-boot-autoconfigure-2.3.11.RELEASE.jar!/META-INF/spring.factoriesorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\

可以發(fā)現(xiàn),SpringBoot默認支持的自動配置包含數(shù)據(jù)源、JdbcTemplate、事務(wù)管理器、JNDI、XA協(xié)議等。

10.2.1 配置數(shù)據(jù)源

在SpringBoot的官方文檔中,介紹了SpringBoot支持的數(shù)據(jù)源連接池:

1.1.4. Supported Connection Pools
Spring Boot uses the following algorithm for choosing a specific implementation:
We prefer HikariCP for its performance and concurrency. If HikariCP is available, we always choose it.
Otherwise, if the Tomcat pooling DataSource is available, we use it.
Otherwise, if Commons DBCP2 is available, we use it.
If none of HikariCP, Tomcat, and DBCP2 are available and if Oracle UCP is available, we use it.

可見,SpringBoot支持的數(shù)據(jù)源連接池包括HikariCP、Tomcat、DBCP2、Oracle UCP等,默認使用HikariCP。

因此,自動配置類DataSourceAutoConfiguration的靜態(tài)內(nèi)部類PooledDataSourceConfiguration會生效。因為它通過@Import注解導(dǎo)入了DataSourceConfiguration.Hikari類。

源碼2DataSourceAutoConfiguration.java@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {@Configuration(proxyBeanMethods = false)@Conditional(PooledDataSourceCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,DataSourceJmxConfiguration.class })protected static class PooledDataSourceConfiguration {}
}
源碼3DataSourceConfiguration.java@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HikariDataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",matchIfMissing = true)
static class Hikari {@Bean@ConfigurationProperties(prefix = "spring.datasource.hikari")HikariDataSource dataSource(DataSourceProperties properties) {HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);if (StringUtils.hasText(properties.getName())) {dataSource.setPoolName(properties.getName());}return dataSource;}
}

由 源碼2、3 可知,SpringBoot默認會創(chuàng)建一個HikariDataSource。

此外,DataSourceAutoConfiguration還使用@Import注解導(dǎo)入了一個DataSourceInitializationConfiguration配置類。

源碼4DataSourceInitializationConfiguration.java@Configuration(proxyBeanMethods = false)
@Import({DataSourceInitializerInvoker.class, DataSourceInitializationConfiguration.Registrar.class})
class DataSourceInitializationConfiguration {static class Registrar implements ImportBeanDefinitionRegistrar {private static final String BEAN_NAME = "dataSourceInitializerPostProcessor";@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry) {if (!registry.containsBeanDefinition(BEAN_NAME)) {// 注冊DataSourceInitializerPostProcessorGenericBeanDefinition beanDefinition = new GenericBeanDefinition();beanDefinition.setBeanClass(DataSourceInitializerPostProcessor.class);beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);beanDefinition.setSynthetic(true);registry.registerBeanDefinition(BEAN_NAME, beanDefinition);}}}}

由 源碼4 可知,這個配置類又使用@Import注解導(dǎo)入了一個DataSourceInitializerInvoker和一個Registrar注冊器。注冊器又向BeanDefinition中注冊了一個DataSourceInitializerPostProcessor。

10.2.1.1 DataSourceInitializerInvoker

由類名理解,這是一個數(shù)據(jù)源初始化的執(zhí)行器。

源碼5DataSourceInitializerInvoker.javaclass DataSourceInitializerInvoker implements ApplicationListener<DataSourceSchemaCreatedEvent>, InitializingBean {@Overridepublic void afterPropertiesSet() {DataSourceInitializer initializer = getDataSourceInitializer();if (initializer != null) {boolean schemaCreated = this.dataSourceInitializer.createSchema();if (schemaCreated) {initialize(initializer);}}}}

由 源碼5 可知,DataSourceInitializerInvoker實現(xiàn)了ApplicationListener接口,因此是一個監(jiān)聽器,監(jiān)聽的事件是DataSourceSchemaCreatedEvent;此外,它還實現(xiàn)了InitializingBean接口,會在對象創(chuàng)建后回調(diào)afterPropertiesSet方法執(zhí)行初始化邏輯。

afterPropertiesSet方法中,首先會調(diào)用getDataSourceInitializer方法獲取DataSourceInitializer實例,隨后執(zhí)行DataSourceInitializer的createSchema方法,如果執(zhí)行成功則繼續(xù)執(zhí)行initialize方法。

(1)createSchema

該方法名直譯為“創(chuàng)建約束”,即執(zhí)行DDL語句。也就在項目開發(fā)中,可以先不創(chuàng)建數(shù)據(jù)庫的表結(jié)構(gòu),而是在應(yīng)用程序啟動時,自動讀取自定義的SQL文件執(zhí)行DDL語句進行創(chuàng)建。

源碼6DataSourceInitializer.javaboolean createSchema() {// 加載Schema資源List<Resource> scripts = getScripts("spring.datasource.schema", this.properties.getSchema(), "schema");// 解析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();
}private List<Resource> getScripts(String propertyName, List<String> resources, String fallback) {if (resources != null) {// 如果全局配置文件中配置了spring.datasource.schema屬性// 則直接根據(jù)該spring.datasource.schema屬性加載資源文件return getResources(propertyName, resources, true);}// 默認返回字符串"all"String platform = this.properties.getPlatform();List<String> fallbackResources = new ArrayList<>();// 拼接文件名:schema-all.sql和schema.sqlfallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");fallbackResources.add("classpath*:" + fallback + ".sql");// 加載文件schema-all.sql和schema.sqlreturn getResources(propertyName, fallbackResources, false);
}

由 源碼6 可知,createSchema方法先讀取全局配置文件中的spring.datasource.schema屬性,根據(jù)該屬性配置的路徑加載資源文件,再對資源文件進行解析。在調(diào)用getScripts方法讀取資源文件時,分為兩種情況:

  • 如果全局配置文件中配置了spring.datasource.schema屬性,則直接根據(jù)該屬性的值加載資源文件;
  • 如果全局配置文件沒有配置該屬性,則加載名為schema-all.sql和schema.sql的資源文件。
(2)initialize
源碼7DataSourceInitializerInvoker.javaprivate void initialize(DataSourceInitializer initializer) {try {// 廣播DataSourceSchemaCreatedEvent事件this.applicationContext.publishEvent(new DataSourceSchemaCreatedEvent(initializer.getDataSource()));if (!this.initialized) {// 解析資源文件this.dataSourceInitializer.initSchema();this.initialized = true;}} // catch ......
}@Override
public void onApplicationEvent(DataSourceSchemaCreatedEvent event) {DataSourceInitializer initializer = getDataSourceInitializer();if (!this.initialized && initializer != null) {initializer.initSchema();this.initialized = true;}
}
源碼8DataSourceInitializer.javavoid 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);}
}

由 源碼7 可知,initialize方法會廣播一個DataSourceSchemaCreatedEvent事件,回調(diào)onApplicationEvent方法,最終執(zhí)行DataSourceInitializer類的initSchema方法。

由 源碼8 可知,initSchema方法和createSchema方法大同小異,不同的是initSchema方法尋找資源文件的依據(jù)是全局配置文件中的spring.datasource.data屬性,如果沒有配置該屬性,則加載名為data-all.sql和data.sql的資源文件。

總結(jié)一下,有了DataSourceInitializerInvoker的設(shè)計,使得項目開發(fā)中,可以自定義DDL語句和DML語句并保存在SQL文件中,放置在resources目錄下,在項目啟動時自動初始化數(shù)據(jù)庫表結(jié)構(gòu)和數(shù)據(jù)。

10.2.1.2 DataSourceInitializerPostProcessor

由類名理解,這是一個專門為DataSourceInitializer定制的后置處理器。

源碼9DataSourceInitializerPostProcessor.java@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof DataSource) {this.beanFactory.getBean(DataSourceInitializerInvoker.class);}return bean;
}

由 源碼9 可知,當DataSourceInitializerPostProcessor檢測到當前正在創(chuàng)建的bean對象的類型是DataSource,主動調(diào)用BeanFactory的getBean方法創(chuàng)建一個DataSourceInitializerInvoker對象。這樣做的目的是使預(yù)定定義好的SQL腳本立即執(zhí)行,以確保DataSource與數(shù)據(jù)庫表結(jié)構(gòu)、數(shù)據(jù)的同步初始化。

10.2.2 創(chuàng)建JdbcTemplate

源碼10JdbcTemplateAutoConfiguration.java@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(JdbcProperties.class)
@Import({ JdbcTemplateConfiguration.class, NamedParameterJdbcTemplateConfiguration.class })
public class JdbcTemplateAutoConfiguration {}

由 源碼10 可知,自動配置類JdbcTemplateAutoConfiguration會使用@Import注解注冊一個JdbcTemplateConfiguration配置類和一個NamedParameterJdbcTemplateConfiguration配置類。

源碼11JdbcTemplateConfiguration.java@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(JdbcOperations.class)
class JdbcTemplateConfiguration {@Bean@PrimaryJdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);JdbcProperties.Template template = properties.getTemplate();jdbcTemplate.setFetchSize(template.getFetchSize());jdbcTemplate.setMaxRows(template.getMaxRows());if (template.getQueryTimeout() != null) {jdbcTemplate.setQueryTimeout((int) template.getQueryTimeout().getSeconds());}return jdbcTemplate;}}

由 源碼11 可知,JdbcTemplateConfiguration配置類會注冊一個JdbcTemplate對象,用于與數(shù)據(jù)庫的簡單交互。

源碼12NamedParameterJdbcTemplateConfiguration.java@Configuration(proxyBeanMethods = false)
@ConditionalOnSingleCandidate(JdbcTemplate.class)
@ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
class NamedParameterJdbcTemplateConfiguration {@Bean@PrimaryNamedParameterJdbcTemplate namedParameterJdbcTemplate(JdbcTemplate jdbcTemplate) {return new NamedParameterJdbcTemplate(jdbcTemplate);}}

由 源碼12 可知,NamedParameterJdbcTemplateConfiguration配置類會注冊一個NamedParameterJdbcTemplate對象,用于支持參數(shù)命名化的JdbcTemplate增強。

10.2.3 配置事務(wù)管理器

源碼13DataSourceTransactionManagerAutoConfiguration.java@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({JdbcTemplate.class, PlatformTransactionManager.class})
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceTransactionManagerAutoConfiguration {@Configuration(proxyBeanMethods = false)@ConditionalOnSingleCandidate(DataSource.class)static class DataSourceTransactionManagerConfiguration {@Bean@ConditionalOnMissingBean(PlatformTransactionManager.class)DataSourceTransactionManager transactionManager(DataSource dataSource,ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));return transactionManager;}}}

由 源碼13 可知,自動配置類DataSourceTransactionManagerAutoConfiguration會注冊一個DataSourceTransactionManager,用于支持基于數(shù)據(jù)源的事務(wù)控制。

······

本節(jié)完,更多內(nèi)容請查閱分類專欄:SpringBoot源碼解讀與原理分析

http://aloenet.com.cn/news/47512.html

相關(guān)文章:

  • 佛山專業(yè)網(wǎng)站營銷seo是什么意思網(wǎng)絡(luò)用語
  • 平面設(shè)計類網(wǎng)站app開發(fā)公司排行榜
  • 湖南建設(shè)廳網(wǎng)站不良記錄數(shù)據(jù)分析師資格證書怎么考
  • 門戶網(wǎng)站意思種子搜索引擎在線
  • 做網(wǎng)站業(yè)務(wù)員提成幾個點網(wǎng)絡(luò)營銷的渠道有哪些
  • 建設(shè)網(wǎng)站的目的服裝類鎮(zhèn)江網(wǎng)站定制
  • 蕪湖做網(wǎng)站的鄧健照片企業(yè)培訓(xùn)
  • 做網(wǎng)站的費用 可以抵扣嗎網(wǎng)絡(luò)整合營銷4i原則
  • 下載app軟件安裝搜索引擎優(yōu)化公司排行
  • 網(wǎng)站開發(fā)連接形式合肥網(wǎng)站優(yōu)化推廣方案
  • 刪除wordpress站高端營銷型網(wǎng)站
  • 做外貿(mào)網(wǎng)站怎么訪問外國網(wǎng)站成品影視app開發(fā)
  • 網(wǎng)站個人備案 企業(yè)備案嗎新冠疫情最新情況最新消息
  • wordpress儀表盤訪問不了網(wǎng)站seo視頻
  • 做網(wǎng)站的公司哪好專業(yè)網(wǎng)站優(yōu)化公司
  • 西安網(wǎng)站建設(shè)哪個平臺好品牌營銷服務(wù)
  • wordpress卡車主題深圳外貿(mào)seo
  • 網(wǎng)站獨立ip多代表什么灰色詞快速排名接單
  • 安徽房和城鄉(xiāng)建設(shè)部網(wǎng)站網(wǎng)站優(yōu)化排名技巧
  • 創(chuàng)立制作網(wǎng)站公司國家免費培訓(xùn)機構(gòu)
  • wordpress 導(dǎo)入限制seo sem
  • 關(guān)于優(yōu)化調(diào)整疫情防控相關(guān)措施seo優(yōu)化技術(shù)排名
  • 如何入侵自己做的網(wǎng)站網(wǎng)絡(luò)營銷最基本的應(yīng)用方式是什么
  • 做優(yōu)惠卷網(wǎng)站倒閉了多少錢黃頁引流推廣
  • 自己做網(wǎng)站的優(yōu)勢自己開網(wǎng)站怎么開
  • 新手做網(wǎng)站教程網(wǎng)站seo如何做好優(yōu)化
  • 新手如何做海外網(wǎng)站代購優(yōu)化網(wǎng)絡(luò)的軟件
  • 論文引用網(wǎng)站數(shù)據(jù) 如何做注釋互聯(lián)網(wǎng)銷售公司
  • 網(wǎng)絡(luò)科技公司 網(wǎng)站建設(shè)百度廣告推廣費用
  • 北京做網(wǎng)站費用深圳全網(wǎng)營銷系統(tǒng)