Java tutorial
/******************************************************************************* * Copyright (C) 2018 hankai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ******************************************************************************/ package ren.hankai.cordwood.data.jpa.config; import com.alibaba.druid.filter.Filter; import com.alibaba.druid.filter.logging.Slf4jLogFilter; import com.alibaba.druid.filter.stat.StatFilter; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.wall.WallFilter; import org.apache.commons.lang3.StringUtils; import org.eclipse.persistence.platform.database.HSQLPlatform; import org.eclipse.persistence.platform.database.MySQLPlatform; import org.eclipse.persistence.platform.database.OraclePlatform; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import ren.hankai.cordwood.core.Preferences; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; import javax.sql.DataSource; /** * ??? * * @author hankai * @version 1.0.0 * @since Aug 18, 2016 2:19:51 PM */ public abstract class JpaDataSourceConfig { private static final Logger logger = LoggerFactory.getLogger(JpaDataSourceConfig.class); protected static String[] basePackages = null; /** * ???????????? ??? * * @return ?? * @author hankai * @since Jun 21, 2016 10:45:48 AM */ private static Properties loadExternalConfig(String fileName) { Properties props = null; try { props = new Properties(); props.load(new FileInputStream(Preferences.getDbConfigFile(fileName))); } catch (final IOException ex) { logger.warn("Failed to load external database configuration file for production profile.", ex); } if ((props != null) && (props.size() > 0)) { return props; } return null; } /** * ? * * @param props ???? * @param dataSource Druid?? * @author hankai * @since Dec 3, 2018 5:23:54 PM */ private static void configureFilters(Properties props, DruidDataSource dataSource) { final List<Filter> filters = new ArrayList<>(); // SQL final StatFilter statFilter = new StatFilter(); String param = props.getProperty("pool.slow.sql.millis", "5000"); statFilter.setSlowSqlMillis(Long.parseLong(param)); param = props.getProperty("pool.log.slow.sql", "true"); statFilter.setLogSlowSql(Boolean.parseBoolean(param)); statFilter.setMergeSql(true); // ??sql filters.add(statFilter); // ? // SLF4J final Slf4jLogFilter slf4jLogFilter = new Slf4jLogFilter(); slf4jLogFilter.setResultSetLogEnabled(false); filters.add(slf4jLogFilter); // SQL param = props.getProperty("pool.check.sql.injection", "false"); if (Boolean.parseBoolean(param)) { // Druid wall filter ? https://github.com/alibaba/druid/wiki/?-wallfilter final WallFilter wallFilter = new WallFilter(); // wallFilter.getConfig().setXX wallFilter.setLogViolation(true);// SQL? filters.add(wallFilter); } dataSource.setProxyFilters(filters); } /** * ???? * * @param props ???e.g. mysql.properties * @param dataSource Druid ?? * @author hankai * @since Jul 31, 2018 3:21:48 PM */ private static void configureDataSourcePool(Properties props, DruidDataSource dataSource) { // url?user?password dataSource.setDriverClassName(props.getProperty("driverClassName")); dataSource.setUrl(props.getProperty("url")); dataSource.setUsername(props.getProperty("username")); dataSource.setPassword(props.getProperty("password")); // ?????? String param = props.getProperty("pool.initial.size", "1"); dataSource.setInitialSize(Integer.parseInt(param)); param = props.getProperty("pool.min.idle", "1"); dataSource.setMinIdle(Integer.parseInt(param)); param = props.getProperty("pool.max.active", "20"); dataSource.setMaxActive(Integer.parseInt(param)); // ?? param = props.getProperty("pool.max.wait", "60000"); dataSource.setMaxWait(Long.parseLong(param)); // ????? param = props.getProperty("pool.time.between.eviction.runs.millis", "60000"); dataSource.setTimeBetweenEvictionRunsMillis(Long.parseLong(param)); // ???? param = props.getProperty("pool.min.evictable.idle.time.millis", "300000"); dataSource.setMinEvictableIdleTimeMillis(Long.parseLong(param)); dataSource.setTestWhileIdle(true);// ?? dataSource.setTestOnBorrow(false);// ??? dataSource.setTestOnReturn(false);// ?? // PSCache?PSCache? dataSource.setPoolPreparedStatements(true); dataSource.setMaxPoolPreparedStatementPerConnectionSize(20); param = props.getProperty("pool.debug", "false"); if (Boolean.parseBoolean(param)) { // ?? dataSource.setRemoveAbandoned(true); // ?? param = props.getProperty("pool.remove.abandoned.timeout", "180"); dataSource.setRemoveAbandonedTimeout(Integer.parseInt(param)); dataSource.setLogAbandoned(true); } else { dataSource.setRemoveAbandoned(false); } // ? configureFilters(props, dataSource); } /** * ?? */ public JpaDataSourceConfig() { String pkg = this.getClass().getPackage().getName(); if (StringUtils.isNotEmpty(pkg) && (basePackages == null)) { pkg = pkg.split("\\.")[0]; basePackages = new String[] { pkg }; } } /** * HSQL ??? * * @author hankai * @version 1.0.0 * @since Jul 31, 2018 2:59:52 PM */ @Profile(Preferences.PROFILE_HSQL) @Configuration public static class HsqlConfig { /** * ?? * * @return ?? * @author hankai * @since Oct 25, 2016 11:35:04 AM */ @Bean public DataSource dataSource() { final Properties props = loadExternalConfig("hsql.properties"); // ?????? String url = props.getProperty("url"); if (url.contains("%s")) { // ???? final String dbPath = Preferences.getDbDir() + File.separator + "application"; url = String.format(props.getProperty("url"), dbPath); props.setProperty("url", url); } final DruidDataSource dataSource = new DruidDataSource(); configureDataSourcePool(props, dataSource); // ??sql? dataSource.setValidationQuery("SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS"); return dataSource; } /** * ???? * * @return ???? * @author hankai * @since Oct 25, 2016 11:35:17 AM */ @Bean public JpaDataSourceInfo dataSourceInfo() { return new JpaDataSourceInfo(HSQLPlatform.class.getName(), basePackages); } } /** * MySQL ??? * * @author hankai * @version 1.0.0 * @since Jul 31, 2018 3:00:14 PM */ @Configuration @Profile(Preferences.PROFILE_MYSQL) public static class MySqlConfig { /** * MySQL ?? * * @return ?? * @author hankai * @since Oct 25, 2016 11:35:34 AM */ @Bean public DataSource dataSource() { final Properties props = loadExternalConfig("mysql.properties"); final DruidDataSource dataSource = new DruidDataSource(); configureDataSourcePool(props, dataSource); dataSource.setValidationQuery("select 1");// ??sql? return dataSource; } @Bean public JpaDataSourceInfo dataSourceInfo() { return new JpaDataSourceInfo(MySQLPlatform.class.getName(), basePackages); } } /** * Oracle ??? * * @author hankai * @version 1.0.0 * @since Jul 31, 2018 3:00:41 PM */ @Configuration @Profile(Preferences.PROFILE_ORACLE) public static class OracleConfig { /** * ORACLE ?? * * @return ?? * @author hankai * @since Oct 25, 2016 11:35:50 AM */ @Bean public DataSource dataSource() { final Properties props = loadExternalConfig("oracle.properties"); final DruidDataSource dataSource = new DruidDataSource(); configureDataSourcePool(props, dataSource); dataSource.setValidationQuery("select * from dual");// ??sql? return dataSource; } @Bean public JpaDataSourceInfo dataSourceInfo() { return new JpaDataSourceInfo(OraclePlatform.class.getName(), basePackages); } } }