Solon轻量级Web框架:第一个增删改查(四)

代码的世界大部分是枯燥的乏味的,在一个又一个加班的普通日子里,给自己来点趣味性。比如用《薛定谔的猫》相关知识勾搭文科生(美女才行),推荐看个书《万万没想到:用理工科思维理解世界》,有趣味性,不像至于文学性的东西看不进去。一切的一切就是给自己的生活加点料,保持良好的创造性思维。

创造力最重要的不是发现前人未见的,而是在人人所见到的现象中想到前人所没有想到的。 ——薛定谔

前言

一个Web应用程序,总是包含用户、部门、角色的,也就是权限管理,权限关了是所有Web应用程序的开始,如Gitee中的几个MVP项目Ruoyi、Guns等。所以本人也不能免俗,依然从权限管理系统讲起,怀念下曾经做“毕业设计”的日子。

模块划分

可能大多数讲师从用户开始,但我认为一个系统总是从配置开始(系统设置模块)的,如默认密码配置等。系统设置模块包为“system”,以下为系统设置增删改查实现过程。

数据库设计

DROP TABLE IF EXISTS sys_config;
CREATE TABLE sys_config(
    config_id INT(11) NOT NULL AUTO_INCREMENT  COMMENT '参数主键' ,
    config_name VARCHAR(100)    COMMENT '参数名称' ,
    config_key VARCHAR(100)    COMMENT '参数键名' ,
    config_value VARCHAR(500)    COMMENT '参数键值' ,
    config_type CHAR(1)   DEFAULT 'N' COMMENT '系统内置;(Y是N否)' ,
    -- 后面为全局通用字段
    create_by VARCHAR(64)    COMMENT '创建者' ,
    create_time DATETIME    COMMENT '创建时间' ,
    update_by VARCHAR(64)    COMMENT '更新者' ,
    update_time DATETIME    COMMENT '更新时间' ,
    remark VARCHAR(500)    COMMENT '备注' ,
    PRIMARY KEY (config_id)
)  COMMENT = '参数配置表';

基础实体类(全局通用字段):

package cn.minimelon.solon.domain;

import lombok.Getter;
import lombok.Setter;
import org.noear.snack.annotation.ONodeAttr;

import java.io.Serializable;
import java.util.Date;

@Getter
@Setter
public class BaseEntity  implements Serializable {
    /**
     * 创建者
     */
    private String createBy;

