论坛首页 Java企业应用论坛

挑战DAO模式

浏览 14671 次
锁定老帖子 主题:挑战DAO模式
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-10-31  
DAO
TOB是一个面向对象的数据库, 但是它目前将数据存储在关系数据库中, 也可以通过SQL查询对象.
(很像ORM, 但其实有一些更生层次的原因它更应该被看作一个独立的对象数据库, 此处不多讨论)

因为TOB这样的实现方式, 后台关系数据库的所有分析统计,备份维护工具和接口都没有浪费. 同时通过TOB的持久程序设计比JDBC, DAO 甚至ORM都要方便, 持久类上除了一些Annotation和一些设计原则, 根本不必程序员自己编写持久代码. 当然前提是必须掌握Java5新引入的Annotation和Generics语言特性.

以一个联系人的管理做例子, User和Contact两个类只要这样写:
(注意User类的 main 方法, 它可以直接执行. 当然需要一个关系数据库, 直接把 hsqldb 或者 H2 的jar加到CLASSPATH, 则User类就可以直接执行了)

import java.util.List;
import java.util.Vector;

import av.tob.FetalDeathException;
import av.tob.Kin;
import av.tob.MakeSwappable;
import av.tob.ObjectBaseCreationException;
import av.tob.Persistent;
import av.tob.TheObject;
import av.tob.TheObjectBase;
import av.tob.TypeSpec;
import av.tob.Writing;
import av.tob.rdb.SQLQuerier;

@MakeSwappable
public class User extends TheObject
{

    @Kin(iAm = "owner")
    protected final List<Persistent<Contact>> contacts = new Vector<Persistent<Contact>>();

    public List<Persistent<Contact>> getContacts()
    {
        return contacts;
    }

    @TypeSpec(precision = 200)
    private String name;

    public User(String name)
    {
        this.name = name;
    }

    protected User()
    {
    }

    public String getName()
    {
        return name;
    }

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

    /**
     * Test
     * 
     * @throws ObjectBaseCreationException
     * @throws FetalDeathException
     */
    public static void main(String[] args) throws ObjectBaseCreationException,
            FetalDeathException
    {
        String userName = "Compl";
        if (args.length > 0) userName = args[0];

        TheObjectBase<SQLQuerier> tob = TheObjectBase.create(SQLQuerier.class);

        List<Persistent<? extends User>> users = tob.querier.query(1, 1,
                User.class, UserQ.NAME + " = ?", userName);

        Persistent<? extends User> user;
        if (users.size() < 1)
            user = tob.birth(new User(userName));
        else
            user = users.get(0);

        String contactName = "Robbin";
        if (args.length > 1) contactName = args[1];

        System.out.println("Contacts of " + userName + " :");
        for (Persistent<Contact> contact : user.o.getContacts())
        {
            if (contactName.equals(contact.o.getName()))
                System.out.println(" *" + contact.o.getName());
            else
                System.out.println("  " + contact.o.getName());
        }

        List<Persistent<? extends Contact>> contacts = tob.querier.query(1, 1,
                Contact.class, ContactQ.OWNER$NAME + " = ? AND "
                        + ContactQ.NAME + " = ?", userName, contactName);
        if (contacts.size() < 1)
        {
            System.out.println("Creating contact " + contactName + " for user "
                    + userName);
            Contact contact = new Contact(user);
            contact.setName(contactName);
            tob.birth(contact);
        }

        tob.commitAllTransactions();
        tob.shutdown();
    }
}

import av.tob.MakeSwappable;
import av.tob.Persistent;
import av.tob.TheRelation;
import av.tob.Tie;
import av.tob.TypeSpec;
import av.tob.Writing;

@MakeSwappable
public class Contact extends TheRelation
{

    public class Owner extends Role<User>
    {
        protected Owner(Persistent<? extends User> owner)
        {
            super(owner);
        }
    }

    @Tie
    protected Owner owner;

    @TypeSpec(precision = 200, defaultValue = "'<Unnamed>'")
    private String name;

    @TypeSpec(precision = 200)
    private String address;

    @TypeSpec(precision = 50)
    private String phone;

    public Contact(Persistent<? extends User> owner)
    {
        this.owner = new Owner(owner);
    }

    protected Contact()
    {
    }

    public String getAddress()
    {
        return address;
    }

    @Writing
    public void setAddress(String address)
    {
        this.address = address;
    }

    public String getName()
    {
        return name;
    }

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

    public String getPhone()
    {
        return phone;
    }

    @Writing
    public void setPhone(String phone)
    {
        this.phone = phone;
    }

    public Owner getOwner()
    {
        return owner;
    }

}


这里用到的查询条件类 UserQ 和 ContactQ 是TOB自动生成的, 代码如下:
import av.tob.rdb.*;

public interface UserQ extends TheObjectQ
{
  String TABLE_NAME = "TOB_CONTACT_USER";

  QueryField NAME = new QueryField("o.name");
}

import av.tob.rdb.*;

public interface ContactQ extends TheObjectQ
{
  String TABLE_NAME = "TOB_CONTACT_CONTACT";

  QueryField OWNER$ID = new QueryField("o.owner");
  QueryField OWNER$NAME = new QueryField("owner.name");

  QueryField ADDRESS = new QueryField("o.address");
  QueryField NAME = new QueryField("o.name");
  QueryField PHONE = new QueryField("o.phone");
}

   发表时间:2006-10-31  
代码怎么自动插入了那么多空行? 是JE的问题还是需要注意什么?
0 请登录后投票
   发表时间:2006-11-09  
自己顶一下, 大家谁有空研究评估一下.
TOB免费版本可以从 http://ableverse.com/download-free.jsp 下载, 然后下载一个 HyperSonic http://www.hsqldb.org 或者 H2 database engine http://h2database.com 放到classpath里就可以直接运行了.
0 请登录后投票
   发表时间:2006-11-09  
annotation大潮不可挡....
0 请登录后投票
   发表时间:2006-11-10  
son of the bitch,还不是很习惯annotation!
0 请登录后投票
   发表时间:2006-11-10  
都需要继承你提供的TOB类,不太好吧。
0 请登录后投票
   发表时间:2006-11-10  
没看出来是怎样的挑战了DAO模式的
0 请登录后投票
   发表时间:2006-11-10  
nihongye 写道
没看出来是怎样的挑战了DAO模式的

业务类上已经没有任何持久逻辑了, 并且是在没有任何DAO的情况下实现的.
0 请登录后投票
   发表时间:2006-11-11  
complystill 写道
nihongye 写道
没看出来是怎样的挑战了DAO模式的

业务类上已经没有任何持久逻辑了, 并且是在没有任何DAO的情况下实现的.


tob.birth(new User(userName)); 
tob.querier.query(1, 1, 
                 Contact.class, ContactQ.OWNER$NAME + " = ? AND " 
                         + ContactQ.NAME + " = ?", userName, contactName); 

birth不是做持久化吗?
0 请登录后投票
   发表时间:2006-11-11  
没看出来优越在哪里, 能否与Hibernate/ibatis横向比较一下, 证明所谓"业务类上已经没有任何持久逻辑了, 并且是在没有任何DAO的情况下实现的."

按我看tob不就是一个通用的DAO么? 我用hibernate也一样啊, session.save(Object), 一样的通用DAO.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics