opengoofy / crane4j

一个简单易用的关联字段填充框架,通过简单的注解配置快速根据外键/编码值填充相关字段,支持字典,枚举,方法等多种数据源。 A simple and easy-to-use data mapping framework, quickly populate relevant fields according to foreign keys/encoded values through simple annotation configuration, supports dictionaries, enumerations, methods and other data sources.
http://www.crane4j.cn
Apache License 2.0
218 stars 33 forks source link

写一篇推广文章 #32

Closed Createsequence closed 7 months ago

Createsequence commented 1 year ago

在 1.1.0 发布以后,crane4j 的项目推广需要提上日程,不过在这之前,需要先好好整理一篇项目推广的文章,如果可以的话希望能在周五前肝出来。

在求助万能的 ChatGPT 后,目前得到了以下可以参考的建议:

关于推广文章的大纲:

当推广自己的开源项目时,一个好的文档可以让人们更好地了解和使用你的项目。以下是一个可能的文档大纲:

1.介绍你的项目 介绍你的项目是什么,它的目的和它所解决的问题。你可以包括一些具体的例子或应用场景,以帮助读者更好地理解你的项目。

2.安装指南 提供安装指南,以确保人们能够轻松地安装和使用你的项目。你可以包括各种平台(例如Windows,MacOS和Linux)的安装说明,以及一些基本的操作指南。

3.功能和特点 描述你的项目的主要功能和特点。你可以解释一些关键功能的工作原理,并提供一些例子来展示如何使用它们。

4.使用示例 提供使用示例,让人们了解如何使用你的项目。你可以提供一些基本的示例,以及更复杂的示例,以便读者可以更好地了解你的项目。

5.开发者文档 如果你的项目是开源的,并且有其他开发者可以参与进来,那么提供开发者文档可以帮助其他人更好地理解你的代码和如何做出贡献。你可以提供关于项目架构、代码结构和开发流程的详细信息。

6.贡献指南 如果你希望其他人为你的项目做出贡献,提供贡献指南可以帮助他们更好地了解如何参与进来。你可以提供一些指南,例如如何提交bug报告、如何提交代码贡献、如何撰写文档等等。

7.社区支持 如果你希望建立一个社区来支持你的项目,提供社区支持的文档可以帮助人们更好地了解如何加入和参与进来。你可以提供一个论坛或邮件列表等方式,以便人们可以与其他人交流和寻求帮助。

8.许可证信息 提供许可证信息,让人们了解你的项目的使用和再分发的规则。你可以选择一些开源许可证,例如MIT或GPL,以便其他人可以自由地使用和分发你的代码。

9.项目更新历史 提供项目的更新历史,让人们了解项目的演变过程。你可以包括每个版本的新功能、改进和修复的bug,以便人们可以了解你的项目的发展历程。

10.作者信息 提供作者信息,让人们了解你的背景和经验。你可以提供你的联系方式,以便其他人可以与你交与你联系,例如电子邮件地址或社交媒体账户。这也可以让人们更好地了解你的动机和目标,并与你建立联系。

11.常见问题解答 提供常见问题解答,以便人们可以在使用你的项目时解决常见问题。你可以列出一些常见问题和解决方案,并提供链接到更详细的解释或文档。

12.推广和宣传 最后,提供推广和宣传的信息,让更多的人知道你的项目。你可以提供一些推广和宣传的技巧,例如使用社交媒体或在技术博客上发表文章。你还可以提供一些社区或论坛的链接,以便人们可以在这些平台上了解和讨论你的项目。

以上是一个可能的文档大纲,你可以根据你的项目和目标另行修改。好的文档可以帮助你的项目更好地被人们了解和使用,并吸引更多的用户和贡献者。

关于如何突出项目的优点:

要突出自己的项目的优点,你可以考虑以下几点:

1.突出项目的独特性和创新性 介绍你的项目的独特性和创新性是吸引人们的关键。如果你的项目有一些新的、前沿的或与众不同的特点,可以在文档中重点突出。你可以通过比较你的项目与其他类似项目的不同之处来突出这些优点。

2.强调项目的实用性和解决问题的能力 人们更愿意使用那些能够解决实际问题的项目,因此突出你的项目的实用性和解决问题的能力非常重要。在文档中提供使用案例和故事,以展示你的项目如何解决实际问题,如何改善用户体验。

3.着重介绍项目的性能和效率 现代软件应用程序需要快速、高效地运行,因此着重介绍项目的性能和效率是吸引用户的一个关键因素。提供有关项目的性能、速度和效率的统计数据、指标和测试结果,可以让用户更好地了解你的项目在性能方面的优点。

4.侧重于项目的易用性和用户友好性 如果你的项目易于使用和用户友好,它就更有可能被广泛接受和使用。在文档中提供有关如何使用项目的详细说明和教程,以及如何配置和调整项目以满足不同需求的指南,可以让用户更容易地使用你的项目。

5.重点介绍项目的安全性和稳定性 在今天的数字时代,安全性和稳定性是用户最关心的问题之一。在文档中强调项目的安全性和稳定性,包括如何保护用户数据、如何处理潜在的安全漏洞和如何维护项目的可靠性和稳定性,可以增加用户对你的项目的信任和使用的意愿。

以上是几个突出项目优点的方法,你可以根据你的项目和目标选择适合你的方法。通过突出你的项目的优点,可以吸引更多的用户和贡献者,增强你的项目的影响力和竞争力。

heliang666s commented 8 months ago

你好,我是社区新人,如果可以的话,希望能把这个issue推给我借此熟悉项目大致内容,谢谢!

Createsequence commented 8 months ago

你好,我是社区新人,如果可以的话,希望能把这个issue推给我借此熟悉项目大致内容,谢谢!

欢迎!

heliang666s commented 7 months ago

Crane4j:一款简单实用的字段填充框架

项目地址:https://github.com/opengoofy/crane4j 欢迎大家积极star和提出issue和pr。
官方文档:https://createsequence.gitee.io/crane4j-doc/#/user_guide/getting_started/getting_started_with_springboot.html alt text

项目简介与应用场景:

在日常的开发中,我们经常会遇到“根据 A 的 key 值拿到 B,再把 B 的属性映射到 A”的需求。除了手动set之外,比较常见的就是利用Spring提供的BeanUtils.CopyProperties进行属性拷贝。虽然这也是一个不错的解决方法,但是遇到一个复杂对象的填充或者场景多样化时难免力不从心。因此Crane4j的出现就是用于自动查询接口并填充字段值。并且支持为MybatisPlus、Jackson、Redis提供了拓展插件,适应性广泛。

原理

crane4j 的整体执行流程可大致分为两阶段:

  1. 配置解析阶段:根据 AnnotatedElement (一般是类或者方法)解析获得对应的操作配置对象 BeanOperations,通过该配置对象我们可以知道一个对象中有多少个字段需要处理,要怎么处理,在 BeanOperation 里面,一个 key 字段对应的一个操作会被转为一个 Operation 对象;
  2. 操作执行阶段:输入要处理的对象,与该对象类型对应操作配置,然后交由操作执行器 BeanOperationExecutor 生成待完成的任务 Execution,并最终分发给操作执行器 OperationHandlerOperationHandler 会根据配置从数据源获得对象,并完成具体的字段映射 alt text 上图描述了一个 Foo 对象,是如何通过 id 获得数据源,并最终将数据源中的 userName 字段值映射到 Foo 的 name 字段上的过程。

    安装指南:

    Crane4j是一个插件,可以通过maven坐标直接安装,推荐与 spring/springboot 集成使用,不过在非 Spring 环境中也提供了很好的支持。样例如下:

    <dependency>
    <groupId>cn.crane4j</groupId>
    <artifactId>crane4j-spring-boot-starter</artifactId>
    <version>2.6.1</version>
    </dependency>

    maven坐标导入后,如果你使用的springboot版本在2.4.0及更高的版本,那么后续就不需要任何额外的配置来引入crane4j。如果是2.4.0以下, 那么你需要在启动类或者配置类上添加@EnableCrane4j或者 @EnableCrane4jFramework来引入自动配置。

@EnableCrane4j
@Configuration
public class Crane4jConfiguration{

}

至此Crane4j就已经安装并且配置完毕。(非Spring的配置方法请参考官方文档)

快速开始

首先我们先做一个简单样例吧! 在开始自动填充之前,我们先准备一个数据源(Container),它们通过独一无二的命名空间(namespace)区分。为了简单,我们就使用Map集合创造数据源

