開發環境搭建:
1個想法一通向導搞定spring boot
ps:使用IDEA構建一個SpringBoot + Hibernate + Gradle項目
這一步,算是建造了spring + hibernate,後面還有連接池,換成mybatis的問題。
idea中Alt + Enter導入包,和eclipse有點不一樣。
甲骨文罐子??:ps: gradle開發springboot項目,連接甲骨文數據庫
然後狂建一堆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,這個就不進行下去了。
ps:相關參考:用到時候,參考一下,這裏先記下。
- 深入瞭解Spring Boot數據源與連接池原理
- Spring Boot集成Druid連接池(MySQL8.0.11)
- springBoot + gradle + Oracle配置德魯伊
- springboot多數據源(三種數據庫連接池--JDBC,dbcp2,Druid)
- Springboot整合Druid,添加攔截器進行數據監控
- springboot添加德魯伊步驟
- Springboot + Mybatis的+ dbcp + MySQL的簡單集成
- springboot配置數據庫連接池
- SpringBoot配置連接池
- springboot添加druid步驟(兩種方案)
- springboot2.0整合德魯伊,以及springboot自動裝配DataSource原理
持久層考慮因素:
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分析平臺的設計與實現(二)_測試開發配置》。
ps:Zxing的集成---- Maven對應Gradle的寫法
測試不成功,可能是代理,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
ps:java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal 的解決辦法
打開原來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 {
....
以前我都是寫配置文件,這次換註解,測試通過。
參考文檔:
SpringBoot 與JPA結合中 JpaRepository 裏自定義查詢
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>
效果如下圖: