开发环境搭建:
1个想法一通向导搞定spring boot
这一步,算是建造了spring + hibernate,后面还有连接池,换成mybatis的问题。
idea中Alt + Enter导入包,和eclipse有点不一样。
甲骨文罐子??:
然后狂建一堆model .....
测试运行一遍:报错:
java.lang.IllegalArgumentException: Not a managed type: class com.comm.f_olap.model.CommObject...
。实体类加上注解啥的,问题解决。
@Entity
@Table(name = "user")//数据库的表名
public class CommObject {
@Id
private int id;
@Column(name = "name")//数据库的字段名,数据库 不区分大小写 这个 要注意
.....
连接池:
spring boot自带了连接池?测试一把:
@SpringBootTest
class FOlapApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() {
System.out.println(dataSource.getClass());
}
}
结果:com.zaxxer.hikari.HikariDataSource类。
貌似HikariDataSource蛮强大,本想约会德鲁伊,有了可用的连接池,就不看其他的,否则,我可能还得做加配置文件等工作。
HikariDataSource是spring boot2才约会的。
ps:本想约会德鲁伊:
build.gradle:中加一行:
compile group: 'com.alibaba', name: 'druid', version: '1.1.10'
属性文件(application.properties)如下:
server:
port: 8881
max-http-header-size: 102400
spring:
datasource:
url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
username: SUPERVISION
password: 1
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: oracle.jdbc.OracleDriver
druid:
initial-size: 1
min-idle: 1
max-active: 300
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 30000
validation-query: SELECT 'x' from dual
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
filters: stat,slf4j
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
web-stat-filter.enabled: true
web-stat-filter.principal-session-name: username
stat-view-servlet.enabled: true
stat-view-servlet.url-pattern: /druid/*
jpa:
show-sql: true
database: oracle
properties:
hibernate:
dialect: org.hibernate.dialect.OracleDialect
enable_lazy_load_no_trans: true
open-in-view: true
运行报错:应该是还要加一个配置文件,既然用HikariDataSource,这个就不进行下去了。
持久层考虑因素:
1,我们要集成mondrian,mondrian好像是jdbc直连,所以测试一下mondrian集成在spring boot 2.0下的表现。
从2个方面测试,一个是mondrian直联jdbc,一个是和spring boot jdbc template Integrated?
2,我们项目用hibernate还是mybatis?
hibernate?对我来说,类是继承的pojo,hibernate如何实现,得测试一遍。
mybatis?貌似蛮灵活,但可以点击,也得测试一遍。
因此,我们要从三个方面进行测试:
- mondrian集成;
- hibrenate中,pojo是继承关系的rud测试。
- mybatis测试。
spring boot环境下 mondrian集成:
mondrian集成?参考我前面写的《非税olap分析平台的设计与实现(二)_测试开发配置》。
测试不成功,可能是代理,GW惹的祸?
不管它:
直接约会lib,
gradle中,加入 dependencies{compile files('lib/mondrian-4.7.0.0-12.jar')} ok!
搭建环境中,没必要掌握所有细节,还是得以解决问题为导向。
mondrian集成过程:gradle中添加如下内容(也许有多的jar):
dependencies{compile files('lib/mondrian-4.7.0.0-12.jar')}
dependencies{compile files('lib/eigenbase-xom-1.3.4.jar')}
dependencies{compile files('lib/eigenbase-resgen-1.3.1.jar')}
compile group: 'org.olap4j', name: 'olap4j', version: '1.2.0'
compile group: 'org.olap4j', name: 'olap4j-xmlaserver', version: '1.2.0'
//compile group: 'eigenbase', name: 'eigenbase-xom', version: '1.3.4'
compile group: 'net.hydromatic', name: 'eigenbase-properties', version: '1.1.5'
//compile group: 'eigenbase', name: 'eigenbase-resgen', version: '1.3.1'
compile group: 'commons-math', name: 'commons-math', version: '1.2'
compile group: 'apache-log4j', name: 'log4j', version: '1.2.14'
compile group: 'commons-vfs', name: 'commons-vfs', version: '1.0'
compile group: 'org.apache.commons', name: 'commons-vfs2', version: '2.1'
但 测试运行报错:
org.apache.commons.vfs.FileSystemException: Could not create a file system manager of class "org.apache.commons.vfs.impl.StandardFileSystemManager".
at org.apache.commons.vfs.VFS.createManager(VFS.java:93)
at org.apache.commons.vfs.VFS.getManager(VFS.java:47)
at mondrian.spi.impl.ApacheVfsVirtualFileHandler.readVirtualFile(ApacheVfsVirtualFileHandler.java:37)
at mondrian.olap.Util.readVirtualFile(Util.java:3479)
at
......
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal
at java.lang.ClassLoader.defineClass1(Native Method)
......
Caused by: java.lang.ClassNotFoundException: org.w3c.dom.ElementTraversal
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 97 more
java.lang.NoClassDefFoundError: org/apache/commons/collections/map/ReferenceMap
......
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.map.ReferenceMap
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 78 more
提示差java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal ,百度一番,发现这个jar 报名是xml-apis
打开原来maven引用的情况如下:
可以看到,olap4j 依赖xml_apis.jar,
我这里是complie引用该jar,因此,(gradle 没有优先读本地maven?这方式没有加载olap4j 所依赖的库?或者maven库有问题?)
另外ClassNotFoundException:org.apache.commons.collections.map.ReferenceMap,这个问题,是差commons-collections。
重新引入它,运行测试,报错:
2019-11-14 13:59:36.548 INFO 83320 --- [ main] o.a.c.vfs.impl.DefaultFileReplicator : Using "C:\Users\tbxc\AppData\Local\Temp\vfs_cache" as temporary files store.
mondrian.olap.MondrianException: Mondrian Error:Internal error: Virtual file is not readable: FSCK_MDX.xml
at mondrian.resource.MondrianResource$_Def0.ex(MondrianResource.java:989)
at mondrian.olap.Util.newInternal(Util.java:2536)
at mondrian.olap.Util.newError(Util.java:2551)
at
......
mondrian.olap.MondrianException: Mondrian Error:Connect string must contain property 'Catalog' or property 'CatalogContent'
at mondrian.resource.MondrianResource$_Def1.ex(MondrianResource.java:1009)
......
文件路径不对?重新copy路径如下图:
ok! 测试通过!
完整gradle如下:
plugins {
id 'org.springframework.boot' version '2.2.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.Comm'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-web-services'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.1'
implementation('org.springframework.boot:spring-boot-starter-actuator')
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-jdbc')
implementation('org.springframework.boot:spring-boot-starter-web')
testImplementation('org.springframework.boot:spring-boot-starter-test')
dependencies{compile files('lib/ojdbc6.jar')}
dependencies{compile files('lib/mondrian-4.7.0.0-12.jar')}
dependencies{compile files('lib/eigenbase-xom-1.3.4.jar')}
dependencies{compile files('lib/eigenbase-resgen-1.3.1.jar')}
dependencies{compile files('lib/xml-apis-1.4.01.jar')}
compile group: 'org.olap4j', name: 'olap4j', version: '1.2.0'
compile group: 'org.olap4j', name: 'olap4j-xmlaserver', version: '1.2.0'
compile group: 'net.hydromatic', name: 'eigenbase-properties', version: '1.1.5'
compile group: 'commons-math', name: 'commons-math', version: '1.2'
compile group: 'apache-log4j', name: 'log4j', version: '1.2.14'
compile group: 'commons-vfs', name: 'commons-vfs', version: '1.0'
compile group: 'org.apache.commons', name: 'commons-vfs2', version: '2.1'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2.2'
}
test {
useJUnitPlatform()
}
hibernate5:
继承关系的测试:
//父类
@Entity
@Table(name = "COMMOBJECT")//数据库的表名
@Inheritance(strategy = InheritanceType.JOINED)
public class CommObject {
@Id
private int id;
@Column(name = "name")//数据库的字段名,数据库 不区分大小写 这个 要注意
private String name;
....
//子类
@Entity
@Table
@PrimaryKeyJoinColumn(name = "id")
public class FormFolder extends CommObject {
....
以前我都是写配置文件,这次换注解,测试通过。
ibats?算了,用hibernate就够了!
原型需要的数据:
开发先做关键原型,接下来准备各种原型需要的数据。
先准备维度数据:年度、期间、版本、币别、场景、项目、组织
(维度的管理类)
一个具体维度,数据库上有三张表反映:
(维度及mondrian相关表)
维度相关的表:
- commObject,所有原始的祖先表;
- 前缀为 “c_” 的表,用于管理各类维度。
- 前缀为““c_dim_”的表,是mondrain引擎用到维度表。
配置mondrian的schemal相关的维度表用"c_dim_"前缀开头。
维度数据准备,以后应该用kettle抽取?
由于我先搞了一个项目维度表,感觉内容多了,相关数据重新迁移到commobject表。
select p.projectkey + 500000,
p.projectname,
1,
-100, --上级id 下面再处理
case --代数
when p.projectcode = p.level1projectcode then
1
when p.projectcode = p.level2projectcode then
2
when p.projectcode = p.level3projectcode then
3
when p.projectcode = p.level4projectcode then
4
when p.projectcode = p.level5projectcode then
5
when p.projectcode = p.level6projectcode then
6
when p.projectcode = p.level7projectcode then
7
when p.projectcode = p.level8projectcode then
8
end,
case p.isleaf --是否有子节点
when '0' then
1
when '1' then
0
end,
rank,
0,
to_timestamp(to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss'), --时间戳
'yyyy-mm-dd hh24:mi:ss')
from dim_chargeproject p,
(select p.projectkey projectkey,
p.projectcode,
p.projectname
,
rank() over(order by p.projectcode) rank --排序号 可能有问题
from dim_chargeproject p) pr
where pr.projectkey = p.projectkey
ps:timestamp 是oracle对date的扩展,其度量精度比date类型更高。
case when 在这条语句中有2个形态,注意语法上些许差别。
上面没有更新commobject表中parent,后面用一条语句更新一下,即根据一张表的数据更新另外一张表相关字段。
--temp22 是一张临时表
update commobject t
set t.parent = (select s.pk2 from temp22 s where s.pk0 = t.id)
where t.id in (select s.pk0 from temp22 s)
mondrian用到的维度表是偏平化结构,所以要去掉非末级节点:
delete from c1_dim_account c1 where c1.id in (
select p.projectkey+500000 pk0 from dim_chargeproject p where p.isleaf=0);
到此,模拟维度数据准备完毕。
其他开发配置:
我们项目何vue前端,采取json交换,因此,引入了json相关jar,json消息,我们需要进行格式化封装,沿用我们原有项目格式,又是一番copy,解决问题。
测试vue 前端和后端服务连接,上一段测试代码,ok! 测试代码如下:
<template>
<div id="vue_olap_showData">
<div>
<el-button type="primary" @click="get_olap_showData">读取后台数据</el-button>
</div>
<div class="olapResult" v-html="olapData"></div>
</div>
</template>
<script type="text/javascript">
import olapShowData from "@/api/olap/olap_showData.js";
export default {
data() {
return {
olapData: ""
};
},
methods: {
get_olap_showData() {
olapShowData.olapShowData().then(res => {
this.olapData = res.data;
});
}
}
};
</script>
<style lang='scss'>
.olapResult {
td {
font-size: 12px;
border-left: solid 1px silver;
border-right: none;
border-top: none;
border-bottom: solid 1px silver;
text-align: right;
width: 105px;
height: 25px;
}
}
//flex 高度控制的问题,还有点模糊,先放着
.vue_olap_showData {
display: flex;
flex-direction: column;
justify-content: flex-start;
}
</style>
效果如下图: