### Fetch BeetlSQL提供了默认的3个注解用来获取额外的对象,@FetchOne,@FetchMany,和@FetchSql。 开发者可以自定自己的Fetch注解,以FetchSql为例子 ```java public class CustomerOrder2 { @AutoID Integer id; String name; Integer customerId; @FetchSql("select * from sys_customer where id =#{customerId}") Customer customer; } ``` @FetchSql必须使用@Builder注解指明实现类 ```java @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.FIELD}) @Builder(FetchSqlAction.class) public @interface FetchSql { /** * sql模板语句 * @return */ String value(); } ``` FetchSqlAction实现了FetchAction接口,推荐继承`AbstractFetchAction` ```java public interface FetchAction { public void execute(ExecuteContext ctx, List list); public void init(Class owner, Class target,Annotation config, PropertyDescriptor pd); public Annotation getAnnotation(); public PropertyDescriptor getOriginProperty(); } ``` execute方法是加载额外数据,list是sqlManager查询的结果,Fetch操作需要遍历list,获取每一个数据库查询结果,然后根据init方法的配置,知道需要额外加载哪些属性,比如CustomerOrder2对象的customer 实现FetchSql 需要考虑关键一点,就是确保如果对象已经被处理过,不需要加载额外数据了,免得无限嵌套循环,比如a加载b,b又加载a。AbstractFetchAction的queryFromCache会查询FetchContext(一个上下文)是否已经处理过此对象,AbstractFetchAction的containAttribute方法则会从FetchContext查询此对象的此属性是否已经处理