zoukankan      html  css  js  c++  java
  • [saiku] 将saiku自带的H2嵌入式数据库迁移到本地mysql数据库

    saiku数据库的表和用户默认创建是在启动项目的时候,通过初始化 saiku-beans.xml 中的 h2database 这个 bean 

    执行org.saiku.service.Database类的init方法来初始化数据表和默认用户的。

    具体修改如下:

    1/修改web.xml 中 数据连接配置信息

    将数据库链接修改为本地mysql配置信息

      <context-param>
        <param-name>db.url</param-name>
        <param-value>jdbc:mysql://localhost:3306/saiku</param-value>
      </context-param>
      <context-param>
        <param-name>db.user</param-name>
        <param-value>root</param-value>
      </context-param>
      <context-param>
        <param-name>db.password</param-name>
        <param-value>root</param-value>
      </context-param>

    2/修改saiku-beans.xml中h2database配置信息

    新增mysql数据源适配:

        <bean id="h2database" class="org.saiku.database.Database" init-method="init">
            <property name="datasourceManager" ref="repositoryDsManager"/>
            <property name="datasourcetype" value="mysql" />
        </bean>

    3/修改Database中获取的数据源为mysql

    修改Database类:

    private String datasourcetype = "mysql";
    private void initDB() {
    
            String url = servletContext.getInitParameter("db.url");
            String user = servletContext.getInitParameter("db.user");
            String pword = servletContext.getInitParameter("db.password");
            
            if (this.datasourcetype.equals("mysql")) {
                ds = new MysqlDataSource();
                ((MysqlDataSource) ds).setUrl(url);
                ((MysqlDataSource) ds).setUser(user);
                ((MysqlDataSource) ds).setPassword(pword);
            } else if (this.datasourcetype.equals("h2")) {
                ds = new JdbcDataSource();
                ((JdbcDataSource) ds).setUrl(url);
                ((JdbcDataSource) ds).setUser(user);
                ((JdbcDataSource) ds).setPassword(pword);
            }
            
        }

    4/因为h2建表sql和mysql的还是有差异的,所以将创建表和用户信息的代码替换如下:

    mysql数据表和用户的创建代码为:

        private void loadUsers() throws SQLException {
         
            Connection c = ds.getConnection();
          
            Statement statement = c.createStatement();
            
            statement.execute(" CREATE TABLE IF NOT EXISTS log ( time  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, log  TEXT); ");
            statement.execute(" CREATE TABLE IF NOT EXISTS users(user_id INT(11) NOT NULL AUTO_INCREMENT, " + " username VARCHAR(45) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, email VARCHAR(100), " + " enabled TINYINT NOT NULL DEFAULT 1, PRIMARY KEY(user_id)); ");
            statement.execute(" CREATE TABLE IF NOT EXISTS user_roles ( " + " user_role_id INT(11) NOT NULL AUTO_INCREMENT,username VARCHAR(45), "  + " user_id INT(11) NOT NULL REFERENCES users(user_id), " + " ROLE VARCHAR(45) NOT NULL, " + " PRIMARY KEY (user_role_id)); ");
        
            ResultSet result = statement.executeQuery("select count(*) as c from log where log = 'insert users'");
            
            result.next();
            
            if (result.getInt("c") == 0) {
                
                statement.execute("INSERT INTO users (username,password,email, enabled) VALUES ('admin','admin', 'test@admin.com',TRUE);");
                statement.execute("INSERT INTO users (username,password,enabled) VALUES ('smith','smith', TRUE);");
                statement.execute("INSERT INTO user_roles (user_id, username, ROLE) VALUES (1, 'admin', 'ROLE_USER');");
                statement.execute("INSERT INTO user_roles (user_id, username, ROLE) VALUES (1, 'admin', 'ROLE_ADMIN');");
                statement.execute("INSERT INTO user_roles (user_id, username, ROLE) VALUES (2, 'smith', 'ROLE_USER');");
                statement.execute("INSERT INTO log (log) VALUES('insert users');");
            }
    
            String encrypt = servletContext.getInitParameter("db.encryptpassword");
            if (encrypt.equals("true") && !checkUpdatedEncyption()) {
                updateForEncyption();
            }
        }
    
     
        public boolean checkUpdatedEncyption() throws SQLException{
            Connection c = ds.getConnection();
            Statement statement = c.createStatement();
            ResultSet result = statement.executeQuery("select count(*) as c from log where log = 'update passwords'");
            result.next();
            return result.getInt("c") != 0;
        }
     
        public void updateForEncyption() throws SQLException {
            
            Connection c = ds.getConnection();
            Statement statement = c.createStatement();
            statement.execute("ALTER TABLE users MODIFY COLUMN PASSWORD VARCHAR(100) DEFAULT NULL");
            ResultSet result = statement.executeQuery("select username, password from users");
            while (result.next()) {
                statement = c.createStatement();
                String pword = result.getString("password");
                String hashedPassword = passwordEncoder.encode(pword);
                String sql = "UPDATE users " + "SET password = '" + hashedPassword
                        + "' WHERE username = '" + result.getString("username")
                        + "'";
                statement.executeUpdate(sql);
            }
            statement = c.createStatement();
            statement.execute("INSERT INTO log (log) VALUES('update passwords');");
        }

    以上的信息修改完毕后,在本地mysql创建url中指定的database->saikuBase,此时db中无任何表

    运行saiku项目成功后,刷新db,可以看见db中多出了三张表user/user_roles/log,说明初始化表和默认数据已经成功。

    但是,此时只是创建了表结构和默认的登陆账户,并没有修改登录的用户认证数据源。

    当我们使用admin登陆时还是会访问到jdbc中配置的h2数据库数据源。

    其实这时候还是通过访问h2内嵌数据库的db文件登陆的,在管理端新建的用户也会保存在h2数据源中,mysql数据源中查询不到新建的用户

    所以,接下来要修改认证数据源为本地的mysql

    5/修改用户认证数据源

    将 bean id 为 datasource 的 数据源的配置信息改为我们本地mysql的配置信息,重新部署服务并启动

    这时,我们在管理端创建一个用户saiku,点击保存。

    查看本地mysql数据库的user表,能看见saiku已经存在user表中了,并且使用saiku用户登录也能登录成功。

    将*security-jdbc.xml 中的配置信息改成mysql的即可

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >  
            <property name="driverClassName" value="mysql的驱动"/>  
            <property name="url" value="mysql的url"/>  
            <property name="username" value="账户名"/>  
            <property name="password" value="密码"/>  
    </bean>

    至此就完成了h2数据库迁移到本地mysql的操作了

  • 相关阅读:
    [JAVA]Java下XML的解析
    [短彩信]C#短彩信模块开发设计(4)——其他
    [短彩信]C#短彩信模块开发设计(3)——协议
    入住博客园了~
    【Oyster轻量框架】C# ORM 较灵活的轻量数据模型
    C# Oracle 之Insert 与 Update 的封装
    用WORD发布博客测试~
    C#自带的.net类库获得主机名和IP
    百万本书籍视频资料免费送
    教你使用ECode破解E语言crackme视频教程
  • 原文地址:https://www.cnblogs.com/avivaye/p/4881106.html
Copyright © 2011-2022 走看看