前言
本来准备自己写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,并实现自动事务。