mysql创建表并初始化_APDPlat如何自动建库建表并初始化数据?

APDPlat共支持10种数据库:DB2、DERBY、H2、HSQL、INFORMIX、MYSQL、ORACLE、POSTGRESQL、SQL_SERVER、SYBASE。

数据库的默认配置信息在文件APDPlat_Core/src/main/resources/org/apdplat/db.properties中定义,用户可以根据自己的选择,在APDPlat_Web/src/main/resources/db.local.properties配置文件中覆盖默认配置。

1、如何指定使用哪一种数据库呢?

jpa.database=MYSQL

jpa.database配置项的值可为上述10种数据库之一,10种数据库的JDBC驱动已经集成到APDPlat中,其中5种定义到maven配置文件APDPlat_Web/pom.xml的依赖中,其余5种放置在APDPlat_Web/src/main/webapp/WEB-INF/lib目录中。

2、如何配置数据库连接信息呢?

#mysql

db.driver=com.mysql.jdbc.Driver

db.url=jdbc:mysql://localhost:3306/${module.short.name}?useUnicode=true&characterEncoding=UTF-8&createDatabaseIfNotExist=true&autoReconnect=true

db.username=root

db.password=root

jpa.database=MYSQL

db.backup.command=mysqldump -u${db.username} -p${db.password} ${module.short.name}

db.restore.command=mysql -u${db.username} -p${db.password} ${module.short.name}

db.forlog.driver=com.mysql.jdbc.Driver

db.forlog.url=jdbc:mysql://localhost:3306/${module.short.name}_for_log?useUnicode=true&characterEncoding=UTF-8&createDatabaseIfNotExist=true&autoReconnect=true

db.forlog.username=root

db.forlog.password=root

jpa.forlog.database=MYSQL

在文件APDPlat_Core/src/main/resources/org/apdplat/db.properties中已经预先定义了10种数据库的连接信息,用户可在此基础上修改成适合自己的连接信息,然后放置到配置文件APDPlat_Web/src/main/resources/db.local.properties中覆盖默认配置。

对于MYSQL数据库来说,因为指定了createDatabaseIfNotExist=true选项,所以会自动建库。ORACLE和SQL_SERVER需要手动建库。其他数据库请参考相关的JDBC编程指南文档,总之,在这里只需要提供标准的JDBC编程所需的信息:driver、url、username、password。

3、表是怎么建的呢?

表是自动建的,不需要手动执行数据库DDL,是由如下配置指定的:

jpa.generateDdl=true

在文件APDPlat_Core/src/main/resources/org/apdplat/db.properties中还定义了数据库连接池以及数据库缓存的配置信息,详情参考配置文件。

4、初始数据是怎么导入的?

初始数据是在系统启动的时候自动导入的,不需要手工执行SQL脚本导入数据。RegisterService抽象类为数据导入提供了支持,在Spring容器初始完毕后就会检查是否需要导入数据,只有在表为空的情况下才会执行导入,也就是说能够保证只会导入一次,执行导入调用的是抽象方法registe,需要子类来实现,这是一个典型的"模板方法"设计模式:

public abstract class RegisterService implements ApplicationListener {

protected final APDPlatLogger LOG = APDPlatLoggerFactory.getAPDPlatLogger(getClass());

@Resource(name="serviceFacade")

protected ServiceFacade serviceFacade;

@Resource(name="entityManagerFactory")

protected EntityManagerFactory entityManagerFactory;

protected Class modelClass;

@Override

public void onApplicationEvent(ApplicationEvent event){

if(event instanceof ContextRefreshedEvent){

this.modelClass = ReflectionUtils.getSuperClassGenricType(getClass());

LOG.info("spring容器初始化完成, 开始检查 "+ModelMetaData.getMetaData(this.modelClass.getSimpleName()) +" 是否需要初始化数据");

if(shouldRegister()){

LOG.info("需要初始化 "+ModelMetaData.getMetaData(this.modelClass.getSimpleName()));

openEntityManager();

registe();

closeEntityManager();

registeSuccess();

}else{

LOG.info("不需要初始化 "+ModelMetaData.getMetaData(this.modelClass.getSimpleName()));

}

}

}

private void openEntityManager(){

EntityManager em = entityManagerFactory.createEntityManager();

TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(em));

LOG.info("打开实体管理器");

}

private void closeEntityManager(){

EntityManagerHolder emHolder = (EntityManagerHolder)TransactionSynchronizationManager.unbindResource(entityManagerFactory);

LOG.info("关闭实体管理器");

EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());

}

protected void registeSuccess(){

}

protected List getRegisteData(){

return null;

}

protected abstract void registe();

protected boolean shouldRegister() {

Page page=serviceFacade.query(modelClass);

if(page.getTotalRecords()==0) {

return true;

}

return false;

}

}

下面我们看一个导入用户数据(至少数据库中有用户数据才能登陆吧)的例子,这里RegisteUser 实现了抽象类RegisterService的抽象方法registe,执行真正的数据导入操作。从这里我们可以看到,用户数据是从类路径下的/data/user.xml文件中获得的。事实上,这个文件是在APDPlat启动的时候从APDPlat_Core-X.X.jar中提取出来的。这里使用了Page的newInstance静态方法把一个XML数据文件转换为了JAVA页面对象。之后设置用户数据的依赖,即用户所属的组织架构和角色,注意这里的导入是有先后顺序的,需要保证顺序。

/**

* 注册用户数据,这里需要注意的是:

* 因为User有一个Org字段和一个Role列表(protected Org org; protected List roles = new ArrayList<>();)

* 所以要先注册了Org和Role之后才能注册用户

* 但是RegisteUser、RegisteOrg以及RegisteRole都继承自RegisterService

* 都实现了Spring的ApplicationListener接口

* 那么Spring会先调用谁呢?

* 为了保证先注册Org和Role

* RegisteUser类用@Resource注解注入了RegisteOrg和RegisteRole,分别用来获取Org和Role

* Spring保证会在装配完成RegisteOrg和RegisteRole之后才装配RegisteUser

* 而装配的先后顺序也就是Spring调用实现ApplicationListener接口的Bean的顺序

* 因此,这里的注册数据依赖问题就完美地解决了

* @author 杨尚川

*/

@Service

public class RegisteUser extends RegisterService{

@Resource(name="registeOrg")

protected RegisteOrg registeOrg;

@Resource(name="registeRole")

protected RegisteRole registeRole;

@Override

protected void registe() {

String xml="/data/user.xml";

LOG.info("注册【"+xml+"】文件");

LOG.info("验证【"+xml+"】文件");

boolean pass=XMLUtils.validateXML(xml);

if(!pass){

LOG.info("验证没有通过,请参考dtd文件");

return ;

}

LOG.info("验证通过");

Page page=Page.newInstance(User.class, RegisteUser.class.getResourceAsStream(xml));

if(page!=null){

for(User user : page.getModels()){

user.setPassword(PasswordEncoder.encode(user.getPassword(), user));

user.setOrg(registeOrg.getRegisteData().get(0));

user.addRole(registeRole.getRegisteData().get(0).getChild().get(0));

serviceFacade.create(user);

}

}

}

}

最后看一下数据文件/data/user.xml的内容:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值