spring整合type-orm(11)

121 阅读2分钟

前言

本来准备自己写jpa的,毕竟之前也写过。但是本着不重复造轮子的思想,还是先去GITHUB上面逛逛,白嫖别人的智慧成果也是一件美事。

只是看的代码越多,越发现自己的愚笨,哈哈。

type-orm代码大致看了下,代码写的一板一眼,oo味道十足。老外的开源精神确实值得肯定,细节处理的十分严谨,每种数据库的字段限制都有添加,想想自己写的ORM实在脸红。

代码读起来还是很简单的哦,就是围绕着Driver和QuryRuner这两个接口的实现。只实现了基础的ORM并没有对缓存进行过多处理,也没有预留太多的接口。感觉很像mybatis,还是需要自己封装和扩展的。

这里就进行最简单的整合吧。

1.和spring进行整合

编写一个抽象的基础数据链接类,实现了SpringContainer可以拿到所有注解,方便拿到Entity类。

这里还是还实现了SpringStarter,因为链接操作是异步的,需要需要一个异步启动器。

clazzMap.set(DataSource as Clazz,dataSource);将启动成功的实例注入到Spring容器中,会自动进行二次装配。

abstract class BaseDataSourceConnect extends SpringContainer implements SpringStarter {
    isSpringStater(): boolean {
        return true;
    }
    abstract getOptions(entities:Function[]):DataSourceOptions;
    
    async doStart(clazzMap: Map<Clazz, any>): Promise<any> {

        const entities:Function[] = [];

        this.getBeanDefineMap().forEach( (_bean,bd) => {

            if(bd.hasAnnotation(Table)){
                entities.push(bd.clazz)
            }

        })

        const options = this.getOptions(entities);

        const dataSource = new DataSource(options)

        await dataSource.initialize();

        clazzMap.set(DataSource as Clazz,dataSource);
    }
}

2.实现一个Sqlite启动类

实现了上面这个类,主要返回DataSourceOptions(type-orm)对象。mysql,sqlserver如法炮制。

const sqliteOptionsPrefx = 'j-spring-jpa.sqlite'
@Component()
export class SqliteStarter extends BaseDataSourceConnect {

    @Value({path:`${sqliteOptionsPrefx}.name`,type:String,force:false })
    name:string = 'sqlite';

    @Value({path:`${sqliteOptionsPrefx}.database`,type:String,force:false})
    database:string = './data.db';

    @Value({path:`${sqliteOptionsPrefx}.logging`,type:Boolean,force:false})
    logging:boolean = true;

    @Value({path:`${sqliteOptionsPrefx}.synchronize`,type:Boolean,force:false})
    synchronize:boolean = true;

    getOptions(entities:Function[]): DataSourceOptions {
        const {name,database,logging,synchronize} = this;
        const options: DataSourceOptions = {
            name,
            type: "sqlite",
            database,
            logging,
            synchronize,
            entities
        }
        return options;
    }

}

在启动时注入配置,覆盖默认配置。

spring.loadConfig({
   'j-spring-jpa':{
       sqlite:{
           database:'/d/test.db'
       }
   }
})

3.编写一个单元测试就OK了


    @Component()
    class Application {

      @Autowired({clazz:DataSource as Clazz})
      dataSource:DataSource;

      async main(){
        const connectState = this.dataSource ? 'yes':'no';
        await this.dataSource?.destroy();
        return connectState;
      }

    }

    await spring.bind(SqliteStarter).loadConfig(baseConfig).invokeStarter();

    const app = spring.getBean(Application);

    const result = await app.main();

    expect(result).toEqual('yes');


  })

下一章讲解如何整合SpringWeb,并实现自动事务。