阅读更多

154顶
42踩

企业架构
Douyu是一种完全采用Java语言开发的、运行于JVM之上的新型基础开发平台。
在web层,Douyu完全抛弃了JSP/Servlet,
在数据库访问层,Douyu不依赖于任何ORM(对像关系映射)框架(如Hibernate)。


Douyu将Java语言编译器、Http服务器、MVC完美整合在一起,
几乎实现了ORM全自动化,同时在Java语言层面引入了权限管理模型。


Douyu内置的Java语言编译器基于OpenJDK Javac编译器(b60版),
并进行了修改和扩充,跟Http服务器结合之后能在控制器层发挥出强大的威力,
你只要修改Java源文件,然后刷新浏览器就能查看运行结果,
同时编译器也是实现ORM自动化的基石。

Douyu内置的Http服务器是基于NIO技术的,
是对Tomcat6及com.sun.net.httpserver(总共1300多个Java源文件)进行大刀阔斧的改造后得来的,
改造后的Http服务器目前只有60个左右的源文件,支持Http1.0/1.1协议。

Douyu内置的权限管理模型目前包含了功能权限、字段权限两类,
功能权限一般对应控制器类中的Action方法,Action方法可以与表单中的按钮关联,
字段权限能控制表单中的字段是否可以查看、修改或隐藏。

Douyu内置的ORM已几乎实现自动化,你只须建个数据库表(如pet),
然后在服务器配置文件中配置数据库驱动、并为每个数据库指定一个包名(如my.oracle.table),
然后就你可以在你的Java源文件中用import my.oracle.table.Pet导入模型类Pet。
Douyu还支持横跨多个数据库的事务,还支持保存点(Savepoint)。

Douyu项目主页目前放在:
http://code.google.com/p/douyu/

下面是一些简单的代码片断:


Hello World


@Controller
public class HelloWorld {
	public void index(PrintWriter out) {
		out.println("Hello World!");
	}
}



自动提取表单参数:


<FORM METHOD=POST ACTION="User/show">
	姓名:<INPUT TYPE="text" NAME="name">
	年龄:<INPUT TYPE="text" NAME="age">
	<INPUT TYPE="submit">
</FORM>


@Controller
public class User {
	public void show(String name, int age) {
		...
	}
}


文件上传


	<FORM ENCTYPE="multipart/form-data" METHOD="POST" ACTION="FileUpload">
    文件1:<INPUT NAME="file1" TYPE="file"><br>
	说明 :<TEXTAREA NAME="description"></TEXTAREA><br>
    <INPUT TYPE="submit" VALUE="上传">
    </FORM>


import com.douyu.http.UploadedFile;

@Controller
public class FileUpload {
	public void index(UploadedFile file1, String description) {
		File f = new File("D:/Douyu/temp/uploadedFiles", file1.getSimpleName());
		file1.saveTo(f);
	}
}


基本的CRUD操作


create table pet(
  id  int not null auto_increment,
  name varchar(50) not null,
  age int,
  primary key(id)
);


import com.douyu.main.Context;
import sql.table.mysql.Pet;

@Controller
public class Crud {
	public void index(Context c) {
		Pet pet = new Pet();
		pet.name("pet1");
		pet.age(3);
		c.insert(pet);

		pet.name("MyPet");
		c.update(pet);

		c.delete(pet);

		Rows<Pet> rows = new Rows<Pet>(Pet.class);
		rows.offset = 1;
		rows.limit = 100;
		c.select(rows);
		for(Pet p : rows.rowList) {
			...
		}
	}
}



横跨多个数据库的事务


import com.douyu.main.Context;
import my.table.oracle.Table1;
import my.table.mysql.Table2;

@Controller
public class Transaction {
	public void index(Context c) {
		Table1 t1 = new Table1();
		t1.f1("1234");
		Table2 t2 = new Table2();
		t2.f2("1234");

		c.beginTransaction();

		c.insert(t1);
		c.insert(t2);

		c.setSavepoint(); 

		t2.f2("abcd");
		c.update(t2);

		c.endTransaction();
	}
}



Douyu将使用两种开源协议:GPL2.0、 Apache License Version 2.0

