一、废话
今天项目经理给了我一个任务,就是需要将一个数据库中字典表的数据,相对应的添加到另外一张表中,这里将有数据的字典表成为dict嘛,需要添加数据的表为test表,我写的demo中表名也是这样的。
当然呢,最开始我也是手动写SQL语句添加数据,搞了一两个字典数据,就着不住了,实际项目中的字典表数据是非常多的。一个字典类型有的就上千条数据,我一想,像我楞个加,得加到什么时候去。
先想到的就是在原项目中再加一个数据源,搞了半天,一直给我报错,然后我就果然放弃了,然后打算自己新建项目,然后印象中记得当时熟悉项目框架时,好像记得是有demo的。那就不用自己去引依赖啥的了,下载下来,直接用。
我当时就是用的这个:JFinal demo for maven 5.0.0
二、配置数据源
使用JFinal项目的话需要有一定的Java基础,maven环境这些都不说了,没有配置的,百度百度一大堆教程
1.创建表
CREATE DATABASE test;
CREATE TABLE `dict` (
`id` int NOT NULL COMMENT '主键ID',
`code_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典类型',
`code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典值',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典值名称',
`order_id` int DEFAULT NULL COMMENT '排序号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
# 由于下载的项目里面有一个Blog实体类,会影响项目启动,可以将其删掉,也可以在数据库中添加一张表
CREATE TABLE `blog` (
`id` int NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
我这里是使用的mysql数据库两个数据库测试的,你也可以用两种数据库mysql或者oracle,或者其他sql server等
CREATE DATABASE blog;
CREATE TABLE `test` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID主键',
`code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典值',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字典值名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
2.配置demo-config-dev.txt文件
可以直接复制过去用,也可以根据自己的修改
devMode = true
jdbcUrl = jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
user = root
password = 123456
jdbcUrl1 = jdbc:mysql://127.0.0.1:3306/blog?characterEncoding=utf8
user1 = root
password1 = 123456
3.配置DemoConfig.java文件
在项目的/src/main/java/com/demo/common文件下有一个DemoConfig.java文件,也是该项目的启动类
(1)要将configConstant方法中的devMode改为true
/**
* 配置常量
*/
public void configConstant(Constants me) {
loadConfig();
me.setDevMode(p.getBoolean("devMode", true));
/**
* 支持 Controller、Interceptor、Validator 之中使用 @Inject 注入业务层,并且自动实现 AOP
* 注入动作支持任意深度并自动处理循环注入
*/
me.setInjectDependency(true);
// 配置对超类中的属性进行注入
me.setInjectSuperClass(true);
}
(2)然后就是数据源的配置
/**
* 配置插件
*/
public void configPlugin(Plugins me) {
// 配置 druid 数据库连接池插件
DruidPlugin druidPlugin = new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password"));
me.add(druidPlugin);
// 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin("dictDB", druidPlugin);
// 所有映射在 MappingKit 中自动化搞定
_MappingKit.mapping(arp);
arp.addMapping("blog", "id", Blog.class);
arp.addMapping("dict", "id", Dict.class);
me.add(arp);
DruidPlugin testDP = new DruidPlugin(p.get("jdbcUrl1"), p.get("user1"), p.get("password1"));
me.add(testDP);
ActiveRecordPlugin testARP = new ActiveRecordPlugin("testDB", testDP);
testARP.setDialect(new MysqlDialect());
testARP.addMapping("test", "id", Test.class);
_MappingKit.mapping(testARP);
me.add(testARP);
}
注意!如果启动项目时会报错某某.某某表不存在的话,可以将_Mapping.java文件中的blog表的配置注释掉,我上面也配置了的
public static void mapping(ActiveRecordPlugin arp) {
// arp.addMapping("blog", "id", Blog.class);
// arp.addMapping("dict", "id", Dict.class);
// arp.addMapping("test", "id", Test.class);
}
三、实现数据迁移
在IndexController中的新建一个方法copyDictData,这里只是写了简单的逻辑,实际项目开发中的字段肯定很多,需要判断,那些需要,那些不需要,是否会有上下级这些,都要判断,这都要根据你的实际情况来了,我这里都不写项目中的东西了,保密!!!
public void copyDictData() {
// 获取字典表数据
List<Dict> dictList = Dict.dao.findAll();
// 获取表中id的最大值
Integer max = Db.use("testDB").findFirst("select max(id) as id from test").getInt("id");
AtomicLong id = new AtomicLong(max + 1);
System.out.println(max);
// 将获取到的数据保存到test表中
List<Test> testList = new ArrayList<>();
dictList.forEach(dict -> {
Test test = new Test();
test.set("id", id.getAndIncrement());
test.set("name", dict.getStr("name"));
test.set("code", dict.getStr("code"));
testList.add(test);
});
// 事务
boolean tx = Db.use("testDB").tx(() -> {
Db.use("testDB").batchSave(testList, 100);
return true;
});
if(tx) {
renderJson(Ret.ok());
} else {
renderJson(Ret.fail());
}
}
到这里就可以启动项目,访问http://localhost:60/copyDictData 就可以了,页面显示{“state”:“ok”}的json数据,就应该没什么问题了
哦,对了,我这里的端口是在undertow.txt文件中配置了端口的,防止出现端口占用的问题,你也可以配置配置
# 配置 undertow
undertow.devMode=true
undertow.host=0.0.0.0
undertow.port=60
我会将我的demo代码放到gitee代码平台托管,感兴趣的小伙伴,也可以找来看看,谢谢~