JAVA工程啟動時自動建立資料庫、資料表
阿新 • • 發佈:2018-11-09
很多時候,我們會有這樣的需求:
- 系統首次部署時,自動建立資料庫、表
- 執行單元測試時,資料庫、表維持初始化狀態方便測試。
本文對這種需求的實現做了可行性驗證。
**** 注意這邊需要配置具有建庫建表許可權的資料庫使用者名稱、密碼*****
資料庫配置檔案 jdbc.properties
jdbc.driver = com.mysql.jdbc.Driver jdbc.password = root jdbc.url = jdbc:mysql://127.0.0.1:3306/jdbc-dbutils?useUnicode=true&characterEncoding=utf-8 jdbc.username = root
待執行初始化sql 指令碼 sql/init.sql ,可以多個
/* Navicat MySQL Data Transfer Source Server : mysql Source Server Version : 50559 Source Host : localhost:3306 Source Database : dbutils Target Server Type : MYSQL Target Server Version : 50559 File Encoding : 65001 Date: 2018-11-02 22:48:33 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', 'name_525', '48'); INSERT INTO `user` VALUES ('2', 'name_367', '33'); INSERT INTO `user` VALUES ('3', 'name_630', '23'); INSERT INTO `user` VALUES ('4', 'name_230', '34'); INSERT INTO `user` VALUES ('5', 'name_750', '50'); INSERT INTO `user` VALUES ('6', 'name_762', '26'); INSERT INTO `user` VALUES ('7', 'name_433', '38'); INSERT INTO `user` VALUES ('8', 'name_742', '44'); INSERT INTO `user` VALUES ('9', 'name_960', '37');
這裡只用到了Spring的JdbcTemplate ,故使用了只有單個jar包的 spring的早期版本。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.fly</groupId> <artifactId>jdbc</artifactId> <version>0.0.1-SNAPSHOT</version> <name>jdbc</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> <version>2.5.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
核心程式碼
import java.io.IOException;
import java.io.InputStream;
import java.util.ResourceBundle;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
public class JdbcTemplateTest
{
private static final Logger logger = LoggerFactory.getLogger(JdbcTemplateTest.class);
private static JdbcTemplate jdbcTemplate;
static
{
try
{
// 建庫用臨時DataSource
MysqlDataSource dataSource = new MysqlDataSource();
ResourceBundle config = ResourceBundle.getBundle("jdbc");
String jdbcUrl = StringUtils.substringBeforeLast(config.getString("jdbc.url"), "/");
dataSource.setUrl(jdbcUrl);
dataSource.setUser(config.getString("jdbc.username"));
dataSource.setPassword(config.getString("jdbc.password"));
jdbcTemplate = new JdbcTemplate(dataSource);
logger.info("JdbcTemplate = {}", jdbcTemplate);
// 取資料庫名
String dataBase = StringUtils.substringAfterLast(config.getString("jdbc.url"), "/");
dataBase = dataBase.contains("?") ? StringUtils.substringBefore(dataBase, "?") : dataBase;
logger.info("★★★★ jdbcUrl = {}, dataBase = {}", jdbcUrl, dataBase);
// 新建庫
jdbcTemplate.execute(String.format("drop database if exists `%s`;", dataBase));
jdbcTemplate.execute(String.format("create database `%s` character set utf8", dataBase));
}
catch (DataAccessException e)
{
logger.error(e.getMessage(), e);
}
}
/**
* 初始化表
*
* @throws IOException
*
*/
@Before
public void initTable()
{
try (InputStream inputStream = getClass().getResourceAsStream("/sql/init.sql"))
{
MysqlDataSource dataSource = new MysqlDataSource();
ResourceBundle config = ResourceBundle.getBundle("jdbc");
dataSource.setUrl(config.getString("jdbc.url") + "&allowMultiQueries=true"); // 設定允許一次同時執行多條語句
dataSource.setUser(config.getString("jdbc.username"));
dataSource.setPassword(config.getString("jdbc.password"));
jdbcTemplate = new JdbcTemplate(dataSource);
logger.info("JdbcTemplate = {}", jdbcTemplate);
String sqlText = IOUtils.toString(inputStream, "utf-8");
logger.info("SQL = {}", sqlText);
if (dataSource.getUrl().contains("allowMultiQueries=true"))
{
logger.info("開始執行當前的初始化語句塊");
jdbcTemplate.execute(sqlText);
}
else
{
logger.info("開始分割執行當前的初始化語句塊");
for (String sql : sqlText.split(";"))
{
if (StringUtils.isNotBlank(sql))
{
jdbcTemplate.execute(sql);
}
}
}
logger.info("★★★★ initTable success!!");
}
catch (DataAccessException | IOException e)
{
logger.error(e.getMessage(), e);
}
}
/**
* JdbcTemplate
*
* @see [類、類#方法、類#成員]
*/
@Test
public void testTemplate()
{
String sql = "select 1 from dual";
Object object = jdbcTemplate.queryForObject(sql, Integer.class);
logger.info("Execute: {} ==> {}", sql, object);
}
}
完整的專案程式碼請參考:
https://gitee.com/00fly/java-code-frame/tree/master/jdbc