所有与编译器有关的源代码使用GPL2.0协议(因为OpenJDK Javac编译器是使用这个协议的)
其他源代码使用Apache License Version 2.0协议开源。


不过目前Douyu的版本只是0.1.0,还不稳定,所以只是提供了二进制版,
目前我也并不推荐你研究Douyu的源代码,因为这可能会浪费你的时间,
因为Douyu的内部实现变动很频繁,在一年之内,大大小小的版本变更次数已超过100次了,
源代码中的注释也非常少,根本就来不急写,等过几个版本稳定先后再发布源代码。

目前Douyu的开发工作只有我一个人,全凭个人兴趣在家全职开发,
如果你对Douyu的实现有兴趣,想参与进来,我也是欢迎的,
但是你必须对Http协议、JDBC规范、Java语言编译器有相当程度的了解,
否则的话你可能在看Douyu的源代码时很吃力。


要想了解更多内容请看:
Without SSH/JSP/Servlet,不走寻常路,Java可以更酷
http://zhh2009.iteye.com/blog/517796

这篇文章是昨晚在JavaEye刚发布的,详细说明了Douyu的更种用法,
里面也详细说明了Douyu的很多设计理念以及我个人的很多研究心得。

赶快去看看吧。。。
154
42
评论 共 209 条 请登录后发表评论
49 楼 icezx 2009-11-16 14:45
看了几个特性相当心动。。。
48 楼 zcq100 2009-11-16 14:45
终结者?你认为会呢。
不过支持LZ的创新
47 楼 liuruncheng 2009-11-16 14:11
Servlet再怎么说也是一个标准,一种得到众多厂家支持的底层技术。凭空做一套这样的东东有多大的商用价值是值得考虑的。楼主的作品作为一种娱乐倒是不错,呵呵
不依托在稳定的JEE基础上来做,是不可能商用了,也就没法产品软件应有的价值,商业要求的是稳定,成熟,可靠
46 楼 daxiong921 2009-11-16 14:07
大家多多参与提供建议,框架才会进一步完善哦
45 楼 daxiong921 2009-11-16 14:06
play引用了其它的jar,自己核心jar才475K呢
44 楼 hqs7636 2009-11-16 14:05
如果你牛就请多参与改进和加强,别那么多风凉话

那么多开源框架,没一个让俺心动,这个似乎。。。

期待他越来越好
43 楼 WhiLang 2009-11-16 14:04
楼主的精神值得学习
42 楼 l42420460 2009-11-16 14:02
myrev 写道
思想新颖,大胆创新!!支持!!


41 楼 l42420460 2009-11-16 14:01
描述的不错
40 楼 qianfeng0819 2009-11-16 13:55
其实确实不错的
39 楼 Arden 2009-11-16 13:51
这东西确实很强大,比playframework还要简洁,Douyu才1M多,而playframework有40多M,真是服了~~
38 楼 ZHH2009 2009-11-16 13:47
snowolf9929 写道
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version n
umber in .class file
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
第一次运行。。。。。。


UnsupportedClassVersionError这个错误是因为Douyu是用JDK1.6编译的,
class文件的版本号在JDK1.5中不能识别,所以就会出现这个错误。

换成JDK1.6应该就可以了。
37 楼 energykey 2009-11-16 13:45
单凭楼主的精神我觉得就值得大家赞扬。
javaqiang 写道
望Douyu不会成为
caoyangx 写道
看描述不错,希望它对得起这种的宣传,希望Douyu不会成为duoyu(多余)。

我一开始也看成了多余,不过支持一下LZ,大家少泼冷水了,很多东西是不会创造出来就是完美的,而且LZ在一年之内大大小小的版本变更次数已超过100次了,可见这个框架已经注入了他的生命。泼凉水的兄弟们,你们没看见LZ这么欢迎的邀请大家一起探讨研究吗?国外那么多著名的框架,刚开始也不就是十来个人的小团队组建起来的,而国内知名的框架(指开源的)却知之甚少。要么就是被:“不要重复造轮子”这句话误导,这句话本身的意思是很对,但我们现在用的spring,struts,hibernante,ibatis。。。想想这些都是外国的轮子,自己的呢?外国人用吗?再说自己造个轮子只要它是好轮子,有自己的优势,这就不构成重复造轮子。


