ic framework是一款集成框架,对mybatis、鉴权、数据库自动ddl、代码生成等进行简化集成,方便开发者快捷接入和使用
icframework集成中后台、用户管理、鉴权管理、部门岗位、酒店管理
IC Framework 是一个Java开发框架,基于Spring Boot 3.5.3构建,提供了一套完整的开发脚手架。框架集成了认证授权、数据访问、代码生成、缓存管理等核心功能,旨在提高开发效率,规范代码结构。
在线文档 【giteee】 ✋🏻 前言
作者在开发某 AI 股票分析 K 线策略训练模拟器 App 的后台时,曾尝试过热门项目若依。若依上手简单、功能完善,但页面与 Java 风格不太契合,因此决定自研一套框架,这便是 IC Framework 的由来。
在选择 ORM 框架时,作者也尝试了MybatisFlex,个人更倾向Flex,最终决定参考 MybatisFlex 自行实现一套 MyBatis 增强工具,目标是实现复杂 SQL 也无需编写 XML。
目前该框架已在实际项目中稳定运行,现开源出来,欢迎大家参考和交流。
ic-framework/ ├── ic-framework-annotation/ # 注解模块 ├── ic-framework-dependencies/ # 依赖管理模块 ├── ic-framework-common/ # 通用工具模块 ├── ic-framework-auth/ # 认证授权模块 ├── ic-framework-core/ # 核心功能模块 ├── ic-framework-mybatis/ # MyBatis扩展模块 ├── ic-framework-gen/ # 代码生成模块 ├── ic-framework-gen-template/ # 代码生成模板 ├── ic-framework-dber/ # 数据库工具模块 ├── ic-framework-mybatis-processor/ # MyBatis注解处理器 ├── ic-framework-spring-boot-starter/ # Spring Boot启动器 ├── ic-framework-parent/ # 父模块 └── doc/ # 文档目录
在您的Spring Boot项目中添加IC Framework依赖:
<dependency> <groupId>cn.icframework</groupId> <artifactId>ic-framework-spring-boot-starter</artifactId> <version>1.0.0</version> </dependency>
在 application.yml 中配置数据库连接:
spring: datasource: url: jdbc:mysql://localhost:3306/your_database username: your_username password: your_password driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath*:mapper/*.xml type-aliases-package: cn.icframework.**.pojo
spring: redis: host: localhost port: 6379 password: your_password database: 0
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
提供框架中使用的各种注解,如API缓存、权限验证等注解。
通用工具模块,包含:
认证授权模块,提供:
数据库工具模块,提供:
核心功能模块,包含:
MyBatis扩展模块,提供:
代码生成模块,支持:
ic: jwt: secret: your-jwt-secret-key timeout: 7200 log: printStackTrace: true printError: true sql: updatePath: classpath:/sqls initPath: classpath*:/sqls/init.sql snowflake: dataCenterId: 1 workerId: 1 noFilterUrls: - /api/public/** - /api/auth/**
ic: auth: enable: true excludeUrls: - /api/public/** - /api/auth/** jwt: secret: your-secret expiration: 7200
// 多条件,select里面不写或者写table._all就是查询所有字段 UserDef table = UserDef.table(); SqlWrapper sqlWrapper = SELECT(table.name) .FROM(table) .WHERE( table.name.in( SELECT(table.name).FROM(table).WHERE(table.name.eq("2").id.eq("3")) ).or().name.like("2") ); // 还可以这么写 SqlWrapper sqlWrapper = SELECT(table.name) .FROM(table) .WHERE( table.name.in( SELECT(table.name).FROM(table).WHERE(table.name.eq("2").id.eq("3")) ) ).OR(table.name.like("2")); // 还可以这么写 SqlWrapper sqlWrapper = SELECT(table.name) .FROM(table) .WHERE( table.name.in( SELECT(table.name).FROM(table).WHERE(table.name.eq("2").id.eq("3")) ), OR(), table.name.like("2") ); // 去重,不指定条件就是按所有字段去重 SqlWrapper sqlWrapper = SELECT_DISTINCT(table.name) .FROM(table) .WHERE( table.name.in( SELECT(table.name).FROM(table).WHERE(table.name.eq("2").id.eq("3")) ).or().name.like("2") ); // 指定字段去重 SqlWrapper sqlWrapper = SELECT(DISTINCT(table.id), table.name) .FROM(table) .WHERE( table.name.in( SELECT(table.name).FROM(table).WHERE(table.name.eq("2").id.eq("3")) ).or().name.like("2") ); // 排序 SqlWrapper sqlWrapper = SELECT(table.name) .FROM(table) .WHERE( table.name.in( SELECT(table.name).FROM(table).WHERE(table.name.eq("2").id.eq("3")) ).or().name.like("2") ) .ORDER_BY( SELECT(table.id).FROM(table).WHERE(table.name.eq("2")) ) .ORDER_BY(table.name.asc().id.desc()) .ORDER_BY_ASC(table.name); // 子查询 UserDef table2 = UserDef.table(); SqlWrapper sqlWrapper = SELECT(table.name, SELECT(table2.name).FROM(table2).WHERE(table2.name.eq(table.name)).AS("name2")) .FROM(table) .WHERE( table.name.in( SELECT(table.name).FROM(table).WHERE(table.name.eq("2").id.eq("3")) ).or().name.like("2") );
// 基础 User user = new User(); user. setName("张三"); userService. insert(user); // 批量插入 List<User> userList = new ArrayList<>(); userList. add(user); userService. insertBatch(user); // 批量插入如果不需要捕获异常,可以使用skipError,会用虚拟线程分批入库,大幅度提升性能 List<User> userList = new ArrayList<>(); userList. add(user); userService. insertBatch(user, true); // into select UserDef table = UserDef.table(); SqlWrapper insert = INSERT() .INTO(User.class) .COLUMNS(User::getName, User::getDel, User::getId) .VALUES( SELECT(AS(1, User::getName), AS(1, User::getDel), table.id) .FROM(table) .WHERE(table.name.eq("123")) ); userService. insert(insert); // 得到以下sql // INSERT INTO user (name, del, id) // SELECT 1 AS `name`, 1 AS `del`, user.id // FROM user WHERE (user.name = #{params.p_0})
sql可以查了,怎么映射到实体也挺重要
// 结果映射,以下两个注解的前提是sql已经查询出来了 // 也就是如下sql: // sqlWrapper = select u.*,r.name as `roles.name`,dep.name as `dep.name` from user u left join user_role ur .... // 然后就会自动封装roles 和 dep了 List<UserDetailVO> userVos = userService.select(sqlWrapper, UserDetailVO.class); public class UserDetailVO extends UserVO { /** * 对应mybatis的association,把一对一关系映射到实体 */ @Collection private List<RoleSimpleVO> roles; /** * 对应mybatis的association,把一对一关系映射到实体 */ @Association private DeptSimpleVO dep; } // 多层连接查询 // 下面连接是已经查询出User信息也就是只执行了sqlWrapper = select * from user ....,然后返回需要附加如角色、部门、岗位等信息 List<UserDetailVO> userVos = userService.select(sqlWrapper, UserDetailVO.class); public class UserDetailVO extends UserVO { /** * 所属角色 * 以下内容含义就是用 当前UserVO的idd字段,left join UserRole表的userId * 再用UserRole表的roleId left join Role表的id,最终获得RoleSimpleVO信息 * 可以简单理解内部实现为 * select * from user_role ur left join role r on ur.role_id = r.id where ur.user_id = #{UserVO.id} * 但是实际内部是批量处理的, 会用虚拟线程分批查询,再分配到对应的UserVO * select * from user_role ur left join role r on ur.role_id = r.id where ur.user_id in #{ids} */ @Joins(joins = { @Join(joinTable = UserRole.class, selfField = "id", joinTableField = "userId"), @Join(joinTable = Role.class, selfField = "roleId", joinTableField = "id") }) private List<RoleSimpleVO> roles; /** * 所属部门 * 如果不是List则取join第一个 */ @Joins(joins = { @Join(joinTable = DepUser.class, selfField = "id", joinTableField = "userId"), @Join(joinTable = Dept.class, selfField = "depId", joinTableField = "id") }) private DeptSimpleVO dep; }
@RestController @RequestMapping("/api/user") public class UserController { @RequireAuth(permissions = {"user:view"}) @GetMapping("/list") public Result<List<User>> getUserList() { // 业务逻辑 return Result.success(userList); } @RequireAuth(permissions = {"user:add"}) @PostMapping("/add") public Result<User> addUser(@RequestBody User user) { // 业务逻辑 return Result.success(user); } }
@Configuration public class CustomConfig { @Bean @ConditionalOnMissingBean public CustomService customService() { return new CustomService(); } }
框架支持通过以下方式扩展功能:
详细文档请参考:快速开始
我们欢迎所有形式的贡献,包括但不限于:
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)⭐ 如果这个项目对您有帮助,请给我们一个星标!