Skip to content

Java链式方法配置

Yong Zhu edited this page Jan 19, 2018 · 2 revisions

Java链式方法配置(以生成数据库DDL脚本)

Java链式方法配置使用jDialects独有的语法,用纯Java语法来进行配置。它相比于注解方式配置的优点有:更紧凑、可读性好、不受Java实体字段干拢、可重用性好(与ORM工具无关)、可动态创建和修改、便于导入、导出为Excel。
Java链式方法配置可以嵌入在POJO代码中,方便业务字段设计,也可以抽取出来放在单独的文件中进行统一管理。

Java链式方法配置示例:

	@Test
	public void sampleTest() {
		TableModel t1 = new TableModel("customers");
		t1.column("name").STRING(20).pkey();
		t1.column("email").STRING(20).pkey().entityField("email").updatable(true).insertable(false);
		t1.column("address").VARCHAR(50).defaultValue("'Beijing'").comment("address comment");
		t1.column("phoneNumber").VARCHAR(50).singleIndex("IDX2");
		t1.column("age").INTEGER().notNull().check("'>0'");
		t1.index("idx3").columns("address", "phoneNumber").unique();

		TableModel t2 = new TableModel("orders").comment("order comment");
		t2.column("id").LONG().autoId().pkey();
		t2.column("name").STRING(20);
		t2.column("email").STRING(20);
		t2.column("name2").STRING(20).pkey().tail(" default 'Sam'");
		t2.column("email2").STRING(20);
		t2.fkey().columns("name2", "email2").refs("customers", "name", "email");
		t2.fkey("fk1").columns("name", "email").refs("customers", "name", "email");
		t2.unique("uk1").columns("name2", "email2");

		TableModel t3 = new TableModel("sampletable");
		t3.column("id").LONG().identityId().pkey();
		t3.tableGenerator("table_gen1", "tb1", "pkcol2", "valcol", "pkval", 1, 10);
		t3.column("id1").INTEGER().idGenerator("table_gen1");
		t3.sequenceGenerator("seq1", "seq_1", 1, 1);
		t3.column("id2").INTEGER().idGenerator("seq1");
		t3.engineTail(" DEFAULT CHARSET=utf8");

		String[] dropAndCreateDDL = Dialect.H2Dialect.toDropAndCreateDDL(t1, t2, t3);
		for (String ddl : dropAndCreateDDL)
			System.out.println(ddl);
	}

解释:

  • LONG()、STRING()...等大写方法: 定义列的类型,运行时将翻译成对应当前数据库方言的实际SQL类型,一共有如下类型:
    常用: BOOLEAN,DOUBLE,FLOAT,INTEGER,LONG(=BIGINT),SHORT(=SMALLINT),BIGDECIMAL(=NUMERIC),STRING(=VARCHAR),DATE,TIME,TIMESTAMP,BIGINT,VARCHAR
    不常用:BINARY,BIT,BLOB,CHAR,CLOB,DECIMAL,LONGNVARCHAR,LONGVARBINARY,LONGVARCHAR,NCHAR,NCLOB,NUMERIC,NVARCHAR,REAL,SMALLINT,TINYINT,VARBINARY
  • pkey()方法定义列主键,如一个table对象有多个列用pkey()方法标记,则这些列将构成复合主键。
  • unique()方法定义唯一约束,约束名称可以省略。
  • index()方法定义索引,索引名称可以省略。
  • notNull()方法指定列内容不能为空。
  • check()方法添加一个check约束,注意有些数据库不支持check,如果数据库不支持则输出警告并忽略此设定。
  • defaultValue()方法指定缺省值。
  • fkey()方法定义外键,格式为 table.fkey(键名).columns(本表列1,本表列2...).refs(参考表,参考表列名1,参考表列名2...)
  • singleIndex()、singleUnique、singleFKey()三个方法为快捷方法,仅对当前单列生成索引、唯一约束、外键。
  • column对象和Table对象的comment方法分别用于对列和表添加注解,如果数据库不支持则输出警告并忽略此设定。
  • table.engineTail()方法仅当方言支持engine关键字时追加一个额外字串,通常用于MySQL字符集设定。column.tail()和FkeyConst.tail()方法分别对当前列或外键DDL强制追加一个额外字串。
  • autoID()方法定义一个自动自增主键类型,与JPA的Auto类型相似。jDialect利用创建一个Sequence或一个Table(如方言不支持sequence)来模拟实现,在程序中可用dialect.getNextAutoID(connection)方法来获取生成的唯一自增ID, 类型为Long类型。
  • identityId()方法定义自增类型,注意不是所有数据库都支持自增类型如Oracle将会抛出导常。
  • sequenceGenerator()用于创建Sequence,对应于JPA的@SequenceGenerator注解, 注意有些数据库不支持Sequence。
  • tableGenerator()方法对应于JPA的@TableGenerator注解,创建一个数据库表专门用来生成ID值,通常被用于ORM工具。
  • entityField()、updatable()、insertable()三个方法不影响DDL,仅用于ORM工具,表示一个字段映射到Java的POJO类的属性,并设定其update和insert属性。
  • dialect.toDropDDL()方法、toCreateDDL()方法、toDropAndCreateDDL()方法分别对应于生成当前方言的删表、建表、先删后建表DDL语句,参数为单个table实列或table实例数组,返回值是一个DDL字符串数组。一个小技巧:运行删表DDL时通常要屏蔽异常,因为第一遍运行时表格还没建立,运行Drop语句可能会报错。静态方法DDLFormatter.format()可用于格式化DDL输出。
  • toCreateDDL()方法运行时将进行保留字检查,如果定义了当前数据库方言的保留字作为列名或表名,如"user"、"order"等,将抛出异常,如果定义了非当前数据库的保留字,则仅输出警告提示。Dialect.setAllowReservedWords(Boolean)方法可以设定是否允许在DDL中出现保留字,如果允许,则不会抛出异常。

上例的输出结果如下:

alter table orders  drop constraint  fk1
alter table orders  drop constraint  fk_orders_name2_email2
drop table tb1 if exists
drop sequence if exists seq_1
drop sequence if exists jdia_seq_autoid
drop table customers if exists
drop table orders if exists
drop table sampletable if exists
create table customers ( name varchar(20),email varchar(20),address varchar(50) default 'Beijing',phoneNumber varchar(50),age integer not null check ('>0'), primary key (name,email))
create  index IDX2 on customers (phoneNumber)
create unique index idx3 on customers (address,phoneNumber)
create table orders ( id bigint,name varchar(20),email varchar(20),name2 varchar(20) default 'Sam',email2 varchar(20), primary key (id,name2))
alter table orders add constraint uk1 unique (name2,email2)
create table sampletable ( id bigint generated by default as identity,id1 integer,id2 integer, primary key (id))
create sequence jdia_seq_autoid start with 1 increment by 1
create sequence seq_1 start with 1 increment by 1
create table tb1 (pkcol2 varchar(100),valcol bigint )
alter table orders  add constraint fk_orders_name2_email2 foreign key (name2,email2) references customers (name,email)
alter table orders  add constraint fk1 foreign key (name,email) references customers (name,email)