//从Spring容器中获取全局配置
@Autowired
private Crane4jGlobalConfiguration configuration;
//基于Map集合创建一个数据源容器
Map<Integer,String> map = new HashMap<>();
map.put(1,"a");
map.put(2,"b");
map.put(3,"c");
Container<Integer> container = Containers.forMap("test",map);
//将数据源容器注册到全局配置中
configuration.registerContainer(container);

接着我们需要在实体类上面添加注解

@Data //使用lombok注解,可选择手动创建getter、setter方法
@RequireArgsConstructor
public static class Example{
    //根据id填充字段
    @Assemble(container = "test",props = @Mapping(ref = "name"))
    private final Integer id;
    private String name;
}

该配置表示,根据 id 值从容器中获取对应的数据源,并将其填充到 name 属性上。 最后的一步就是触发填充了:

//在方法上添加注解,表明需要自动填充其方法返回值
@Component
public static class Service{
    @AutoOperate(type = Example.class)  //为Example类自动填充
    public List<Example> getExample(){
        return Arrays.asList(new Example(1),new Example(2),new Example(3));
    }
}

//注入Service,确保AOP能成功拦截
@AutoWired
private Service service;

//自动填入方法返回值
List<Example> examples = service.getExample();
System.out.print(examples);

当控制台输出相关内容时,至此你就已经完成快速入门案例了。

[QuickStartWithSpringBootTest.Example(id=1, name=a), QuickStartWithSpringBootTest.Example(id=2, name=b), QuickStartWithSpringBootTest.Example(id=3, name=c)]

接下来为了更贴近实际,我准备了一个SpringMVC的案例 首先我们假设有一个User接口用于根据id查询用户信息。首先来个正常写法。

@RequestMapping("/user")
@RestController
public class UserController{
    @Autowired
    private UserService userService;

    @PostMapping
    public List<UserVO>listUser(@RequestBody List<Integer> ids){
        return userService.listByIds(ids);
    }
}

//为了代码简单起见,省略Service接口,直接使用实现类
@Service
public class UserService{
    p public List<UserVO> listUser(@RequestBody List<Integer> ids) {
        List<UserVO> users = userService.listByIds(ids);
    }
    //填充性别
    Map<Integer, String> genderMap = Stream.of(Gender.values())
            .collect(Collectors.toMap(Gender::getCode, Gender::getName));
        users.forEach(user -> {
            Integer genderCode = user.getGenderCode();
            user.setGenderName(orderTypeMap.get(genderCode));
        });
        return users;
}

我们可以使用 crane4j 进行优化。 首先,依然是在 UserVO 中使用注解对填充字段进行配置:

@Data
public class UserVO{
    private Integer id;
    //这里将Gender设置为枚举
    @AssembleEnum{
        type = Gender.class,enumKey = "code",
        props = @Mapping(ref = "genderName")
    }
    private Integer genderCode;
    private String genderName;
}

然后将 UserService 中原本的填充代码移除,并在 UserController 对应方法上添加 @AutoOperate 注解即可(有时候,我们会在 Controller 中显式的使用通用响应体包装返回值Result类,此时,我们真正需要填充的数据其实是 Result.data,则可以在 @AutoOperate 注解中通过 on 属性指定):

@RequestMapping("/user")
@RestController
public class UserController {

    @Autowried
    private UserService userService;

    @AutoOperate(type = UserVO.class, on = "data")// 声明自动填充,这里的Result类似:
    /**
     *  public class Result<T> {
        private String msg = "ok";
        private Integer code = 200;
        private T data;
         public Result(T data) {
        this.data = data;
        }
    }
    */
    @PostMapping
    public List<UserVO> listUser(@RequestBody List<Integer> ids) {
        return userService.listByIds(ids);
    } 
}

现在正式开始填充包装对象:

@PostMapping
public Result<List<UserVO>> listUser(@RequestBody List<Integer> ids) {
    // 返回值被通用响应体包装
    return new Result<>(userService.listByIds(ids));
}

综上不难看出使用了Crane4j后仅用几个注解就代替了原来几十行冗余的代码,极大提高了开发效率。并且情况越复杂,Crane4j的优势越明显!

总结

相信到这里了大家都已经或多或少的了解到了Crane4j的基本原理和基本使用方法,详情请翻阅在文章开头的文档。最后再次希望大家动动手点star,你们的star是我们不断开发的动力!