你说的有道理!!!我们应该支持国产,而且这个不是山寨框架,而是一种全新的思维。不过一个人的力量未免太单薄了些?要是大牛们都能团结起来,为国争光啊,多好啊,而且中国人肯定支持中国人的产品的。
36 楼 nychen2000 2009-11-16 13:34
很多人用挑刺的心态来看到楼主的作品,这是不对的!!!

一个新的东西一出来肯定是不完善的,我很欣赏楼主的独特视角,企业应用领域的确需要一场革命!
35 楼 snowolf9929 2009-11-16 13:26
看来是不支持jdk5
34 楼 snowolf9929 2009-11-16 13:24
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version n
umber in .class file
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
第一次运行。。。。。。
33 楼 jindw 2009-11-16 13:22
mccxj 写道
[quote。。。


扫了一下,的确很简单~~不知你是应用于什么场景的?


最早只是想搞一些傻瓜的环境模拟,搞一个小型的嵌入式服务器,web start点击即可生成我需要的调试环境。

比如说,我可以吧JSI开发环境搭建起来,吧Lite测试环境搭建起来。

现在也用它做公司的调试服务器平台的服务器基础。
也用它写我的Andriod手机应用。

比如通过Wifi连接笔记本,在笔记本上操作手机上的文件系统,或者调用手机的其他功能。等等。
32 楼 javaqiang 2009-11-16 13:21
望Douyu不会成为
caoyangx 写道
看描述不错,希望它对得起这种的宣传,希望Douyu不会成为duoyu(多余)。

我一开始也看成了多余,不过支持一下LZ,大家少泼冷水了,很多东西是不会创造出来就是完美的,而且LZ在一年之内大大小小的版本变更次数已超过100次了,可见这个框架已经注入了他的生命。泼凉水的兄弟们,你们没看见LZ这么欢迎的邀请大家一起探讨研究吗?国外那么多著名的框架,刚开始也不就是十来个人的小团队组建起来的,而国内知名的框架(指开源的)却知之甚少。要么就是被:“不要重复造轮子”这句话误导,这句话本身的意思是很对,但我们现在用的spring,struts,hibernante,ibatis。。。想想这些都是外国的轮子,自己的呢?外国人用吗?再说自己造个轮子只要它是好轮子,有自己的优势,这就不构成重复造轮子。
31 楼 mccxj 2009-11-16 13:17
mccxj 写道
jindw 写道
有几个问题:
。。。
出发点和play!是类似的,从根本上抛弃servlet那套标准~~
就怕bug多,和集成的问题~~以后怕没人维护



那这个play是玩大了,呵呵。

我也很讨厌servlet标准。
所以写了一个有点像xwork的,没有servlet的小型Java WebServer。
貌似不到10个类文件吧,小的可以了。

有兴趣的同学可以去试试。
http://www.xidea.org/android/
http://lite.googlecode.com/svn/trunk/examples/FileServer/




扫了一下,的确很简单~~不知你是应用于什么场景的?
30 楼 jindw 2009-11-16 13:08
jindw 写道
有几个问题:
。。。
出发点和play!是类似的,从根本上抛弃servlet那套标准~~
就怕bug多,和集成的问题~~以后怕没人维护



那这个play是玩大了,呵呵。

我也很讨厌servlet标准。
所以写了一个有点像xwork的,没有servlet的小型Java WebServer。
貌似不到10个类文件吧,小的可以了。

有兴趣的同学可以去试试。
http://www.xidea.org/android/
http://lite.googlecode.com/svn/trunk/examples/FileServer/



发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • VC_MFC中CRecordset类详解

    CRecordset类的详细说明和MFC中使用CRecordset类的详细方法

  • CRecordset类

    CRecordset类代表一个记录集,是MFC的ODBC类中最重要、功能最强大的类。 #include 1.      动态集、快照、光标和光标库 在多任务操作系统或网络环境中,多个用户可以共享同一个数据源。共享数据的一个主要问题是如何协调各个用户对数据源的修改。例如,当某一个应用改变了数据源中的记录时,别的连接至该数据源的应用应该如何处理。对于这个问题,基于MFC的ODBC应用程序可以采

  • CRecordset::AddNew()函数

        调用此函数来添加一个新的记录到数据表中,你必须调用成员函数Requery来查看新添加到记录。记录的字段初始值为NULL。为了完成完整的操作,你必须调用Update函数来更新保存你对数据源的改动。    注意:    如果你连续执行批量的记录操作,你不能使用AddNew函数。它将导致失败中断。尽管CRecordset类没有提供一个方法来做批量的记录操作,但是你可以利用ODBC API SQL

  • 单独使用CRecordSet (转)

    单独使用CRecordSet (转)[@more@]闻怡洋 Mailto:wyy_cq@21cn.com"&gt;wyy_cq@21cn.com .NET/"&gt;http://www.vchelp.net/ 一般情况下A...

  • 有关MFC ODBC类对打开的CRecordset数据集无法进行更新操作释疑

             在用MFC数据库类CDatabase和CRecordset类声明的对像无法对打开的数据集进行编辑、添加、删除。偶然间让我碰到个这样的问题让我费了不少精神,不知道为什么数据库能正常打开,数据集也正常Open。可是就是没办法进入编辑状态,老是会弹出“记录集只读”的提示。----------------------------------------------------------

  • 使用CRecordset update()函数不能更新

    最近做一个有数据库编程的项目,使用了CRecordset类。总结下心得,方便自己,方便后学的人。     在中介绍了有关CRecordset类的具体用法。那么有以下两个 问题:    1.CRecordview这个类做了什么?      它继承自CFormview,在OnInitialUpdate()函数中调用了CRecordset类的open()方法。      因为vc++并不能直接

  • MFC的CRECORDSET对数据库的操作 .

    MFC数据库操作系列—数据中间层(CRECORDSET) MFC数据库接口分为两种:ODBC和OLE DB 。ODBC而言提供开放的访问方式,使用较为简单,但是需要注册数据库,这导致在部署应用程序的时候需要重新布置数据库,并且个人意见:数据库操作不涉及大量的数据交换建议使用。   CRECORDSET为数据库和应用程序之间交换数据提供和很好的封装。掌握CRECORDSET必要的字段和方法功能

  • CRecordset类学习记录

    这里写自定义目录标题CRecordset类简介快照和动态集的区别CRecordset类成员数据成员构造记录集属性记录集更新操作记录集定位操作其他记录集操作记录集重载函数 CRecordset类简介 CRecordset对象代表从一个数据源选择的一组记录的集合,被称作“记录集”。CRecordset对象可以以两种形式使用:动态集和快照。动态集是与其它用户的更新保持同步的动态数据集。快照是数据的静态视图。每一种形式都代表打开记录集时固定的一组记录。但是当滚动到动态集中的一个记录时,动态集将反映后来由其它用户或由

  • 如何使用CRecordSet类---入门指导

        大家好,我是北京邮电大学的一名学生,Jamie lee。前不久学习了数据库的编程,在这里总结一下,如大家分享一下入门的经验。   先大体介绍我做的数据库编程用到的技术。有ODBC,MFC中CRecordset,MySQL数据库和它的相应工具--SQL Manager Lite for MySQL。看到这个多陌生的东东肯定很挠头吧。其实很简单的,你自己也可以用一天搞定。前提是看完我篇心得,呵呵。   1.首先用你的数据库管理软件,建立一个你要处理的数据库。因为我用的是MySQL,所以我用SQL Man

  • VC数据库编程 MFC中相关类

    CRecordSet类     一般情况下AppWizard会在数据库应用程序中自动产生CRecordset的派生类,并将派生类和某个数据源中的表联系起来也可以和视图上的子窗口联系起来。但是有时这样做会影响到程序的灵活性,这时候我们可以单独使用CRecordSet类。利用CRecordSet类我们可以执行SQL语句,并可以读出结果集中数据。     首先我们需要包含头文件afxdb

  • 一个在vs2005+上创建一个基于CRecordView的对话框

    在vs2005+之上 好像基类没有CRecordView类,要想建立一个基于CRecordView的类,我暂时没有找到好的方法,只能手动添加了。。。 这里的SSS是你要创建的类的名字; #if !defined(AFX_SSS_H__4F498E08_A53F_46D5_B438_AD50C0E3A6F1__INCLUDED_) #define AFX_SSS_H__4F498E08_A53

Global site tag (gtag.js) - Google Analytics