初めに
Corodva開発をするにあたって、とにかくギリギリまでbrowser開発で粘りたかったので、その辺をいい感じに吸収してくれるプロダクトを探したところTypeORMに当たりました。
本当に素晴らしいプロダクトだと思っています。
※0.2.0以降のTypeORMからWebSQLのサポートが外れました。。。
vuejsに取込む
強引にglobal mixinしました
import { createConnection, Connection, getConnection } from "typeorm"
const merge = require('webpack-merge')
let option = merge(process.env.DB_CONECT, {
logger: new this.constructor.dbLogger(),
entities: [...(省略)]
}
let connection = await createConnection(option)
Vue.mixin({
data() {
return {
connection: connection
}
},
})
ChromeとCorodvaの切り替え
envファイルに持ちました
synchronizeはアプリケーションでタイミングを計りたかったので、自動実行させません。
- chrome+chromeheadless
module.exports = merge(devEnv, {
DB_CONECT: {
type: '"websql"',
database: '"..."',
location: '"default"',
logging: false,
synchronize: false
}
})
- cordova
DB_CONECT: {
type: '"cordova"',
database: '"..."',
location: '"default"',
logging: true,
synchronize: false
},
使い方色々
- entity
テーブルと1:1
import {BaseEntity, Entity, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn, Column} from "typeorm";
@Entity('${テーブル名}')
export class ${テーブル名} extends BaseEntity {
@PrimaryGeneratedColumn()
id = undefined;
@Column({
type: "varchar",
length: 6,
nullable: false,
})
${フィールド名} = new String();
//...テーブルのフィールドを定義
// 共通項目は自動で登録
// 登録日時
@CreateDateColumn()
regist_datetime = new Date();
// 更新日時
@UpdateDateColumn()
upd_datetime = new Date();
}
-
select
- 1件(findOne)
classオブジェクトが返却される
let selectObj = await ${エンティティクラス}.findOne({ ${フィールド名}: "検索条件" });
- 複数件(find)
classオブジェクトのArrayが返却される
let ${エンティティクラス} = await ${エンティティクラス}.find({ ${フィールド名}: "検索条件" });
- 検索オプション
const ${エンティティクラスのArray} = await ${エンティティクラス}.find({ where: { ${フィールド名}: "検索条件" ) }, order: { ${フィールド名}: "ASC" } }); // import無しでもgetRepositoryでエンティティは取れる const ${エンティティクラス} = this.connection.getRepository('${エンティティクラス}') ${エンティティクラス}.findOne({ select: ['id'], where: {id: 1}, order: { id: "ASC" } })
- findオプション
select where relations(entity定義にリレーション定義を書くと使えます) join(entity定義にリレーション定義を書くと使えます) order cache
- 1件(findOne)
-
insert+update
entityクラスのsave
でinsert or updateとなる- insert
let ${エンティティクラス} = new ${エンティティクラス}() ${エンティティクラス}.xxx_cd = '001' // newしたrecordのsaveはinsert扱い ${エンティティクラス}.save()
- update
let ${エンティティクラス} = await ${エンティティクラス}.findOne({ xxx_cd: 001 }) ${エンティティクラス}.xxx_cd = '002' // selectしたrecordのsaveはupdate扱い ${エンティティクラス}.save()
-
delete
let ${エンティティクラス} = await ${エンティティクラス}.findOne({ xxx_cd: 001 }) // selectしたrecordにremoveでdeleteとなる ${エンティティクラス}.remove()
-
transaction制御
const vm = this const transactionFunction = async (manager) => { let ${エンティティクラス} = await ${エンティティクラス}.findOne({ xxx_cd: 001 }) ${エンティティクラス}.xxx_cd = '002' ${エンティティクラス}.save() let ${エンティティクラス} = await ${エンティティクラス}.findOne({ xxx_cd: 002 }) ${エンティティクラス}.remove() } this.connection.transaction(transactionFunction).catch(error => {throw error} )
-
bulk
await this.connection.createQueryBuilder() .insert() .into(${table_name}) .values(parameters) .execute();
-
join
本当はEntityクラスにリレーション定義するんですけど・・・let items = await Items.createQueryBuilder("${エンティティ名}") .innerJoin( ${joinしたいエンティティ名}, "${別名}", "Items.item_cd = ${joinしたいエンティティ名}.item_cd AND ${joinしたいエンティティ名}.pos_dept_key_typ = :${条件のシンボル}", { ${条件のシンボル}: ${条件の変数} } ) .where("Items.start_date <= :nowDate", { nowDate: this.formatYmd(new Date()) }) .andWhere("Items.end_date >= :nowDate", { nowDate: this.formatYmd(new Date()) }) .getRawMany();
-
query
this.connection .createQueryRunner() .query(` SELECT NAME AS NAME FROM SQLITE_MASTER `) .then(resolve => { vm.queryResult = JSON.stringify(resolve, null, " "); }) .catch(reject => { vm.queryResult = reject.stack ? reject.stack : JSON.stringify(reject, null, " "); });
ここまで
これでブラウザで開発出来てそのままCorodvaで動くので便利感ただ事ではないです。