    /**
     * 创建时间
     */
    @ONodeAttr(format = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /**
     * 更新者
     */
    private String updateBy;

    /**
     * 更新时间
     */
    @ONodeAttr(format = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

    /**
     * 备注
     */
    private String remark;
}

配置实体类:

package cn.minimelon.solon.domain.system;

import cn.minimelon.solon.domain.BaseEntity;
import lombok.Getter;
import lombok.Setter;
import org.noear.weed.annotation.PrimaryKey;
import org.noear.weed.annotation.Table;

@Getter
@Setter
@Table("sys_config")
public class SysConfig extends BaseEntity {
    @PrimaryKey
    private Integer configId;
    /**
     * 参数名称
     */
    private String configName;
    /**
     * 参数键名
     */
    private String configKey;
    /**
     * 参数键值
     */
    private String configValue;
    /**
     * 系统内置;(Y是N否)
     */
    private String configType;
}

接口设计

    1. 增加接口 POST /system/config
    1. 删除接口 DELETE /system/config/{configId}
    1. 更新接口 PUT /system/config
    1. 实体查询 GET /system/config/{configId}
    1. 更多查询 POST /system/config/list

业务接口类SysConfigService

package cn.minimelon.solon.service.system;

import cn.minimelon.solon.domain.system.SysConfig;

import java.util.List;

public interface SysConfigService {
    Long insert(SysConfig config);

    Integer deleteById(String configId);

    Integer updateById(SysConfig config);

    SysConfig selectById(String configId);

    List<SysConfig> selectByCond(SysConfig config);
}

控制器SysConfigController

package cn.minimelon.solon.controller.system;

import cn.minimelon.solon.domain.AjaxResult;
import cn.minimelon.solon.domain.system.SysConfig;
import cn.minimelon.solon.service.system.SysConfigService;
import org.noear.solon.annotation.*;

import java.util.List;

@Controller
@Mapping("system")
public class SysConfigController {

    @Inject
    SysConfigService configService;

    @Post
    @Mapping("config")
    public AjaxResult insert(SysConfig config) {
        Long count = configService.insert(config);
        return AjaxResult.success(count);
    }

    @Delete
    @Mapping("/config/{configId}")
    public AjaxResult delete(String configId) {
        Integer count = configService.deleteById(configId);
        return AjaxResult.success(count);
    }


    @Put
    @Mapping("config")
    public AjaxResult update(SysConfig config) {
        Integer count = configService.updateById(config);
        return AjaxResult.success(count);
    }

    @Get
    @Mapping("/config/{configId}")
    public AjaxResult query(String configId) {
        SysConfig config = configService.selectById(configId);
        return AjaxResult.success(config);
    }

    @Post
    @Mapping("/config/list")
    public AjaxResult list(SysConfig config) {
        List<SysConfig> list = configService.selectByCond(config);
        return AjaxResult.success(list);
    }
}

业务逻辑实现

数据库操作类SysConfigMapper:

package cn.minimelon.solon.mapper.system;

import cn.minimelon.solon.domain.system.SysConfig;
import org.noear.weed.BaseMapper;
import org.noear.weed.xml.Namespace;

import java.util.List;

@Namespace("cn.minimelon.solon.mapper.system")
public interface SysConfigMapper extends BaseMapper<SysConfig> {
    List<SysConfig> selectByCond(SysConfig config);
}

对应SQL实现XML:

<?xml version="1.0" encoding="utf-8" ?>
<!-- namespace 不包括文件名; 这点与mybatis不同 -->
<mapper namespace="cn.minimelon.solon.mapper.system"
        import="cn.minimelon.solon.domain.system.*"
        baseMapper="SysConfig">
    <sql id="selectByCond" return="List[SysConfig]" param="config:SysConfig" remarks="按条件查询">
        select * from sys_config
        <trim prefix=" where " trimStart="and ">
            <if test="StringUtils.isNotEmpty(config.getConfigName())">
                and config_name LIKE '${config.getConfigName()}%'
            </if>
        </trim>
    </sql>
</mapper>

业务实现SysConfigServiceImpl:

package cn.minimelon.solon.service.system.impl;

import cn.minimelon.solon.domain.system.SysConfig;
import cn.minimelon.solon.mapper.system.SysConfigMapper;
import cn.minimelon.solon.service.system.SysConfigService;
import org.noear.solon.extend.aspect.annotation.Service;
import org.noear.weed.annotation.Db;

import java.util.List;

@Service
public class SysConfigServiceImpl implements SysConfigService {
    @Db
    SysConfigMapper configMapper;

    @Override
    public Long insert(SysConfig config) {
        return configMapper.insert(config, true);
    }

    @Override
    public Integer deleteById(String configId) {
        return configMapper.deleteById(configId);
    }

    @Override
    public Integer updateById(SysConfig config) {
        return configMapper.updateById(config, true);
    }

    @Override
    public SysConfig selectById(String configId) {
        return configMapper.selectById(configId);
    }

    @Override
    public List<SysConfig> selectByCond(SysConfig config) {
        return configMapper.selectByCond(config);
    }
}

数据源与运行

在config包添加JdbcConfig:

package cn.minimelon.solon.config;

import com.zaxxer.hikari.HikariDataSource;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;

import javax.sql.DataSource;

@Configuration
public class JdbcConfig {
    @Bean
    public DataSource db1(@Inject("${jdbc.master}") HikariDataSource ds) {
        return ds;
    }
}

启动类添加SQL打印,并运行

package cn.minimelon.solon;

import org.noear.solon.Solon;
import org.noear.solon.SolonBuilder;
import org.noear.weed.WeedConfig;

public class AppStarter {
    public static void main(String[] args) {
        new SolonBuilder().start(AppStarter.class, args, (app -> {
            if (Solon.cfg().isDebugMode() || Solon.cfg().isFilesMode()) {
                //执行后打印sql
                WeedConfig.onExecuteAft(cmd -> {
                    System.out.println("[Weed3]" + cmd.text + "\r\n" + cmd.paramMap());
                });
                WeedConfig.onException((cmd, err) -> {
                    System.out.println("[Weed3]" + cmd.text + "\r\n" + cmd.paramMap());
                });
            }
        }));
    }
}

运行截图:

小结

Weed3是Solon同作者开发,XML采用了Java的方式处理SQL,跟Mybatis、beeltSQL等模板语音有很大差别。如果不习惯可以采用其他ORM框架,指导文档:这里

这里讲了第一个增删改查,其他的增删改查不再赘述,建议自行体会。值得吹嘘的是打包出来后,可运行文件如下图,只有2.25M,是不是一个惊喜。

更多源代码:https://gitee.com/hiro/study-test/tree/master/solon-start

下一篇:Solon轻量级Web框架:登录过滤与统一异常(五)

posted @ 2022-04-22 08:51  Hiro(阿宽)  阅读(279)  评论(1)    收藏  举报