? ? ? ? ? ? ? ? ? ? ?
Jpa與Druid線程池及Spring Boot整合(一)
Jpa與Druid線程池及Spring Boot整合(二):幾個坑
附錄官網(wǎng)文檔:core.domain-events域事件
docker實戰(zhàn)(一):centos7 yum安裝docker
docker實戰(zhàn)(二):基礎(chǔ)命令篇
docker實戰(zhàn)(三):docker網(wǎng)絡(luò)模式(超詳細)
docker實戰(zhàn)(四):docker架構(gòu)原理
docker實戰(zhàn)(五):docker鏡像及倉庫配置
docker實戰(zhàn)(六):docker 網(wǎng)絡(luò)及數(shù)據(jù)卷設(shè)置
docker實戰(zhàn)(七):docker 性質(zhì)及版本選擇
認知升維: 道、法、術(shù)、器、勢
(一)Jpa與Druid連接池及Spring Boot整合作為持久層,遇到系列問題,下面一 一記錄:
pom.xml 文件中加入必須的依賴:
<!--設(shè)置spring-boot依賴的版本 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.5</version> <!--2.4.11--> <relativePath/> </parent>
<properties> <lombok.version>1.18.22</lombok.version> <hutool-all.version>5.8.18</hutool-all.version> <druid.version>1.2.16</druid.version> <mysql-connector-java.version>8.0.28</mysql-connector-java.version> </properties>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>${hutool-all.version}</version> </dependency> <!--連接mysql數(shù)據(jù)庫的驅(qū)動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector-java.version}</version> </dependency> <!--阿里巴巴開源的線程池連接框架--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency><!-- spring-boot與jpa整合--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 端點監(jiān)控的配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.hateoas</groupId> <artifactId>spring-hateoas</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
(二) application.yml配置文件
server: port: 9999 servlet: context-path: / spring: #使用JPA作為持久層框架與MYSQL整合---Begin--------------------- datasource: url: jdbc:mysql://localhost:3306/tope-pay-user?&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&useSSL=false username: root password: 123456 driverClassName: com.mysql.cj.jdbc.Driver # 8.0意思mysql驅(qū)動 type: com.alibaba.druid.pool.DruidDataSource # 初始化大小,最小,最大 initialSize: 5 minIdle: 5 maxActive: 20 # 配置獲取連接等待超時的時間 maxWait: 60000 # 配置間隔多久才進行一次檢測,檢測需要關(guān)閉的空閑連接,單位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一個連接在池中最小生存的時間,單位是毫秒 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false # 打開PSCache,并且指定每個連接上PSCache的大小 poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 # 配置監(jiān)控統(tǒng)計攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計,'wall'用于防火墻 filters: stat,wall,log4j # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多個DruidDataSource的監(jiān)控數(shù)據(jù) #spring.datasource.useGlobalDataSourceStat=true jpa: properties: hibernate: dialect: org.hibernate.dialect.MySQL5Dialect # stripped before adding them to the entity manager) database: MYSQL show-sql: true # 打印執(zhí)行的SQL hibernate: ddl-auto: update # Hibernate ddl auto (create, create-drop, update, validate, none) naming: implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy #使用JPA作為持久層框架與MYSQL整合---end---------------------
編寫Druid(alibaba數(shù)據(jù)庫連接池)初始化配置:
package org.jd.websocket.auth.data.reactor.config; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.*; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import java.sql.SQLException; /** * @Transactiona在多數(shù)據(jù)源下失效 * 在多數(shù)據(jù)源的情況下,如果transactionManager進行了分開配置,比如這里針對三個數(shù)據(jù)源配置了三個transactionManager * =========================================================================================================== * @Bean("formTransactionManager") * public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) { * return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory(builder).getObject())); * } *============================================================================================================= * @Bean("fileTransactionManager") * public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) { * return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory(builder).getObject())); * } * ============================================================================================================ * @Primary * @Bean("userTransactionManager") * public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) { * return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory(builder).getObject())); * } * ============================================================================================================= * * 那么在使用@Transactional的時候需要指定transactionManager * @Transactional("formTransactionManager") * * * * * * * Jpa與Druid線程池整合作為持久層 */ @Configuration @EntityScan(basePackages = "org.jd.websocket.auth.data.reactor.jpa") @EnableTransactionManagement // 開啟事務(wù)的支持 @EnableJpaRepositories(basePackages = {"org.jd.websocket.auth.data.reactor.repository","org.jd.websocket.auth.data.reactor.jpa"}, includeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*CrudRepository")}, excludeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*SomeOtherRepository")}) public class JpaDruidConfig { @Value("${spring.datasource.url}") private String dbUrl; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; @Value("${spring.datasource.driver-class-name}") private String driverClassName; @Value("${spring.datasource.initialSize}") private int initialSize; @Value("${spring.datasource.minIdle}") private int minIdle; @Value("${spring.datasource.maxActive}") private int maxActive; @Value("${spring.datasource.maxWait}") private int maxWait; @Value("${spring.datasource.timeBetweenEvictionRunsMillis}") private int timeBetweenEvictionRunsMillis; @Value("${spring.datasource.minEvictableIdleTimeMillis}") private int minEvictableIdleTimeMillis; @Value("${spring.datasource.validationQuery}") private String validationQuery; @Value("${spring.datasource.testWhileIdle}") private boolean testWhileIdle; @Value("${spring.datasource.testOnBorrow}") private boolean testOnBorrow; @Value("${spring.datasource.testOnReturn}") private boolean testOnReturn; @Value("${spring.datasource.poolPreparedStatements}") private boolean poolPreparedStatements; @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}") private int maxPoolPreparedStatementPerConnectionSize; @Value("${spring.datasource.filters}") private String filters; @Value("{spring.datasource.connectionProperties}") private String connectionProperties; @Bean @Primary public DataSource dataSource() { DruidDataSource datasource = new DruidDataSource(); datasource.setUrl(dbUrl); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(driverClassName); // configuration datasource.setInitialSize(initialSize); datasource.setMinIdle(minIdle); datasource.setMaxActive(maxActive); datasource.setMaxWait(maxWait); datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setValidationQuery(validationQuery); datasource.setTestWhileIdle(testWhileIdle); datasource.setTestOnBorrow(testOnBorrow); datasource.setTestOnReturn(testOnReturn); datasource.setPoolPreparedStatements(poolPreparedStatements); datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); try { datasource.setFilters(filters); } catch (SQLException e) { System.err.println("druid configuration initialization filter: " + e); } datasource.setConnectionProperties(connectionProperties); return datasource; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); // entity掃描的包路徑 factory.setPackagesToScan("org.jd.websocket.auth.data.reactor.jpa"); factory.setDataSource(dataSource()); return factory; } /** * * @param entityManagerFactory * @return */ @Primary @Bean(name = "userJpaTransactionManager") public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory); return txManager; } @Bean public ServletRegistrationBean statViewServlet() { System.out.print("init Druid Monitor Servlet ..."); ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); servletRegistrationBean.addInitParameter("allow", "127.0.0.1"); // IP黑名單(共同存在時,deny優(yōu)先于allow) servletRegistrationBean.addInitParameter("deny", "192.168.1.100"); //控制臺管理用戶 servletRegistrationBean.addInitParameter("loginUsername", "admin"); servletRegistrationBean.addInitParameter("loginPassword", "123456"); servletRegistrationBean.addInitParameter("resetEnable", "false"); System.out.print("注冊成功"); return servletRegistrationBean; } @Bean public FilterRegistrationBean startFilter() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); filterRegistrationBean.addUrlPatterns("/*"); // 忽略過濾的格式 filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return filterRegistrationBean; } }
啟動報錯:
init Druid Monitor Servlet ...注冊成功2023-08-10 21:03:14.026 ?INFO 10256 --- [ ?restartedMain] c.github.jasync.sql.db.util.NettyUtils ? : jasync selected transport - nio
2023-08-10 21:03:14.221 ?WARN 10256 --- [ ?restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/jd/websocket/auth/data/reactor/config/JpaDruidConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/log4j/Logger
2023-08-10 21:03:14.233 ?INFO 10256 --- [ ?restartedMain] o.apache.catalina.core.StandardService ? : Stopping service [Tomcat]
2023-08-10 21:03:14.271 ?INFO 10256 --- [ ?restartedMain] ConditionEvaluationReportLoggingListener :?Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-08-10 21:03:14.331 ERROR 10256 --- [ ?restartedMain] o.s.boot.SpringApplication ? ? ? ? ? ? ? : Application run failed
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/jd/websocket/auth/data/reactor/config/JpaDruidConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/log4j/Logger?? ?... 33 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/log4j/Logger
?? ?at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.17.jar:5.3.17]
?? ?at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.17.jar:5.3.17]
?? ?... 47 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/apache/log4j/Logger
?? ?at com.alibaba.druid.filter.logging.Log4jFilter.<init>(Log4jFilter.java:25) ~[druid-1.2.16.jar:na]
?? ?at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_221]
?? ?at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_221]
?? ?at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_221]
?? ?at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_221]?java.lang.NoClassDefFoundError: org/apache/log4j/Logger 報錯最終信息
?問題一: 缺少,Druid初始化化依賴?org/apache/log4j/Logger;但是不應(yīng)該呀,Spring-Boot不是已經(jīng)添加了該依賴嗎,百思不得其解....于是翻下相應(yīng)包是否依賴,如下圖,都沒引入該包的依賴....
?引入Logger三角坐標(biāo):
<!-- spring-boot與jpa整合,當(dāng)前者版本依賴這個,需要加上,否則啟動不了--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
再次啟動項目: 可以正常啟動但是有個警告:
log4j:WARN No appenders could be found for logger (druid.sql.Connection).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
文章來源:http://www.zghlxwxcb.cn/news/detail-639514.html
?很明顯druid啟動過程會加載日志配置文件. 在resources目錄下面新建"log4j.properties"文件,內(nèi)容如下,啟動就正常了;文章來源地址http://www.zghlxwxcb.cn/news/detail-639514.html
log4j.rootLogger=INFO,toFile,toConsole ######## 輸出到到文件 ########## log4j.appender.toFile=org.apache.log4j.FileAppender log4j.appender.toFile.layout=org.apache.log4j.PatternLayout log4j.appender.toFile.file=test.log ######## 輸出到到控制臺 ########## log4j.appender.toConsole=org.apache.log4j.ConsoleAppender log4j.appender.toConsole.layout=org.apache.log4j.PatternLayout
到了這里,關(guān)于Jpa與Druid線程池及Spring Boot整合(一): spring-boot-starter-data-jpa 搭建持久層的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!