O/R Mapping自己开发 Step I

来源:互联网 发布:微信微海报制作软件 编辑:程序博客网 时间:2024/05/16 12:58

自己开发O/R Mapping模块其实说来也是挺简单。

第一步, 数据库链接。

 关于数据库链接的可移植性这里不多说了,无非工厂,代理之类的东西。

关键在于不同数据库中有些方言的区别,比如SQLServer和MySQL是利用AutoIncrement产生主键,Oracle使用Sequence。不过如果你愿意Oracle也可以使用AutoIncrement,但是Create Table的SQL会有些差别。

另外比较重要的就是Join的语句,当然标准的Inner Join,Left Join,Right Join是都支持的,不过很多习惯Oracle的兄弟们会使用(+),还是MySQL使用(*)的。

最后就是嵌套语句,MySQL可能这方面的支持会稍稍弱一点,不过到5.0已经非常好了。

这些问题其实就是解析你的Bean成为SQL的时候会用到,因此需要多加注意。毕竟最后还是需要用SQL来执行的。姑且我们称之为SQLBuilder,和DataSource一样,我们需要工厂,代理之类的东西来自适应SQLBuilder。换句话说在你使用Oracle的时候会有个OracleSQLBuilder来解析,而使用MySQL的时候会有个MySQLSQLBuilder来解析。

第二步,单表定义

表定义包含2个部分。

一是表名,换句话说就是Bean对应哪个表。

二是属性,每个属性分别对应表中的哪个字段。

写个例子: 

@Table(name="t_car")
class Car implements Serializable {
@Field(name
="car_oid", autoincrement=true, sequenceName="seq_car_oid")
private Long oid = null;
@Field(name
="name")
private String name = null;

public void setOid(Long oid) {
this.oid = oid;
}

public Long getOid() {
return this.oid;
}

public void setName(String name) {
this.name = name;
}

public String getName() {
return this.name;
}

}

这是使用Annotation定义的方式。Field是个Annotation,看看写法。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target( 
{ ElementType.METHOD, ElementType.FIELD })
public @interface Field {

    
/**
     * 对应的字段域名称
     * 
     * 
@return
     
*/

    String name();

    
/**
     * 是否是主键
     * 
     * 
@return
     
*/

    
boolean primaryKey() default false;

    
/**
     * 是否自增长
     * 
     * 
@return
     
*/

    
boolean autoIncrease() default false;

    
/**
     * 对应的Sequence名称.<br>
     * 此属性只有在autoIncrease为true的时候才生效, 目前只有Oracle数据库会使用这个属性
     * 
     * 
@return
     
*/

    String sequenceName() 
default "";

    
/**
     * 是否是时间戳
     * 
     * 
@return
     
*/

    
boolean isTimestampMark() default false;

    
/**
     * 是否是版本号
     * 
     * 
@return
     
*/

    
boolean isVersionMark() default false;
}

 

有2个声明必须记住: @Retention, 如果不是RUNTIME,那么你在运行态无法获取到这些声明, 自然也就没有办法解析. @Target, 我声明了可以写在Method和Field之前, 你可以根据你的喜好定义.

再看看Table的写法:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table{
    
/**
     * 对应的持久化对象名称. 例如表名, 视图名等.
     * 
     * 
@return
     
*/

    String name();
}

Table的写法和Field差不多, 不过内容少了很多, 主要定义一个表名就行了, 而且是写在类头上的(@Target=TYPE)

当然如果你在1.4或者以前版本的JDK,或者你不喜欢Annotaion,那么以前通常我们用XML定义。

<car>
      <table>t_car</table>
  
<property name="oid" autoincrement="true" sequence="seq_car_oid" />
  
<property name="name" />
</car>

XML定义可以写在一个文件里,也可以分别写多个文件,就看你的解析器是如何根据Class来寻找的。

其实2种方法都没什么差别,唯一的问题在于使用Annotation的话,你在看这个Bean的时候你就知道数据库的定义了,但是如果用XML定义,那么麻烦你再找一下XML文件在哪里。

看过定义自然程序需要一个解析器来读懂这些定义。这个解析器我就不给例子了,无非是一些通常的代码。

原创粉丝点击