haizhilingyu 的个人知识记录

Open Source, Open Mind,
Open Sight, Open Future!

搭建一套基于Java的web开发框架-界面初始化数据库

搭建一套基于Java的web开发框架-界面初始化数据库

简介

Solon支持扩展配置的写法在app.yml配置文件中添加solon.extend: "!db_ext"配置在启动时会自动加载db_ext中的配置文件,初步想法是启动时判断db_ext文件夹中是否有数据库的配置文件,如果有则启动时创建数据库连接池,没有就在访问主页时跳转数据库初始化页面进行数据库信息的配置,然后进行初始化,成功后才能访问主页。

界面初始化数据库实操

1、首先改造启动方法,在启动时判断配置文件决定是否创建数据库连接池

    /**
     * 应用程序的主入口点
     * 初始化并启动Solon应用程序,并在应用程序上下文中注册数据源
     * 如果配置中包含数据库连接信息,则初始化数据库连接池
     *
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 启动Solon应用程序
        Solon.start(App.class, args, app -> {
            // 启动数据库框架默认的环境工作器
            DefaultEnvironmentWorker.start();
            // 检查配置中是否包含数据库连接URL,以决定是否初始化数据库连接池
            SolonProps cfg = Solon.cfg();
            if (cfg.containsKey("db.jdbcUrl")) {
                // 创建并配置HikariCP连接池
                HikariConfig hikariConfig = new HikariConfig();
                hikariConfig.setDriverClassName(cfg.get("db.driverClassName"));
                hikariConfig.setJdbcUrl(cfg.get("db.jdbcUrl"));
                hikariConfig.setUsername(cfg.get("db.username"));
                hikariConfig.setPassword(cfg.get("db.password"));
                // 使用配置好的连接池创建数据源
                HikariDataSource dataSource = new HikariDataSource(hikariConfig);
                // 注册数据源到上下文中,标识为"db"
                DataSourceHolder.reg("db", dataSource);
            }
        });
    }

2、创建IndexController类,在这个类中我添加了两个方法,一个是用于跳转首页,另一个用于跳转初始化数据库页面,看到官网还有国际化的实现方式,反正不费事加上。

新增maven依赖,


        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>solon.i18n</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

IndexController内容

package site.xiweihai.framework.controller;

import lombok.extern.slf4j.Slf4j;
import org.anyline.proxy.ServiceProxy;
import org.anyline.service.AnylineService;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Param;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.ModelAndView;
import org.noear.solon.i18n.annotation.I18n;
import site.xiweihai.framework.InitDb;

import java.io.FileOutputStream;
import java.util.Locale;
import java.util.Properties;

/**
 * 首页控制器
 *
 * @author hai
 * @since 2024/08/12
 */
@I18n
@Controller
@Slf4j
public class IndexController {

    /**
     * 处理根路径请求,提供视图展示功能
     *
     * @param ctx 上下文对象,用于处理请求和响应
     */
    @Mapping("/")
    public void view(Context ctx) {
        // 通过ServiceProxy获取数据库服务实例
        AnylineService service = ServiceProxy.service("db");

        // 如果服务实例为空,则重定向到初始化页面
        if (service == null) {
            ctx.redirect("/init");
        }else{
            // 返回视图页面
            ctx.forward("/index.html");
        }
    }

    /**
     * 初始化数据库操作的控制器方法
     *
     * @param driver 数据库驱动类名
     * @param url 数据库连接URL
     * @param username 数据库用户名
     * @param password 数据库密码
     * @param ctx 上下文对象,用于重定向等操作
     * @param locale 用户区域设置,用于确定语言环境
     * @return 返回视图和模型数据
     */
    @Mapping("/init")
    public ModelAndView init(@Param(name = "driver") String driver,
                             @Param(name = "url") String url,
                             @Param(name = "username") String username,
                             @Param(name = "password") String password,
                             Context ctx,
                             Locale locale) {
        AnylineService service = ServiceProxy.service("db");
        if(service!=null){
            ctx.forward("/");
        }
        // 创建ModelAndView对象,指定视图模板
        ModelAndView model = new ModelAndView("initdb.ftl");
        // 向模型中添加语言环境信息
        model.put("lang", locale.getLanguage());
        // 向模型中添加标题信息
        model.put("title", "dock");
        model.put("driver", driver!=null?driver:"org.sqlite.JDBC");
        model.put("url", url!=null?url:"jdbc:sqlite:db.db");
        model.put("username", username!=null?username:"");
        model.put("password", password!=null?password:"");
        model.put("errorMsg", "initdb.initmsg");
        // 检查数据库驱动类名是否为空
        if (driver == null) {
            // 如果为空,向模型中添加错误信息并返回模型
            return model;
        }
        try {
            // 尝试初始化数据库
            InitDb.run(driver, url, username, password);
            // 将数据库连接信息写入配置文件
            try (FileOutputStream outputStream = new FileOutputStream("db_ext/_db.properties")) {
                Properties props = new Properties();
                props.put("db.driverClassName", driver);
                props.put("db.jdbcUrl", url);
                props.put("db.username", username);
                props.put("db.password", password);
                // 保存属性到输出流
                props.store(outputStream, "auto create");
            }
            // 重定向到主页
            ctx.redirect("/");
        } catch (Exception e) {
            // 捕获异常,记录错误日志
            log.error(e.getMessage(), e);
            // 向模型中添加错误信息
            model.put("errorMsg", "initdb.fail");
        }

        // 返回模型和视图
        return model;
    }

}

前端模板页面和其它配置太多就不贴代码了,直接展示结果

数据库初始化页面

初始化成功后跳转的首页

用AI辅助写前端代码还是方便,一会儿就生成了,稍微改改就可以用,代码已放在github上了地址https://github.com/Haizhilingyu/framework.git


标题:搭建一套基于Java的web开发框架-界面初始化数据库
作者:haizhilingyu
地址:https://xiweihai.site/articles/2024/08/15/1723671331080.html