MySQL用户管理

MySQL管理员应该知道如何设置MySQL用户账号,指出哪个用户可以连接服务器,从哪里连接,连接后能做什么。MySQL 3.22.11开始引入两条语句使得这项工作更容易做:GRANT语句创建MySQL用户并指定其权限,而REVOKE语句删除权限。两条语句扮演了mysql数据库的前端角色,并提供与直接操作这些表的内容不同的另一种方法。CREATE和REVOKE语句影响4个表:   授权表内容   user 能连接服务器的用户以及他们拥有的任何全局权限   db 数据库级权限   tables_priv 表级权限   columns_priv 列级权限   还有第5个授权表(host),但它不受GRANT和REVOKE的影响。   当你对一个用户发出一条GRANT语句时,在user表中为该用户创建一条记录。如果语句指定任何全局权限(管理权限或适用于所有数据库的权限),这些也记录在user表中。如果你指定数据库、表和列级权限,他们被分别记录在db、tables_priv和columns_priv表中。   用GRANT和REVOKE比直接修改授权表更容易些,然而,建议你阅读一下《MySQL安全性指南》。这些表异常重要,而且作为一名管理员,你应该理解它们如何超越GRANT和REVOKE语句的功能水平。   在下面的章节中,我们将介绍如何设置MySQL用户账号并授权。我们也涉及如何撤权和从授权表中删除用户。   你可能也想考虑使用mysqlaccess和mysql_setpermission脚本,它是MySQL分发的一部分,它们是Perl脚本,提供GRANT语句的另一种选择设置用户账号。mysql_setpermission需要安装DBI支持。   1 创建用户并授权   GRANT语句的语法看上去像这样:   GRANT privileges (columns)   ON what   TO user IDENTIFIED BY "password"   WITH GRANT OPTION    要使用该语句,你需要填写下列部分:   privileges   授予用户的权限,下表列出可用于GRANT语句的权限指定符:   权限指定符   权限允许的操作   ALTER 修改表和索引   CREATE 创建数据库和表   DELETE 删除表中已有的记录   DROP 抛弃(删除)数据库和表   INDEX 创建或抛弃索引   INSERT 向表中插入新行   REFERENCE 未用   SELECT 检索表中的记录   UPDATE 修改现存表记录   FILE 读或写服务器上的文件   PROCESS 查看服务器中执行的线程信息或杀死线程   RELOAD 重载授权表或清空日志、主机缓存或表缓存。   SHUTDOWN 关闭服务器   ALL 所有;ALL PRIVILEGES同义词   USAGE 特殊的“无权限”权限   上表显示在第一组的权限指定符适用于数据库、表和列,第二组数管理权限。一般,这些被相对严格地授权,因为它们允许用户影响服务器的操作。第三组权限特殊,ALL意味着“所有权限”,UASGE意味着无权限,即创建用户,但不授予权限。   columns   权限运用的列,它是可选的,并且你只能设置列特定的权限。如果命令有多于一个列,应该用逗号分开它们。   what   权限运用的级别。权限可以是全局的(适用于所有数据库和所有表)、特定数据库(适用于一个数据库中的所有表)或特定表的。可以通过指定一个columns字句是权限是列特定的。   user   权限授予的用户,它由一个用户名和主机名组成。在MySQL中,你不仅指定谁能连接,还有从哪里连接。这允许你让两个同名用户从不同地方连接。MySQL让你区分他们,并彼此独立地赋予权限。   MySQL中的一个用户名就是你连接服务器时指定的用户名,该名字不必与你的Unix登录名或Windows名联系起来。缺省地,如果你不明确指定一个名字,客户程序将使用你的登录名作为MySQL用户名。这只是一个约定。你可以在授权表中将该名字改为nobody,然后以nobody连接执行需要超级用户权限的操作。   password   赋予用户的口令,它是可选的。如果你对新用户没有指定IDENTIFIED BY子句,该用户不赋给口令(不安全)。对现有用户,任何你指定的口令将代替老口令。如果你不指定口令,老口令保持不变,当你用IDENTIFIED BY时,口令字符串用改用口令的字面含义,GRANT将为你编码口令,不要象你用SET PASSWORD 那样使用password()函数。   WITH GRANT OPTION子句是可选的。如果你包含它,用户可以授予权限通过GRANT语句授权给其它用户。你可以用该子句给与其它用户授权的能力。   用户名、口令、数据库和表名在授权表记录中是大小写敏感的,主机名和列名不是。   一般地,你可以通过询问几个简单的问题来识别GRANT语句的种类:   谁能连接,从那儿连接?   用户应该有什么级别的权限,他们适用于什么?   用户应该允许管理权限吗?   下面就讨论一些例子。   1.1 谁能连接,从那儿连接?   你可以允许一个用户从特定的或一系列主机连接。有一个极端,如果你知道降职从一个主机连接,你可以将权限局限于单个主机:   GRANT ALL ON samp_db.* TO boris@localhost IDENTIFIED BY "ruby"   GRANT ALL ON samp_db.* TO fred@res.mars.com IDENTIFIED BY "quartz"   (samp_db.*意思是“samp_db数据库的所有表)另一个极端是,你可能有一个经常旅行并需要能从世界各地的主机连接的用户max。在这种情况下,你可以允许他无论从哪里连接:   GRANT ALL ON samp_db.* TO max@% IDENTIFIED BY "diamond"   “%”字符起通配符作用,与LIKE模式匹配的含义相同。在上述语句中,它意味着“任何主机”。所以max和max@%等价。这是建立用户最简单的方法,但也是最不安全的。   取其中,你可以允许一个用户从一个受限的主机集合访问。例如,要允许mary从snake.net域的任何主机连接,用一个%.snake.net主机指定符:   GRANT ALL ON samp_db.* TO mary@.snake.net IDENTIFIED BY "quartz";   如果你喜欢,用户标识符的主机部分可以用IP地址而不是一个主机名来给定。你可以指定一个IP地址或一个包含模式字符的地址,而且,从MySQL 3.23,你还可以指定具有指出用于网络号的位数的网络掩码的IP号:   GRANT ALL ON samp_db.* TO boris@192.168.128.3 IDENTIFIED BY "ruby"   GRANT ALL ON samp_db.* TO fred@192.168.128.% IDENTIFIED BY "quartz"   GRANT ALL ON samp_db.* TO rex@192.168.128.0/17 IDENTIFIED BY "ruby"   第一个例子指出用户能从其连接的特定主机,第二个指定对于C类子网192.168.128的IP模式,而第三条语句中,192.168.128.0/17指定一个17位网络号并匹配具有192.168.128头17位的IP地址。    如果MySQL抱怨你指定的用户值,你可能需要使用引号(只将用户名和主机名部分分开加引号)。   GRANT ALL ON samp_db.president TO "my friend"@"boa.snake.net"   1.2 用户应该有什么级别的权限和它们应该适用于什么?   你可以授权不同级别的权限,全局权限是最强大的,因为它们适用于任何数据库。要使ethel成为可做任何事情的超级用户,包括能授权给其它用户,发出下列语句:   GRANT ALL ON *.* TO ethel@localhost IDENTIFIED BY "coffee" WITH GRANT OPTION   ON子句中的*.*意味着“所有数据库、所有表”。从安全考虑,我们指定ethel只能从本地连接。限制一个超级用户可以连接的主机通常是明智的,因为它限制了试图破解口令的主机。   有些权限(FILE、PROCESS、RELOAD和SHUTDOWN)是管理权限并且只能用"ON *.*"全局权限指定符授权。如果你愿意,你可以授权这些权限,而不授权数据库权限。例如,下列语句设置一个flush用户,他只能发出flush语句。这可能在你需要执行诸如清空日志等的管理脚本中会有用:   GRANT RELOAD ON *.* TO flushl@localhost IDENTIFIED BY "flushpass"   一般地,你想授权管理权限,吝啬点,因为拥有它们的用户可以影响你的服务器的操作。   数据库级权限适用于一个特定数据库中的所有表,它们可通过使用ON db_name.*子句授予:   GRANT ALL ON samp_db TO bill@racer.snake.net INDETIFIED BY "rock"   GRANT SELECT ON samp_db TO ro_user@% INDETIFIED BY "rock"   第一条语句向bill授权samp_db数据库中所有表的权限,第二条创建一个严格限制访问的用户ro_user(只读用户),只能访问samp_db数据库中的所有表,但只有读取,即用户只能发出SELECT语句。   你可以列出一系列同时授予的各个权限。例如,如果你想让用户能读取并能修改现有数据库的内容,但不能创建新表或删除表,如下授予这些权限:   GRANT SELECT,INSERT,DELETE,UPDATE ON samp_db TO bill@snake.net INDETIFIED BY "rock"   对于更精致的访问控制,你可以在各个表上授权,或甚至在表的每个列上。当你想向用户隐藏一个表的部分时,或你想让一个用户只能修改特定的列时,列特定权限非常有用。如:   GRANT SELECT ON samp_db.member TO bill@localhost INDETIFIED BY "rock"   GRANT UPDATE (expiration) ON samp_db. member TO bill@localhost   第一条语句授予对整个member表的读权限并设置了一个口令,第二条语句增加了UPDATE权限,当只对expiration列。没必要再指定口令,因为第一条语句已经指定了。   如果你想对多个列授予权限,指定一个用逗号分开的列表。例如,对assistant用户增加member表的地址字段的UPDATE权限,使用如下语句,新权限将加到用户已有的权限中:   GRANT UPDATE (street,city,state,zip) ON samp_db TO assistant@localhost   通常,你不想授予任何比用户确实需要的权限宽的权限。然而,当你想让用户能创建一个临时表以保存中间结果,但你又不想让他们在一个包含他们不应修改内容的数据库中这样做时,发生了要授予在一个数据库上的相对宽松的权限。你可以通过建立一个分开的数据库(如tmp)并授予开数据库上的所有权限来进行。例如,如果你想让来自mars.net域中主机的任何用户使用tmp数据库,你可以发出这样的GRANT语句:   GRANT ALL ON tmp.* TO ""@mars.net   在你做完之后,用户可以创建并用tmp.tbl_name形式引用tmp中的表(在用户指定符中的""创建一个匿名用户,任何用户均匹配空白用户名)。   1.3 用户应该被允许管理权限吗?   你可以允许一个数据库的拥有者通过授予数据库上的所有拥有者权限来控制数据库的访问,在授权时,指定WITH GRANT OPTION。例如:如果你想让alicia能从big.corp.com域的任何主机连接并具有sales数据库中所有表的管理员权限,你可以用如下GRANT语句:   GRANT ALL ON sales.* TO alicia@%.big.corp.com INDETIFIED BY "applejuice" WITH GRANT OPTION   在效果上WITH GRANT OPTION子句允许你把访问授权的权利授予另一个用户。要注意,拥有GRANT权限的两个用户可以彼此授权。如果你只给予了第一个用户SELECT权限,而另一个用户有GRANT加上SELECT权限,那么第二个用户可以是第一个用户更“强大”。   2 撤权并删除用户   要取消一个用户的权限,使用REVOKE语句。REVOKE的语法非常类似于GRANT语句,除了TO用FROM取代并且没有INDETIFED BY和WITH GRANT OPTION子句:   REVOKE privileges (columns) ON what FROM user   user部分必须匹配原来GRANT语句的你想撤权的用户的user部分。privileges部分不需匹配,你可以用GRANT语句授权,然后用REVOKE语句只撤销部分权限。   REVOKE语句只删除权限,而不删除用户。即使你撤销了所有权限,在user表中的用户记录依然保留,这意味着用户仍然可以连接服务器。要完全删除一个用户,你必须用一条DELETE语句明确从user表中删除用户记录:   %mysql -u root mysql   mysql>DELETE FROM user   ->WHERE User="user_name" and Host="host_name";   mysql>FLUSH PRIVILEGES;    DELETE语句删除用户记录,而FLUSH语句告诉服务器重载授权表。(当你使用GRANT和REVOKE语句时,表自动重载,而你直接修改授权表时不是。)(完) <淘宝热门商品:
 

¥:4.00 

蓉蓉de美女加工厂 打造淘宝最低价

 

198.00 元  

野葛根丰胸胶囊 植物萃取 天然健康


来源:程序员网

小小豆叮

Java Script与Java Applet的综合运用(二)

上次我们介绍了使用Java Script改变Java Applet中的变量的方法(严格来讲应该是改变了String类,不过可以简单的把String类看成是变量);我们说直接在Java Script中改变Java Applet中的变量是不可取的(至少是不推荐的)。因为Java Applet本身并不知道变量被改变, 这会给Applet程序带来隐患(还记得我们不得不调用repaint()函数来刷新显示吗?)。更为积极的做法是在Java Applet中提供public函数支持对内部对象的存取。下面我们对HelloWorld1.java和example.html进行改进,介绍如何在Java Script中调用Java Applet的函数: 考虑到浏览器对同名的Java Applet往往使用cache,因此我们把程序命名为HelloWorld2.java HelloWorld2.java import java.awt.*; import java.applet.*; public class HelloWorld2 extends Applet//主类名必须与文件名相同 { String text="Hello World!";//去掉text的public属性 public void paint(Graphics g) {g.drawString(text,20,20);} //这里增加一个public函数 public void SetString(String NewString) { text=NewString; repaint();//自动调用repaint()函数 } } 编译后生成HelloWorld2.class; example2.html <html> <head><title>例子</title></head> <body> <script language="JavaScript"> <!-- function SetText() { document.app.SetString("世界你好!"); //这里不再需要repaint()函数了 } //--> </script> Java Script与Java Applet的综合运用例二<br> <applet code="HelloWorld2.class" width="100" height="28" name="app"> </applet> <form> <input type="button" value="请点击这里" onclick="SetText()"> </form> </body> </html> 同样打开example2.html点击按钮后你会发现"Hello World!"变成了"世界你好!",说明调用函数成功。 这种方法相比较前一种而言显然更加安全可靠。此时若想再直接访问text,Java将提示出错。 <淘宝热门商品:
 

¥:29.00 

‖ 淘时尚 ‖入托名字条‖布质可烫可缝‖姓名贴‖

‖四钻‖棉质耐洗‖全彩色免缝姓名条 熨烫入托名字条 迪斯尼

 

4.00 元  

阳光网游挂机程序专业店

[自动发货]梦幻西游辅助脚本单开压镖+半自动跑商+单开打图日卡


来源:程序员网

小小豆叮

小议如何在Applet 中显示图象

一、在Applet 中显示图象需要引入以下包,并调用ImageObserver接口.:   import java.awt.image.*;   import java.awt.image.ImageObserver;   import java.net.URL;   public class MyApplet extends Applet implements ImageObserver { ...   二、定义图象路径   URL imgURL = getDocumentBase();   将路径设为和你的html文件在相同。   URL imgUrl = getClassBase();   将路径设为和你的html文件在相同。   三、获取图象   img = getImage(imgURL,imgName);   当然,有可能你想将自己的图象文件放到一个目录里去,那么你可以这样做   img = getImage(imgURL, "img" + imgName);   四、显示图象   最基本方法是调用drawImage(),这个方法在Graphics类中有定义,最简单的调用形式如下:   g.drawImage(image, xPosition, yPosition, this);   最后一个参数呼叫了ImageObserver.   五、最后的补充   以上所说的都是最基本的,当然有时候你甚至想把你的图象文件打成jar包,这时,你就需要用到   getResourceAsStream() 方法了。   InputStream in = getClass().getResourceAsStream("image.gif");   byte buffer[] = new byte[in.available()];   for (int i = 0; n = in.available(); i < n; i ++)   buffer[i] = (byte)in.read();   Image img = createImage(buffer);   六、一个完整的小实例   import java.awt.*;   import java.applet.*;   import java.awt.image.*;   import java.awt.image.ImageObserver;   import java.net.URL;   //使用ImageObserver接口   public class MyApplet extends Applet implements ImageObserver{   Image img;   String imgPath = "";   int xpoint = 100, ypoint = 100;   public void init() {   setBackground(Color.white); //设置背景色   setForeground(Color.blue); //设置前景色   imgPath = "img/" + "test.gif"; //设置图象文件路径   }   public void paint(Graphics g) {   URL imgURL = getDocumentBase();   img = getImage(imgURL, imgPath);   g.drawImage(img,xpoint,ypoint,this);   }   } 来自:http://ecapital.myetang.com/java/article/s9935.htm <淘宝热门商品:
 

¥:4.00 

蓉蓉de美女加工厂 打造淘宝最低价

 

 

哈喽嘟嘟-柠檬绿茶.心蓝t透0.双生儿香港平价店.


来源:程序员网

小小豆叮

如何设置GUI的LookAndFeel包路径

可以参考下面的定义: private String mac = "com.sun.java.swing.plaf.mac.MacLookAndFeel"; private String metal = "javax.swing.plaf.metal.MetalLookAndFeel"; private String motif = "com.sun.java.swing.plaf.motif.MotifLookAndFeel"; private String windows = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; <淘宝热门商品:
 

¥:88.00 

玩儿宝贝 小朋友的礼物

精装礼品手提箱

 

¥:7.80 

高更食品极美滋新奥尔良系列烧烤腌料皇冠旗舰店

【皇冠之家推荐】Jumex极美滋㊣葱香烧烤腌料70g/7.80新品推荐


来源:程序员网

小小豆叮

Java Script与Java Applet的综合运用(三)

这次我们来谈一谈Java Applet之间的互相调用,这里所说的Java Applet是指同页之间的Java Applet。由于这里涉及到Java Applet编程的细节,可能具有一些难度。如果你有过Java的编程经验,你会发现这很容易,并能很快掌握;若你是Java新手,也不要产生畏难心理,你需要一些介绍Java编程的书籍,最重要的是实践,慢慢你就会掌握Java编程技巧的;当然如果你是Java高手,嘿嘿!请教教我如何进行Java编程吧。好了,Let's go! 我们这次也用举例的方式来介绍Java Applet之间的调用。仍旧用HelloWorld1 (HelloWorld最容易掌握,不是吗?)作为例子。 HelloWorld1.java import java.awt.*; import java.applet.*; public class HelloWorld1 extends Applet { public String text="Hello World!";//请注意此处的public public void paint(Graphics g) {g.drawString(text,20,20);} } 还是最初的那个HelloWorld1,丝毫没有改变。 SetText.java import java.awt.*; import java.applet.*; import java.awt.Event; public class SetText extends Applet { String newtext="世界你好!"; public void paint(Graphics g) {g.drawString(newtext,20,20);} //添加了对鼠标的处理函数 public boolean mouseDown(Event evt,int x,int y) {String temp; Applet hello=getAppletContext().getApplet("app"); temp=((HelloWorld1)hello).text; //将hello定义为HelloWorld1类 ((HelloWorld1)hello).text=newtext; ((HelloWorld1)hello).repaint(); newtext=temp; repaint(); return true; } } 为了避免使用Java Script而引起误会,我们在SetText中增加了对鼠标的处理函数;另外我们在编译SetText时,必须先编译HelloWorld1.java,并把编译后的HelloWorld1.class放在指定的目录例如lib;然后运行javac -classpath lib SetText.java,编译后得到SetText.class。 example3.html <html> <head><title>例子</title></head> <body> Java Script与Java Applet的综合运用例三<br> <applet code="HelloWorld1.class" width="100" height="28" name="app"> </applet><br><br> <applet code="SetText.class" width="100" height="28" > </applet><---请点击这里 <br>如果你的浏览器无法正确显示"世界你好!",请改用Netscape试试。 </body> </html> 用浏览器打开example3.html,会出现两个Applet分别显示"Hello World!"和"世界你好!",点击下方的Applet(SetText.class)你会发现两个Applet中的内容发生了互换(如果你发现"世界你好!"显示不正常,那是你所用浏览器的Java虚拟机对中文支持不够好,我就发现我机子上的IE4.0无法在Applet中显示中文,这是浏览器的bug,我以前还曾发现IE在处理Date时,愣是把时间减少了7个小时,升级到win98之后,才改正此bug)。 <淘宝热门商品:
 

278.00 元  

拍趣-拍你喜欢 享受乐趣

3皇冠 大遥控 灿凌RMBOX368(高清DVD/RMVB硬盘播放器) AOK

 

16.00 元  

减肥极品魔芋胶


来源:程序员网

小小豆叮

Java Script与Java Applet综合运用(一)

首先我们编写一个Java Applet,就叫HelloWorld1好了(大家对HelloWorld一定不会陌生). HelloWorld1.java import java.awt.*; import java.applet.*; public class HelloWorld1 extends Applet { public String text="Hello World!";//请注意此处的public public void paint(Graphics g) {g.drawString(text,20,20);} } 编译通过后会生成HelloWorld1.class(别告诉我程序无法通过!如果编译出错请检查是否拼写有误。) example.html <html> <head><title>例子</title></head> <body> <script language="JavaScript"> <!-- function SetText() { document.app.text="世界你好!"; document.app.repaint();//也请注意此句. } //--> </script> Java Script与Java Applet的综合运用例一<br> <applet code="HelloWorld1.class" width="100" height="28" name="app"> </applet> <form> <input type="button" value="请点击这里" onclick="SetText()"> </form> </body> </html> 用浏览器打开example.html会出现一个显示“Hello World!”的Java Applet以及一个按钮“请点击这里”。我们点一下按钮,你会发现“Hello World!”变成了“世界你好”。这说明Java Script已经成功的改变了HelloWorld1中text的内容。 你也许会问在在HelloWorld1.java中为什么要在text前加public?? 还有Java Script中那行:"document.app.repaint();"是什么意思?? 是这样的: 和C++一样,在Java中缺省状态下,对象的属性是private,要让Java Script访问到Java Applet中的对象,必须设置为public(包括函数、变量和类)。 前一句document.app.text="世界你好!"仅改变了text的值,要使它反映在浏览器上,必须要让HelloWorld1刷新它的显示,因此要调用HelloWorld1中的repaint()函数。你也许又要问了:我在HelloWorld1.java中并没有看到repaint()函数呀? HelloWorld1是Applet的子类,我们调用repaint()其实是调用类Applet中的repaint()函数。当然我们并不推荐在外部直接修改Applet内的变量,更安全的方法是提供public函数来读取和改变内部变量。 待续... <淘宝热门商品:
 

188.00 元  

地球都踩在脚下

T-MAC8麦迪8代 麦8 08-09赛季麦迪篮球鞋 白黑红 阿迪达斯adidas

 

 

【广州商盟】意外金喜服装◎抵制暴利低价有好货◎收藏小店有惊喜


来源:程序员网

小小豆叮

过桥问题编程解决

问题  在漆黑的夜里,四位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,四个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,四人所需要的时间分别是1、2、5、10分钟;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这四人尽快过桥。 JAVA实现功能如下: (jdk1.3,jbuild7测试通过) public class mks { public mks() { int[] i={1,2,5,10}; boolean[] j={true,true,true,true}; int go=1; int time=0; for(;true;) { if(j[0]||j[1]||j[2]||j[3]) { if(go==1) { go=0; if(j[0]==true&&j[1]==true) { System.out.print(i[0]+"过桥\r\n"); System.out.print(i[1]+"过桥\r\n"); time+=i[1]; System.out.print("time="+time+"\r\n"); j[0]=false; j[1]=false; } else { System.out.print(i[2]+"过桥\r\n"); System.out.print(i[3]+"过桥\r\n"); time+=i[3]; System.out.print("time="+time+"\r\n"); j[2]=false; j[3]=false; } } else { go=1; if(j[0]==false) { j[0]=true; System.out.print(i[0]+"回来\r\n"); time+=i[0]; System.out.print("time="+time+"\r\n"); } else { j[1]=true; System.out.print(i[1]+"回来\r\n"); time+=i[1]; System.out.print("time="+time+"\r\n"); } } } else { break; } } } } <淘宝热门商品:
 

 

:◤╭ Shanghai 秀卡蒂╮╰女性健康購物中心 ╯◥◣瘦身╮減肥╮

 

288.00 元 

【19shop 超值正品】英国TOPMAN经典修


来源:程序员网

小小豆叮

用jsp如何读取access数据库

<%@page import="java.sql.*" import ="java.util.*" import ="java.io.*" import="java.text.*" contentType="text/html; charset=gb2312" buffer="20kb" %><%! int all,i,m_count; String odbcQuery; Connection odbcconn; Statement odbcstmt; ResultSet odbcrs; String username,title,content,work,email,url,time,date; String datetime; %> <% try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); }catch (ClassNotFoundException e) { out.print ("驱动程序不存在"); } try{ odbcconn = DriverManager.getConnection("jdbc:odbc:db1"); odbcstmt = odbcconn.createStatement(); odbcQuery="Select * From book where datetime>2001-4-26 Order By datetime DESC"; odbcrs=odbcstmt.executeQuery(odbcQuery); int i=0; while (i<130) odbcrs.next(); while (odbcrs.next()) { //*/////////////////////////显示数据库的内容用于调试程序是用// int ii; try{ try{ for (ii=1;;ii++) out.print ("<br>Cloumn "+ii+" is: "+odbcrs.getString(ii)); }catch (NullPointerException e) { out.print ("有空的指针"); } }catch (SQLException e){ } } odbcrs.close(); odbcstmt.close(); odbcconn.close(); }catch (SQLException e) { out.print (e); } %> <淘宝热门商品:
 

198.00 元 

08秋款欧洲正版G-star双排扣夹克外套 超好

 

¥:38.00 

[郭氏鞋坊旗下]四季兜外贸童鞋店

185黑黄 库存外贸 DISNEY/迪斯尼Tigger&pooh童休闲运动鞋 带闪灯


来源:程序员网

小小豆叮

什么是数据仓库

目前,数据仓库一词尚没有一个统一的定义,著名的数据仓库专家W.H.Inmon在其著作《Building the Data Warehouse》一书中给予如下描述:数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、集成的(Integrate)、相对稳定的(Non-Volatile)、反映历史变化(Time Variant)的数据集合,用于支持管理决策。对于数据仓库的概念我们可以从两个层次予以理解,首先,数据仓库用于支持决策,面向分析型数据处理,它不同于企业现有的操作型数据库;其次,数据仓库是对多个异构的数据源有效集成,集成后按照主题进行了重组,并包含历史数据,而且存放在数据仓库中的数据一般不再修改。 根据数据仓库概念的含义,数据仓库拥有以下四个特点: 1、面向主题。操作型数据库的数据组织面向事务处理任务,各个业务系统之间各自分离,而数据仓库中的数据是按照一定的主题域进行组织。主题是一个抽象的概念,是指用户使用数据仓库进行决策时所关心的重点方面,一个主题通常与多个操作型信息系统相关。 2、集成的。面向事务处理的操作型数据库通常与某些特定的应用相关,数据库之间相互独立,并且往往是异构的。而数据仓库中的数据是在对原有分散的数据库数据抽取、清理的基础上经过系统加工、汇总和整理得到的,必须消除源数据中的不一致性,以保证数据仓库内的信息是关于整个企业的一致的全局信息。 3、相对稳定的。操作型数据库中的数据通常实时更新,数据根据需要及时发生变化。数据仓库的数据主要供企业决策分析之用,所涉及的数据操作主要是数据查询,一旦某个数据进入数据仓库以后,一般情况下将被长期保留,也就是数据仓库中一般有大量的查询操作,但修改和删除操作很少,通常只需要定期的加载、刷新。 4、反映历史变化。操作型数据库主要关心当前某一个时间段内的数据,而数据仓库中的数据通常包含历史信息,系统记录了企业从过去某一时点(如开始应用数据仓库的时点)到目前的各个阶段的信息,通过这些信息,可以对企业的发展历程和未来趋势做出定量分析和预测。 企业数据仓库的建设,是以现有企业业务系统和大量业务数据的积累为基础。数据仓库不是静态的概念,只有把信息及时交给需要这些信息的使用者,供他们做出改善其业务经营的决策,信息才能发挥作用,信息才有意义。而把信息加以整理归纳和重组,并及时提供给相应的管理决策人员,是数据仓库的根本任务。因此,从产业界的角度看,数据仓库建设是一个工程,是一个过程。 整个数据仓库系统是一个包含四个层次的体系结构: ·数据源:是数据仓库系统的基础,是整个系统的数据源泉。通常包括企业内部信息和外部信息。内部信息包括存放于RDBMS中的各种业务处理数据和各类文档数据。外部信息包括各类法律法规、市场信息和竞争对手的信息等等; ·数据的存储与管理:是整个数据仓库系统的核心。数据仓库的真正关键是数据的存储和管理。数据仓库的组织管理方式决定了它有别于传统数据库,同时也决定了其对外部数据的表现形式。要决定采用什么产品和技术来建立数据仓库的核心,则需要从数据仓库的技术特点着手分析。针对现有各业务系统的数据,进行抽取、清理,并有效集成,按照主题进行组织。数据仓库按照数据的覆盖范围可以分为企业级数据仓库和部门级数据仓库(通常称为数据集市)。 ·OLAP服务器:对分析需要的数据进行有效集成,按多维模型予以组织,以便进行多角度、多层次的分析,并发现趋势。其具体实现可以分为:ROLAP、MOLAP和HOLAP。ROLAP基本数据和聚合数据均存放在RDBMS之中;MOLAP基本数据和聚合数据均存放于多维数据库中;HOLAP基本数据存放于RDBMS之中,聚合数据存放于多维数据库中。 ·前端工具:主要包括各种报表工具、查询工具、数据分析工具、数据挖掘工具以及各种基于数据仓库或数据集市的应用开发工具。其中数据分析工具主要针对OLAP服务器,报表工具、数据挖掘工具主要针对数据仓库。 <淘宝热门商品:
 

88.00 元 

双皇冠热卖 日本原装 RAKU系列30倍运动硅胶

 

32.00 元  

卖疯了 牙亮白 7天显著洁白牙齿


来源:程序员网

小小豆叮

以IP与Port建立与SQLSERVER的连接

package jsp; import java.sql.*; // JDBC package public class sql_data { String url = "jdbc:inetdae:192.168.2.70?sql7=true"; // use your hostname and port number String login = "sa"; // use your login here String password =""; // use your password here public Connection connection = null; public Statement st = null; public ResultSet rs = null; public sql_data(){  try {   Class.forName("com.inet.tds.TdsDriver").newInstance();   DriverManager.setLoginTimeout(10);  } catch(Exception e) {  e.printStackTrace(); } } public void sqlclose() {  try {   st.close();   connection.close();  }  catch(SQLException ex) {   System.err.println("sqlclose: " + ex.getMessage());  } } public ResultSet executeQuery(String sql) {  try {   connection = DriverManager.getConnection(url,login,password);   connection.setCatalog( "register");   st = connection.createStatement();   rs = st.executeQuery(sql);  }  catch(SQLException ex) {   System.err.println("aq.executeQuery: " + ex.getMessage());  }  return rs; } } <淘宝热门商品:
 

5.00 元 

超人气面膜 平民价格 顶级效果

 

50.00 元  

韩服CASH之家

韩服 HF 跑跑卡丁车 新劳迪 劳迪Introduction 永久 支持韩文名


来源:程序员网

小小豆叮

使用Policy来设置Java的安全策略

众所周知,Java语言具有完善的安全框架,从编程语言,编译器、解释程序到Java虚拟机,都能确保Java系统不被无效的代码或敌对的编译器暗中破坏,基本上,它们保证了Java代码按预定的规则运作。但是,当我们需要逾越这些限制时,例如,读写文件,监听和读写Socket,退出Java系统等,就必须使用数字签名或安全策略文件(*.Policy)。   在企业内部网中,本文提出了使用安全策略文件来设置java程序权限的一种简单的方法。由于企业内部网中各台计算机的位置、用途和安全性明确,更适于使用安全策略文件来设置java的权限,软件的安装、设置、升级和迁移都非常的方便,并且,还可以和数字签名配合使用,更重要的是,可以细分每个java程序的权限,使用起来灵活方便。 一. Java中安全策略的概念   Java应用程序环境的安全策略,详细说明了对于不同的代码所拥有的不同资源的许可,它由一个Policy对象来表达。为了让applet(或者运行在SecurityManager下的一个应用程序)能够执行受保护的行为,例如读写文件,applet(或Java应用程序)必须获得那项操作的许可,安全策略文件就是用来实现这些许可。   Policy对象可能有多个实体,虽然任何时候只能有一个起作用。当前安装的Policy对象,在程序中可以通过调用getPolicy方法得到,也可以通过调用setPolicy方法改变。Policy对象评估整个策略,返回一个适当的Permissions对象,详细说明那些代码可以访问那些资源。   策略文件可以储存在无格式的ASCII文件,或Policy类的二进制文件,或数据库中。本文仅讨论无格式的ASCII文件的形式。 二. Policy文件的格式   为了能够更好地理解下面的内容,建议在阅读时参照\jdk1.2\jre\lib\security\java.policy文件和\jdk1.2\jre\lib\security\java.security文件的内容。   1. Policy文件的语法格式与说明   一个Policy文件实质上是一个记录列表,它可能含有一个“keystore”记录,以及含有零个或多个“grant”记录。其格式如下: keystore "some_keystore_url", "keystore_type"; grant [SignedBy "signer_names"] [, CodeBase "URL"] { Permission permission_class_name [ "target_name" ] [, "action"] [, SignedBy "signer_names"]; Permission ...};   1.1"keystore"记录   一个keystore是一个私有密钥(private keys)数据库和相应的数字签名,例如X.509证书。Policy文件中可能只有一条keystore记录(也可能不含有该记录),它可以出现在文件中grant记录以外的任何地方。Policy配置文件中指定的keystores用于寻找grant记录中指定的、签名者的公共密钥(public keys),如果任何grant记录指定签名者(signer_names),那么,keystore记录必须出现在policy配置文件中。   "some_keystore_url"是指keystore的URL位置,"keystore_type"是指keystore的类型。第二个选项是可选项,如果没有指定,该类型则假定由安全属性文件(java.security)中的"keystore.type"属性来确定。keystore类型定义了keystore信息的存储和数据格式,用于保护keystore中的私有密钥和keystore完整性的算法。Sun Microsystems支持的缺省类型为“JKS”。   1.2"grant"记录   在Policy文件中的每一个grant记录含有一个CodeSource(一个指定的代码)及其permission(许可)。   Policy文件中的每一条grant记录遵循下面的格式,以保留字“grant”开头,表示一条新的记录的开始,“Permission”是另一个保留字,在记录中用来标记一个新的许可的开始。每一个grant记录授予一个指定的代码(CodeBase)一套许可(Permissions)。   permission_class_name必须是一个合格并存在的类名,例如java.io.FilePermission,不能使用缩写(例如,FilePermission)。   target_name用来指定目标类的位置,action用于指定目标类拥有的权限。   target_name可以直接指定类名(可以是绝对或相对路径),目录名,也可以是下面的通配符: directory/* 目录下的所有文件 *当前目录的所有文件 directory/-目录下的所有文件,包括子目录 - 当前目录下的所有文件,包括子目录 《ALL FILES》文件系统中的所有文件 对于java.io.FilePermission,action可以是: read, write, delete和execute。 对于java.net.SocketPermission,action可以是: listen,accept,connect,read,write。   1.3 Policy文件中的属性扩展(Property Expansion)   属性扩展与shell中使用的变量扩展类似,它的格式为: "${some.property}" 实际使用的例子为: permission java.io.FilePermission "${user.home}", "read"; "${user.home}"的值为"d:\Project", 因此,下面的语句和上面的语句是一样的: permission java.io.FilePermission " d:\Project ", "read"; 三. 实例   当初始化Policy时,首先装载系统Policy,然后再增加用户Policy,如果两者都不存在,则使用缺省的Policy,即原始的沙箱模型。   系统Policy文件的缺省位置为: {java.home}/lib/security/java.policy (Solaris) {java.home}\lib\security\java.policy (Windows) 用户Policy文件的缺省位置为: {user.home}/.java.policy (Solaris) {user.home}\.java.policy (Windows)   其实,在实际使用中,我们可能不会象上面介绍的那么复杂,特别是在不使用数字签名时。这时,我们完全可以借鉴JDK 1.2提供给我们的现成的\jdk1.2\jre\lib\security\java.policy文件,根据我们的需要作相应的修改,本文就针对不使用数字签名情况详细说明安全策略文件的用法。   下面,是一个完整的在Windows 95/98/NT下使用的.java.policy文件。在文件中,分别使用注释的形式说明了每个“permission”记录的用途。 // For LanServerTalk.java and LanClientTalk.java grant { //对系统和用户目录“读”的权限 permission java.util.PropertyPermission "user.dir", "read"; permission java.util.PropertyPermission "user.home", "read"; permission java.util.PropertyPermission "java.home", "read"; permission java.util.PropertyPermission "java.class.path", "read"; permission java.util.PropertyPermission "user.name", "read"; //对线程和线程组的操作权限 permission java.lang.RuntimePermission "modifyThread"; permission java.lang.RuntimePermission "modifyThreadGroup"; //操作Socket端口的各种权限 permission java.net.SocketPermission "-", "listen"; permission java.net.SocketPermission "-", "accept"; permission java.net.SocketPermission "-", "connect"; permission java.net.SocketPermission "-", "read"; permission java.net.SocketPermission "-", "write"; //读写文件的权限 permission java.io.FilePermission "-", "read"; permission java.io.FilePermission "-", "write"; //退出系统的权限,例如System.exit(0) permission java.lang.RuntimePermission "exitVM"; }; 四. java.policy文件的使用   对于windows 95/98/NT,使用.java.policy文件的方法主要有下面两种。   1. 使用缺省目录   我们可以简单地将编辑好的.java.policy文件拷贝到windows 95/98/NT的HOME目录,这时,所有的applet(或Java应用程序)可能都拥有某些相同的权限,使用起来简单,但不灵活(例如:对于java.io.FilePermission ,其目标类的target_name必须使用绝对路径),如果不是在企业内部网中使用,还可能存在一定安全隐患。   2. 在命令行中指定   在命令行,如果我们希望传递一个Policy文件给appletviewer,还可以使用"-J-Djava.security.policy"参数来指定policy的位置: appletviewer -J-Djava.security. policy=pURL myApplet   pURL为Policy文件的位置。下面,是一个实际的例子,以当前目录的.java.policy文件所指定的安全策略运行当前目录的LanServerTalk.html(文件中装载并运行LanServerTalk.java): appletviewer -J-Djava.security.policy =.java.policy LanServerTalk.html   这种方法使用灵活,特别是作为一个软件包在企业内部网中发布时,安装、设置和迁移软件,基本无须修改Policy文件的内容,使用起来相当简单,而且,安全许可的范围控制较精细。 <淘宝热门商品:
 

保健品/滋补品 

淑芳阁_苗条姿_最有效的减肥瘦身与丰胸专卖店

 

58.00 元  

淘宝生活 运动鞋专卖/正品ZIPPO热卖//淘宝职业信誉卖家

冲双钻 ADIDAS三叶草08夏季新款特价 漫画小子个性 休闲板鞋


来源:程序员网

小小豆叮

CMP实体bean实战开发

CMP实体bean实战开发 肖开锋 一个容器管理持续的实体bean允许容器处理一些或者它的全部数据访问逻辑。用容器管理的持续,你需要把实体bean类的一些域公开出来,好让容器在代表bean执行数据库操作时可以设置这些域。 在容器管理持续化的情况下,entity bean类的代码必须满足以下条件。首先,类必须定义为public。此外,这个类还必须实现以下内容: 1.EntityBean接口 2.零个或多个ejbCreate方法及ejbPostCreate方法 3.对应于持续化及关联字段的定义它的get方法及set方法 4.home方法 5.business方法 entity bean类不能实现以下方法: 1、finder方法 2、finalize方法 一个访问方法的命名以get或set开始,后面是首字母大写的持续化及关联字段。例如,对salary字段的访问 方法是getSalary和setSalary。 本示例描述一个简单的CMP 实体bean使用实例,构建一个简单的产品查询应用,实例中包括的3个主要 文件: Product.java-------远程接口文件 ProductHome.java--------本地接口文件 ProductBean.java--------Bean文件 Product.java内容如下 import javax.ejb.*; import java.rmi.RemoteException; /** 定义了企业bean的公开商务方法. 客户端通过远程接口和企业bean交互 */ public interface Product extends EJBObject { // 实体bean域的获得器和设置器方法 public String getName() throws RemoteException; public void setName(String name) throws RemoteException; public String getDescription() throws RemoteException; public void setDescription(String description) throws RemoteException; public double getBasePrice() throws RemoteException; public void setBasePrice(double price) throws RemoteException; public String getProductID() throws RemoteException; } ProductHome.java内容如下 import javax.ejb.*; import java.rmi.RemoteException; import java.util.Enumeration; public interface ProductHome extends EJBHome { /* 这个方法创建EJB对象 请注意本地接口返回一个EJB对象,而Bean却没有返回值。这是因为EJB容器负责生成这个EJB对象,而Bean负责初始化。 @参数productID :产品号 (唯一) @参数name:产品名t @参数description :产品的描述 @参数basePrice Base:产品的基础价格 @返回新创建的EJB对象 */ public Product create(String productID, String name, String description, double basePrice) throws CreateException, RemoteException; public Product findByPrimaryKey(String productID) throws FinderException, RemoteException; //定位器方法,容器负责实现。 } Productbean.java文件内容如下 import java.sql.*; import javax.naming.*; import javax.ejb.*; import java.util.*; import java.rmi.RemoteException; /** 容器管理持续性,一个产品的持续内容包括ID#,name,description和 baseprice */ public class ProductBean implements EntityBean { protected EntityContext ctx; //容器管理的状态域必须定义成public类型 public String productID; // 主键 public String name; public String description; public double basePrice; public ProductBean() { System.out.println("New Product Entity Bean Java Object created by EJB Container."); } public String getName() throws RemoteException { System.out.println("getName() called."); return name; } public void setName(String name) throws RemoteException { System.out.println("getName() called."); this.name = name; } public String getDescription() throws RemoteException { System.out.println("getDescription() called."); return description; } public void setDescription(String description) throws RemoteException { System.out.println("setDescription() called."); this.description = description; } public double getBasePrice() throws RemoteException { System.out.println("getBasePrice() called."); return basePrice; } public void setBasePrice(double price) throws RemoteException { System.out.println("setBasePrice() called."); this.basePrice = price; } public String getProductID() { System.out.println("getProductID() called."); return productID; } // EJB必需的方法 // 由容器调用,执行时可获得需要的资源 public void ejbActivate() throws RemoteException { System.out.println("ejbActivate() called."); } /** * EJB 容器在它从数据库中移除实体bean前调用这个方法。它和客户端调用home.Remove()方法相对应。 */ public void ejbRemove() throws RemoteException { System.out.println("ejbRemove() called."); } public void ejbPassivate() throws RemoteException { System.out.println("ejbPassivate () called."); } public void ejbLoad() throws RemoteException { System.out.println("ejbLoad() called."); } public void ejbStore() throws RemoteException { System.out.println("ejbStore() called."); } public void setEntityContext(EntityContext ctx) throws RemoteException { System.out.println("setEntityContext called"); this.ctx = ctx; } public void unsetEntityContext() throws RemoteException { System.out.println("unsetEntityContext called"); this.ctx = null; } public String ejbCreate(String productID, String name, String description, double basePrice) throws CreateException, RemoteException { System.out.println("ejbCreate(" + productID + ", " + name + ", " + description + ", " + basePrice + ") called"); this.productID = productID; this.name = name; this.description = description; this.basePrice = basePrice; return null; } public void ejbPostCreate(String productID, String name, String description, double basePrice) throws RemoteException { System.out.println("ejbPostCreate() called"); } // 因为是容器管理的持续性,不需要定义finder方法。 } 将以上3个文件编译成class文件得到Product.class ProductBean.class ProductHome.class 部署BEAN文件 准备工作:启动j2ee服务器j2ee -verbose;启动cloudscape数据库服务器cloudscape -start。 1. 打开部署工具deploytool,新建一个applicaton命名为Product,display name 也使用Product 2. 给新建的application添加一个EnterPrise Bean,以下操作取默认值。 3.添加建立的三个 class文件(Product.Class ProductHome.Class 和 ProductBean.Class) 4.下一步选择 bean类型Entity bean 设置Enterprise bean Class ProductBean,Enterprise bean name 为ProductBean,display name 默认。 5.设置remote home interface 为ProductHome,remote interface 为Product 6.下一步操作如下,选取定义的状态域。将Primary key class 修改为java.lang.String。 设置Primary key field name为productID。 7.下面的按next跳过,最后单击finish按钮完成实体Bean 的创建过程. 8.选中创建的ProductBean 在右侧的工作栏中点击Entity设置Deployment Setting. 选中Database Setting ,Database jndi name ---jdbc/cloudscape user name :scott,password :tiger. 9.生成默认得sql语句 10.下面可以部署了点击deploy,设置jndi name。 11.点击finish完成部署 12.使用客户端测试刚部署的CMP实体bean。 客户端Client.java import javax.ejb.*; import javax.naming.*; import java.rmi.*; import java.util.Enumeration; import java.util.Properties; public class Client { public static void main(String[] args) { ProductHome home = null; try { Properties props=System.getProperties(); Context ctx=new InitialContext(props); home = (ProductHome) ctx.lookup("ProductHome"); //创建几个产品EJB对象 home.create("123-456-7891", "P5-400", "400 Mhz Pentium", 300); home.create("123-456-7892", "P5-450", "450 Mhz Pentium", 400); home.create("123-456-7893", "SD-64", "64 MB SDRAM", 50); home.create("123-456-7894", "SD-128", "128 MB SDRAM", 100); home.create("123-456-7895", "SD-256", "256 MB SDRAM", 200); //查找一件产品,打印出产品名 Product pk=home.findByPrimaryKey("123-456-7891"); System.out.println(pk.getName()); } catch (Exception e) { e.printStackTrace(); } } } 13.客户端执行java Client返回结果如下:P5-400 14.注:假设你的JAVA_HOME,J2EE_HOME,classpath和path路径已经正确设置。如果出现问题请检查你的路径是否正确。 本实例在j2dk1.3.1 ,j2sdkee1.3.1和 cloudscape4.06环境下通过。 <淘宝热门商品:
 

120.00 元  

上万淘友使用推荐、修复红血丝、敏感、痘印(全国总代)

 

4.00 元  

5钻【成都商盟】竹纤维内裤袜子毛巾超市~~收藏本店就有礼物送哦

特价 100%竹纤维毛巾 京杭丽人儿童毛巾27*48 50克/随机颜色


来源:程序员网

小小豆叮

面向对象的关系数据库设计

一、概念的区分   有些人把面向对象的数据库设计(即数据库模式)思想与面向对象数据库管理系统(OODBMS) 理论混为一谈。其实前者是数据库用户定义数据库模式的思路,后者是数据库管理程序的思路。用户使用面向对象方法学可以定义任何一种DBMS数据库,即网络型、层次型、关系型、面向对象型均可,甚至文件系统设计也照样可以遵循面向对象的思路。   面向对象的思路或称规范可以用于系统分析、系统设计、程序设计,也可以用于数据结构设计、数据库设计。OOSE自上至下、自始至终地贯彻面向对象思路,是一个一气呵成的统一体。面向对象的数据库设计只是 OOSE 的一个环节。 二、数据库设计的重要性   一般数据库设计方法有两种,即属性主导型和实体主导型。属性主导型从归纳数据库应用的属性出发,在归并属性集合(实体)时维持属性间的函数依赖关系。实体主导型则先从寻找对数据库应用有意义的实体入手,然后通过定义属性来定义实体。一般现实世界的实体数在属性数 1/10 以下时,宜使用实体主导型设计方法。面向对象的数据库设计是从对象模型出发的,属于实体主导型设计。   一般数据库应用系统都遵循以下相关开发步骤:   1设计应用系统结构;   2 选择便于将应用程序与 DBMS 结合的DBMS体系结构,如RDBMS;   3 根据应用程序使用的环境平台,选择适宜的DBMS(如Oracle)和开发工具(如PB);   4 设计数据库,编写定义数据库模式的SQL程序;   5 编写确保数据正确录入数据库的用户接口应用程序;   6 录入数据库数据;7 运行各种与数据库相关的应用程序,以确认和修正数据库的内容。   对以上各步骤,有几点需要说明:   (1) 这不是瀑布模型,每一步都可以有反馈。以上各步不仅有反馈、有反复,还有并行处理。比如一些库表在数据录入时,另一些库表设计还在修改。这与我们的递增式开发方法有关,也与面向对象的特征有关。   (2) 上述顺序不是绝对的,大多数场合是从第三步开始的。   (3) 对大多数数据库应用系统来说,上述各步中最重要、最困难的不是应用系统设计而是数据库设计。 三、DBMS的支持和数据库设计   很多数据库应用系统开发者不重视数据库设计的原因是:他们太迷信DBMS,认为购入一个功能强大的 DBMS后数据库设计就不困难、不重要了。一些国内外的数据库教材常常是在为DBMS的开发厂商做宣传,而很少站在数据库用户角度,从数据库应用系统出发介绍数据库设计方法。结果往往使读者搞不清书中介绍的是数据库管理程序的设计思想,还是应用这种 DBMS 进行数据库设计的思想。   其实,DBMS只是给用户为已采用的数据库提供一个舞台,而是否使用这个舞台上的道具以及唱什么戏,则完全取决于用户的戏剧脚本和导演(开发者)的安排。例如,公路局系统所使用的数据库管理系统,是以二维表为基本管理单元、支持所有关系代数操作、支持实体完整性与实体间参照完整性的全关系型 RDBMS,而我们要在这个舞台上利用上述"道具"设计一个面向对象的关系数据库。 四、应用对象模型与RDBMS模型的映射   数据库设计(模式)是否支持应用系统的对象模型,这是判断是否是面向对象数据库系统的基本出发点。由于应用系统设计在前,数据库设计随后,所以应用系统对象模型向数据库模式的映射是面向对象数据库设计的关键。 1. 3层数据库模式面向对象模型的扩展   一般数据库设计多参照ANSL/SPARC关于数据库模式的3层标准结构提案。最接近物理数据库的内部模式由 DBMS 提供的SQL来描述。概念模式可以由若干个内部模式聚集而成,它是由数据库用户规范的一些表的集合。一般的概念模式是数据库物理模式作用域的边界,它能实现数据库的物理意义、特定DBMS 的特殊操作对外部应用程序的信息隐蔽。外部模式是从特定用户应用角度看待的数据库模式,从不同的应用出发对同一概念模式可以给出多种不同的外部模式。当外部应用系统以对象模型进行抽象时,从各个应用出发抽象出的对象模型可以映射到外部模型上,对此我们不妨称之为外部对象模型。但是,外部模型只是概念模型的子集,所以面向对象的数据库设计核心在于系统对象模型(不妨称之为概念对象模型) 向数据库概念模型的映射 。 2. 对象模型向数据库表的映射规则   由于 RDBMS 是以二维表为基本管理单元的,所以对象模型最终是由二维表及表间关系来描述的。换言之,对象模型向数据库概念模型的映射就是向数据库表的变换过程。有关的变换规则简单归纳如下:   (1) 一个对象类可以映射为一个以上的库表,当类间有一对多的关系时,一个表也可以对应多个类。   (2) 关系(一对一、一对多、多对多以及三项关系)的映射可能有多种情况,但一般映射为一个表,也可以在对象类表间定义相应的外键。对于条件关系的映射,一个表至少应有3个属性。   (3) 单一继承的泛化关系可以对超类、子类分别映射表,也可以不定义父类表而让子类表拥有父类属性;反之,也可以不定义子类表而让父类表拥有全部子类属性。   (4) 对多重继承的超类和子类分别映射表,对多次多重继承的泛化关系也映射一个表。   (5) 对映射后的库表进行冗余控制调整,使其达到合理的关系范式。 3. 数据库模式要面向应用系统   我们选择面向对象的系统设计也好,面向对象的数据库设计也好,根本目的是服务于应用系统的需要。 五、面向对象关系数据库设计效果   从某种意义上讲,是数据库设计的面向对象特征最终奠定了整个系统的面向对象性,才使面向对象方法在程序开发阶段全面开花。其效果归纳如下: 1. 数据库结构清晰,便于实现 OOP   由于实现了应用模块对象对数据库对象的完全映射,数据库逻辑模型可以自然且直接地模拟现实世界的实体关系。用户所处的当前物理世界、系统开发者所抽象的系统外部功能,与支持系统功能的内部数据库 (数据结构)一一对应,所以用户、开发者和数据库维护人员可以用一致的语言进行沟通。特别是对多数不了解业务的程序开发人员来说,这种将应用对象与相应的数据对象封装在对象统一体中的设计方法,大大减轻了程序实现的难度,使他们只要知道加工的数据及所需的操作即可,而且应用程序大多雷同,可以多处继承由设计人员抽象出来的、预先开发好的各种物理级超类。 2. 数据库对象具有独立性,便于维护   除了数据库表对象与应用模块对象一一对应外,在逻辑对象模型中我们没有设计多重继承的泛化关系,所以这样得到的数据库结构基本上是由父表类和子表类构成的树型层次结构,表类间很少有继承以外的复杂关系,是一个符合局部化原则的结构,从而使数据库表数据破坏的影响控制在局部范围且便于修复,给系统开通后的数据库日常维护工作带来便利。 3. 需求变更时程序与数据库重用率高,修改少   在映射应用对象时,除关系映射规范化后可能出现一对多的表映射外,大多数应用对象与表对象是一一对应的。我们可以把规范化处理后的、由一个应用对象映射出来的多个表看成一个数据库对象。因此当部分应用需求变更时,首先,系统修改可以不涉及需求不变更的部分。其次,变更部分的修改可以基本上只限于追加或删除程序模块或追加新库表,而基本上不必修改原有程序代码或原有库表定义,从而大大减少了工作量,降低了工作难度。 六、最简单的就是最好的   客观世界是错综复杂的,计算机科学理论的发展也越来越高深、复杂。然而,人类探索理论和技术的最终目的是:让客观世界的复杂变简单,最简单的就是最好的。为此给出以下几点忠告: 1. 慎用外键   RDBMS 支持复杂关系的能力很强,无论用户怎么在逻辑上设定外键,它基本上都能从物理上帮用户实现。但是外键把许多独立的实体牵连在一起,不仅使 RDBMS 维持数据一致性负担沉重,也使数据库应用复杂化,加重了程序开发负担。这样的数据库很难理解,很难实现信息隐蔽性设计,往往把简单问题复杂化。 2. 适当冗余   减少数据库冗余的设计思路产生于70年代,它是促使 DBMS 进步的重要动力之一。然而,犹如为了节省2个字节的存储空间而酿成了如今全球为之头痛的2000年问题一样,它是计算机硬件主导时代的产物。以今天国内计算机市场价格为例,6G服务器硬盘的价格不过2000元,而上海物价局 1996 年颁发的一个人月软件开发的指导价约8000元,即一个人月的软件价格就可以购买20G左右的硬盘。即使有5万行数据的库表,每个记录压缩40字符的冗余,单纯计算合计也不足2M,即节省0.6元钱的磁盘空间。   今天的世界已进入软件主导的计算机时代。因此,最容易理解、应用开发工作量最少、维护最简单的数据库结构才是最好的。只要数据完整性、一致性不受威胁,有些冗余,不足为虑。换言之,最节省软件成本 (而不是硬件成本) 的是最好的。 3. 信息隐蔽   这是软件工程最重要的基本原则之一。简言之即信息的作用域越小越好,数据库的透明度越大越好,因为应用程序需要知道得越多就越复杂。使数据库黑盒化 (透明度高) 的方法很多,除了设计上的局部化处理外,还可以利用 DBMS 的触发器、存储过程、函数等,把数据库中无法简化的复杂表关系封装到黑盒子里,隐藏起来,特别是放到服务器端,其优越性更是多方面的。         <淘宝热门商品:
 

132.00 元 

假一罚十 专柜正品 进口牛皮单肩包

 

 

大芬村油画网上订购【画师联盟】纯手绘油画无框画装饰画四钻信誉


来源:程序员网

小小豆叮

说文解字:解读Java中的“垃圾方言”

中国人学电脑,多数情况下是通过看中文版的资料书来学习的。但是有过学电脑,特别是学习程序设计语言经历的读者(包括本人)都会有这样的体会:中文电脑书拿起来易如反掌,读起来却抓耳挠腮。原因之一就是书中有许多莫名其妙的中文专业术语。当然,它们都是从英文翻译过来的,只是翻译得太晦涩。 在我的记忆里,第一个让我念念不忘且深恶痛绝的中文专业术语是:“良基”。现在可能很少有人知道这个词。那是在我上大学时,在一门和人工智能有关的课程中,老师讲解“良基关系”。所谓“良基关系”就是满足几个条件的关系。我明白这几个条件的意思,当然算学会了“良基关系”,只是不明白为什么叫“良基”不叫“烧鸡”?“良基关系”好象很重要,因为老师“良基”了一个学期。许多年过去了,我现在还记得它。学期末的时候,要交一篇论文。我去查了英文资料,才知道满足那几个条件的关系是Well-Founded(基础良好),意思是设计良好、没有矛盾的关系。 我想我的同学应该和我一样,初见“良基”,一定会感到莫名其妙,相信本文的读者也有同感。因为它不是一个正常的中文名词,中文字典里找不到(可能是有人捏造出来的)。 Java是纯粹面向对象的程序设计语言,类似的语言还有C++等。如果你已经学过面向对象技术,还记得第一次看到“对象”一词的感觉吗?如果你没有学过,那么能看懂下面关于对象的解释吗? “世界上是由对象组成的。例如人是对象、电脑是对象、猪是对象、泥巴也是对象......”。 上面是大意,是我第一次学习面向对象技术时,一本中文书上的说法。我不明白,所以整个一本书都没有看懂。直到我知道对象翻译自英文的Object(物体),才慢慢学会面向对象技术。上面的说法实际上的意思是: “世界上是由物体组成的。例如人是物体、电脑是物体、猪是物体、泥巴是物体......”。 中文“专业”垃圾术语有几个特征。其一如“良基”,它是一个字典里和生活中闻所未闻的汉字组合:每个汉字都认识,但是拼在一起就不懂。其二如“对象”,它偏离了英文原意而导致误解,完全是张冠李戴。但是这些中文莫名其妙的术语对应的英文却都是简单的、生活化的英文单词,并非很晦涩。实际上,以我阅读英文资料的体会看,我并不认为有多少“专业”的英文计算机术语。相反,不知道译者出于何种原因,简单的英文单词翻译成中文后,就常常变得扑朔迷离、高深莫测,所以就成了中文“专业”术语。 下面主要以Java语言为例,列出一些中文计算机“术语”和它们对应的英文。 面向对象与Object-Oriented Object-Oriented的意思是“对象为主的、对象主导的”,而“面向”的同义词是“面对”,丝毫没有主导的含义。此中文术语与“对象”的垃圾特征相同。 本人在业余时间去讲课,我的一个学员在课上嘲笑“对象”,指出“面向对象”也非善类。我从来没有想到质疑“面向对象”,所以突然意识到,很多垃圾已经不知不觉成了我们学识的一部分了。 在此,我把“面向对象”列为本文的头条,以示对这位学员的感谢。 重载/重置与Overload/Override 在我上课讲Overload/Override前,我总是先问这两个单词的中文术语是什么,应该怎么念,结果答案还不止一个。有的说“重载= Overload”,有的说“重载=Override”。一般都把“重载”和“重置”的“重”念成“重新”的“重”。 Overload的原意是“超载”,指几个方法的名字相同,但是方法的参数不同。本人理解其意思可能就是一个名字承担了太多的功能,就像一个人要打几份工伺候几个老板一样,活太多,有些超载了。所以,Overload应该对应“重载”,而“重载”的“重”是“沉重”而不是“重新”的意思。有些书把Overload翻译为“过载”,值得赞扬。 Override的含义和Overwrite相同,其原意是“越过”、“跳过”,即是某事情无效。它在Java中,表示子类的方法覆盖了父类的同名方法。因此我猜测Override对应“重置”,也许是“重新安置”的缩写?所以,“重置”的“重”应该是“重新”的“重”,不是“沉重”的“重”,不要与“重载”混淆了。“重置”和“良基”的垃圾特征相同,“重载”还勉强算个正常名词。唉!每次我讲课,都要嚼半天舌头来解释这两个中文“专业”术语。 函数与Function 函数并非计算机专门术语。在中学时,数学课本上就有了函数一词。坦率地说,直到上大学,才知道“函数=Function(功能)”,不过目前仍然不明白为什么叫“函数”,是音译还是意译?所以虽然我知道它是垃圾,却不知道是哪一类,是“良基”的还是“对象”的,或者是某个垃圾新类型?如果说数学中的“函数”还和“数”多少有点关系的话,它可是和程序设计语言中的Function没有什么字面的关联。也许该把Function翻译为“函码”? 在Java中,可喜的是已经用method(方法)取代Function一词了,所以不必为解释“函数”再费口舌了。 显式/隐式与Explict/Implicit 一看“显式/隐式”,就知道它们和“良基”同类,也是翻遍大字典,都找不到的中文计算机术语。“显式”译自explict,意思是明显地、明白的,例如语句int x= 4的结果是x被赋值4,可以很“明显”地能够看出x被赋初值。而x如果是类的成员,那么int x的结果是x被赋初值0。这种赋初值不太容易看出来,称为“隐式”赋值。隐式译自英文implicit,意思是隐含的、默认的。 线程与Thread “线程”译自英文的Thread,如果查字典就知道它指“线”,比如缝衣服用的线。衣服上有纵横交错的很多线,好象程序的流程图一样,所以,Thread在英文中比喻程序执行的线路。例如,判断语句如果真,就走流程图的这条“线”,如果为假,那么就走另外一条“线”。因此Multi-Threads指得就是程序在运行时,有几条“线”上的代码同时在运行。而非多线程的程序在流程图上只能有一条线上的代码在运行:一段代码没有执行完,绝对不许执行另外的代码。顺便补充一句,以上的“说文解字”是作者自己的猜测(因此也是原创)。猜测得对不对不知道,但是比喻却与Thread在程序设计中的含义完全吻合。可见,“线程”的垃圾特征与“良基”相同。 数据报文与Datagram UDP (User Datagram Protocol) 发送的数据称为Datagram。gram是表示重量的“克”,克在实际生活中是很小的重量单位,所以Datagram表示UDP发送接收数据的基本单位。每个Datagram独立发送,彼此没有关联,因此速度快,但是不可靠,所谓“欲速而不达”。 Datagram好象被某些书翻译成“数据报文”,猛一看还以为和拍电报有什么瓜葛呢,这就是作者第一次看到这个中文“术语”时的感觉。 套接字与Socket 网络中的一个著名中文术语是“套接字”,这是个什么“字”?恐怕连第一个造这个“字”的人都不知道。 这个“字”译自英文的Socket,其原意是插座、插孔的意思。当两台电脑通过网络、电缆或者电话线等建立连接,可以互相通讯后,可以想象连接线是插在每个电脑的Socket中,尽管实际上电脑上并没有这样的物理部件。Socket是一种形象的比喻,可看作是实现电脑之间通讯的程序或者方法,和任何“字”都没有关系。 令牌与Token Token的原意是“标记、记号、标志”。Token在Java的StreamTokenize中大体指流中有意义的内容,例如一个字母、一个数字都是一个Token,但是空格、回车则不是Token。 Token常常被翻译成“令牌”,例如所谓的“令牌网”。这听起来像古代打仗时下达作战命令的“令牌”,此中文与Token的原意有几成相似? 文件/正文/文档/归档与File/Text/Document/Archive 无论中文还是英文,这些术语都是很容易混淆的。 依我的理解,File是“文件”,泛指计算机中存储的信息或者数据。 Text指文件的内容,通常是可以理解的字符,常常翻译为“正文”,但是我不知道“偏文”或者“非正文”是什么。例如本文的内容就是Text。而Text文件属于文件的一种,指其内容大体是可见的字符,没有格式化的信息。 Document大概被翻译为“文档”,它应该算File的一种,常用来说明什么,例如说明书就是Document。这个词在HTML有关的内容中出现的比较多,例如“HTML文档”、“XML文档”等。 Archive的原意是“档案”,含义是有关某个主题、项目的一系列文件,例如中国每个人都有一份人事档案,这一份档案中有不止一份File或者Document。Java中有jar程序,用于压缩文件(一个或者多个),我想它应该是Java Archieve的缩写。我看到有的书把Archieve翻译为“归档”,可是“归档”听起来像动词,例如,“我有一份归档”是什么意思? 在写到这里时,正好听到电视里的一个药厂广告,广告词坚定而庄重:关注生命,健康人类。瞧,它把“健康”当动词用了,跟“归档”可谓半斤八两。 应用/实现与Appliaction/Implementation 这两个词的翻译比前面的“归档”稍好,但是仍然搞错了词性。“应用”和“实现”在正常的汉语中是动词,可是在电脑书中常常当名词。例如“本协议有了不少实现和应用”,是很多电脑书(特别是翻译书)的说法,听起来不太像中国话。正常的语句应该是“本协议有了不少实现方法和实际应用的例子”。 总线与Bus 刚学计算机时就听说电脑有“总线”技术,但是老师和课本一直避而不谈“支线”在哪,直到看到Bus一词,才明白“支线”技术还没被发明出来。 反省、内省与Introspector Introspector的原意是“向内看、观察和分析内部”,在Java中,它指分析一个类例如JavaBean的内部情况,了解其中有哪些属性、方法和事件。我看到的译文有“反省”和“内省”,听起来像干了坏事做检讨一样。 定制与Customization “定制”是个著名的中文计算机术语,几乎出现在每本电脑书中。“定制”译自Customization,而与该英文词相关的单词为Customer(顾客、用户)。定制某个东西就是按照用户的要求进行设计,而不是采用一般的或者标准的方法,其实就是“定做”的意思。例如您在裁缝店定做一套西装就是Customization。因为这套衣服是按照您的身材和喜好设计制作的,而到商场买一套就不是Customization。 也许我文化水平有限,当第一次看到中文“定制”时,不知道它的意思就是“定做”。但是我现在还是认为,“定做”比“定制”更通俗、更容易理解。也许这就是为什么大家非要“定制”不要“定做”的原因:不把名词故意弄得莫名其妙,怎么体现出IT技术的高深呢? 子句与Clause SQL语句中的Where、From部分被称为“子句”,它的英文为Clause。英文语法书称Clause为“从句”,例如以If开始的“条件从句”等,表示从句是组成完整语句的一部分。应该说,“子句”这个中文术语翻译得不错,可是中学学英语时就知道了“从句”,为什么到了电脑领域,非要改个名字叫“子句”? 公开/私有密钥与Public/Private Key 记得在大学学密码学时,就知道了“公开密钥”一词,当时感觉字面上似乎很矛盾,既已“公开”、“密”又在哪里?而“私有密钥”似乎有点罗嗦,既然是“密”,当然就“私有”了。 几乎所有密码学的著作都把Key翻译成“密钥”,但是Key没有“密”的含义,是“密钥”的始作俑者强行加了“密”,可能是为了显示密码学的深奥吧。 会话与Session 术语Session的英文原意是“聚会”或者“开会”。如果某个浏览器在一段时间中持续访问服务器,那么这种情况被称为Session,就好像浏览器和服务器在聚会一样。大致可认为,只要浏览器不关闭,那么就一直是同一个Session,就像不散会,总是在开同一个会一样。关闭浏览器相当于散会,再次启动浏览器相当于开始一次新的会议。 一些中文书将Session翻译成“会话”或者“对话”,例如所谓的“会话Bean”(Session Bean),是否以为开会就是讲话? 表单与Form 中文“表单”译自英文的Form。从字面上看,中文的“表单”好象既指Form,还指Table,其实Form的样子和Table根本不同。后者是“表”,就像数据库的Table一样,是田字型的表格,而Form是调查表、申请表之类的东西,远远没有Table那样规则。 流与Stream 记得在大学时就知道了“流”是关于I/O的,只是不明白为什么是一个字的“流”,老感到“流”是不是比I/O更高级? 流译自Stream,原意是水流。输入和输出实际上是数据的运动。数据从一个地方运动到另外一个地方就像水的流动一样,也许这就是流Stream这个术语名字的来源吧。 应该说“流”是很好的译文,只是我的大学老师没有给我讲“流=Stream”,或者是我上课走了神没听到,反正本人很久以后才明白,多少时光已经无情地“流”逝了。 计算机中如“对象、套接字”之类的中文“垃圾方言”不少。由于本人对中文电脑书通常是“惧而远之”,所以了解的中文垃圾方言较少,受害较浅。我想垃圾术语一定不止本文列出的这十几个。如果哪位读者是“重伤员”,不得不常常与很多垃圾术语搏斗,不妨就为本文写个续吧。 <淘宝热门商品:
 

1.50元  

星钻喜铺◣皇冠信誉◢{100%满意婚庆一站式店铺}特色婚庆用品大全

 

¥:21.0 

【华佗天然居】天然花草茶花茶中草药中药材

花草茶之瘦腿茶:迷迭香+柠檬草+马鞭草30包21元包快递美容减肥茶


来源:程序员网

小小豆叮

如何实现自定义的ClassLoader

ClassLoader,顾名思义是用来Load Class的,即加载Java类。ClassLoader读入一个字节数组,并且经过处理返回一个JVM内部可以识别的Class实例。Java虚拟机使用一套复杂但有效的方式来进行这一个至关重要的过程处理,并且提供了许多灵活的方式供人们扩展这套机制。 为什么要使用自定义ClassLoader 很多时候人们会选择使用自定义的ClassLoader,而不使用系统的ClassLoader。这样做的原因是,在编译时无法预知运行时会需要哪些Class,特别是在一些AppServer中,比如Tomcat、Avalon-Phonix、Jboss;或是程序提供某种插件(Plug-In)的特性,让用户可以在只拥有程序二进制代码的情况下添加自己的功能,比如Ant、 Jxta-shell等。 ClassLoader内部结构 通常定制一个ClassLoader很简单,一般只需要很少的几个步骤就可以完成。 Java规范规定,所有的用户自定义ClassLoader都必须从抽象类“java.lang.ClassLoader”类继承而来。下面先看一下这个类的内部实现,以帮助我们更好的理解相关内容。 1: protected synchronized Class loadClass(String name, boolean 2: resolve)throws ClassNotFoundException{ 3: // 首先, 检查这个类是否已经加载。 4: Class c = findLoadedClass(name); 5: if (c == null) { 6: try { 7: if (parent != null) { 8: c = parent.loadClass(name, false); 9: }else{ 10: c = findBootstrapClass0(name); 11: } 12: }catch(ClassNotFoundException e){ 13: // 如果仍然没有找到,那么就调用findclass查找这个类. 14: c = findClass(name); 15: } 16: } 17: if (resolve) { 18: resolveClass(c); 19: } 20: return c; } 通常我们使用ClassLoader.loadClass(String name):Class根据指定的类名得到一个相应的Class实例。从Java源代码中我们可以看到,缺省的ClassLoader做了如下的工作: 1. 调用FindLoadedClass(String):Class 检查一下这个Class是否已经被加载过了。由于JVM 规范规定ClassLoader可以在缓存保留它所加载的Class,因此如果一个Class已经被加载过,直接从缓存中获取即可。 2. 调用它的父类的LoadClass()方法,如果它的父类不为空,则使用JVM内部的ClassLoader(即著名的BootstrapClassloader)来加载这个Class。在第10行我们可以看到使用了一个Native方法来调用这个Bootstrap classloader。 3. 如果上面两步都没有找到,调用FindClass(String):Class方法来查找并加载这个Class。 因此我们只要覆盖这个FindClass(String):Class方法即可达到定义ClassLoader的要求。 1: public class AnotherClassLoader extends ClassLoader { 2: private String baseDir; private static final Logger LOG = 3: Logger.getLogger(AnotherClassLoader.class); 4: public AnotherClassLoader (ClassLoader parent, 5: String baseDir) { 6: super(parent); 7: this.baseDir = baseDir; 8: } 9: protected Class findClass(String name) 10: throws ClassNotFoundException { 11: LOG.debug("findClass " + name); 12: byte[] bytes = loadClassBytes(name); 13: Class theClass = defineClass(name, bytes, 0, 14: bytes.length); 15: if (theClass == null) 16: throw new ClassFormatError(); 17: return theClass; 18: } 19: private byte[] loadClassBytes(String className) throws 20: ClassNotFoundException { 21: try { 22: String classFile = getClassFile(className); 23: FileInputStream fis = new FileInputStream(classFile); 24: FileChannel fileC = fis.getChannel(); 25: ByteArrayOutputStream baos = new 26: ByteArrayOutputStream(); 27: WritableByteChannel outC = Channels.newChannel(baos); 28: ByteBuffer buffer = ByteBuffer.allocate Direct(1024); 29: while (true) { 30: int i = fileC.read(buffer); 31: if (i == 0 || i == -1) { 32: break; 33: } 34: buffer.flip(); 35: outC.write(buffer); 36: buffer.clear(); 37: } 38: fis.close(); 39: return baos.toByteArray(); 40: } catch (IOException fnfe) { 41: throw new ClassNotFoundException(className); 42: } 43: } 44: private String getClassFile(String name){ 45: StringBuffer sb = new StringBuffer(baseDir); 46: name = name.replace('.', File.separator Char) + ".class"; 47: sb.append(File.separator + name); 48: return sb.toString(); 49: } 50: } 以上是很简单的代码,关键的地方就在13行处。我们调用了DefineClass方法,目的在于把从文件中得到的二进制数组转换为相应的Class实例。DefineClass是一个Native的方法,它替我们识别Class文件格式,分析、读取相应的数据结构,并生成一个Class实例。 我们只找到了发布在某个目录下的Class,但是,如何获取相应的资源呢?我们有时会用Class.getResource()来获取相应的资源文件。如果仅仅使用上面的ClassLoader是找不到这个资源的,相应的返回值为Null。 同样我们看一下原来的Class类内部的结构。 1: public java.net.URL getResource(String name) { 2: name = resolveName(name); 3: ClassLoader cl = getClassLoader0(); 4: if (cl==null) { 5: return ClassLoader.getSystemResource(name); 6: } 7: return cl.getResource(name); 8: } 原来系统是使用加载这个Class的ClassLoader获取资源的。那么我们再看一下ClassLoader.getResource(String)方法的实现: 1: public URL getResource(String name) { 2: URL url; 3: if (parent != null){ 4: url = parent.getResource(name); 5: }else { 6: url = getBootstrapResource(name); 7: } 8: if (url == null) { 9: url = findResource(name); 10: } 11: return url; 12: } 同样在第9行处,JVM最后会调用一个FindResource方法获取资源的URL。因此同FindClass方法一样只要继承FindResource(String)方法就可以了。 在AnotherClassLoader中添加如下代码: 1: protected URL findResource(String name) { 2: LOG.debug("findResource " + name); 3: try { 4: URL url = super.findResource(name); 5: if (url != null) 6: return url; 7: url = new URL("file:///" + converName(name)); 8: //简化处理,所有资源从文件系统中获取 9: return url; 10: } catch (MalformedURLException mue) { 11: LOG.error("findResource", mue); 12: return null; 13: } 14:} 15:private String converName(String name) { 16: StringBuffer sb = new StringBuffer(baseDir); 17: name = name.replace('.', File.separatorChar); 18: sb.append(File.separator + name); 19: return sb.toString(); 20:} 好了,到这里一个简单的、自定义的ClassLoader就做好了,同样你可以添加其它的调料(比如安全检查,修改class文件等),以满足你自己的口味。 ClassLoader的补充说明 1. 在Java规范中定义了两种ClassLoader,一种成为BootstrapClassLoader,另一种成为UserDefined ClassLoader。BootstrapClassLoader是属于JVM的一部分,用户不可更改,它主要负责加载JavaAPI中的Class。UserDefinedClassLoader是用户可以接触的,包括一个用来加载CLASS_PATH定义中Class的SystemClassLoader和用户自定义的ClassLoader。 2. 这段代码使用了Java1.4中的java.nio包下面的方法。 3.每个Class可以通过Class.getClassLoader():ClassLoader方法获得加载它的ClassLoader。但是对于某些JVM(包括SUN的实现)实现而言,JavaAPI中的那些Class的getClassLoader()方法返回Null(可以参阅JavaDoc)。 <淘宝热门商品:
 

198元 

深深魅惑-*减肥*美容*收藏有惊喜:-)购物惊喜不断……

 

 

【北京商盟】风の轩杂货铺 小美贵族瘦身


来源:程序员网

小小豆叮

Oracle安装后出现的问题?

在Oracle装完后,重新启动入服务器的时候会出现:“share memory realm does not exist”这样的警告的“错误”,解决的办法是: 在启动Oracle数据库的服务,以Oracle用户登陆步骤如下: (一数据库管理员身份启动Server Manager) $svrmgrl 回车 svrmgrl>connect internal(等价于SYS连接,internael连接只能连接到专用数据库,不能连接到共享数据库) 显示信息:connected。然后就要启动实例了。 启动实例方式: (1)不装配数据库,通常是建立数据是使用: svrmgrl>startup nomount (2)装配数据库但不打开,通常在执行特定维护时使用,如:修改数据文件的名称、增加、删除、重命名日志文件;使日志存档选项有用或无用;执行全数据库恢复: svrmgrl>startup mount (3)装配并打开数据库:(必须有CREATE SESSION权限) svrmgrl>startup open %databasename% (4)装配并打开数据库,同时具有CREATE SESSION和RESTRICTED SESSION系统权限的用户: svrmgrl>startup open %datadasename% restrict (5)强制启动: svrmgrl>startup %databasename% force (6)装配数据库,并执行完全介质恢复: svrmgrl>startup mount recover 一般的情况下可以输入: svrmgrl>startup 启动数据库服务后,可以退出svrmgrl控制台: svrmgrl>quit 回车 <淘宝热门商品:
 

 

义乌三冠店→大量贩の热销女性用品(零售+批发)

 

¥:6.98 

四皇冠 值得您收藏的包店 冲五冠 5i贝贝外贸包店◢

◣四冠◆贝妈家◢出口英国★荔枝纹钉扣简约短款钱包◆特价6.99


来源:程序员网

小小豆叮

设计模式之Bridge

Bridge定义 : 将抽象和行为划分开来,各自独立,但能动态的结合. 为什么使用? 通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以下两种: 1. 这多个具体实现之间恰好是并列的,如前面举例,打桩,有两个concrete class:方形桩和圆形桩;这两个形状上的桩是并列的,没有概念上的重复,那么我们只要使用继承就可以了. 2.实际应用上,常常有可能在这多个concrete class之间有概念上重叠.那么需要我们把抽象共同部分和行为共同部分各自独立开来,原来是准备放在一个接口里,现在需要设计两个接口,分别放置抽象和行为. 例如,一杯咖啡为例,有中杯和大杯之分,同时还有加奶 不加奶之分. 如果用单纯的继承,这四个具体实现(中杯 大杯 加奶 不加奶)之间有概念重叠,因为有中杯加奶,也有中杯不加奶, 如果再在中杯这一层再实现两个继承,很显然混乱,扩展性极差.那我们使用Bridge模式来实现它. 如何实现? 以上面提到的咖啡 为例. 我们原来打算只设计一个接口(抽象类),使用Bridge模式后,我们需要将抽象和行为分开,加奶和不加奶属于行为,我们将它们抽象成一个专门的行为接口. 先看看抽象部分的接口代码: public abstract class Coffee {   CoffeeImp coffeeImp;   public void setCoffeeImp() {     this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();   }   public CoffeeImp getCoffeeImp() {return this.CoffeeImp;}   public abstract void pourCoffee(); } 其中CoffeeImp 是加不加奶的行为接口,看其代码如下: public abstract class CoffeeImp {   public abstract void pourCoffeeImp(); } 现在我们有了两个抽象类,下面我们分别对其进行继承,实现concrete class: //中杯 public class MediumCoffee extends Coffee {   public MediumCoffee() {setCoffeeImp();}   public void pourCoffee()   {     CoffeeImp coffeeImp = this.getCoffeeImp();     //我们以重复次数来说明是冲中杯还是大杯 ,重复2次是中杯     for (int i = 0; i < 2; i++)     {       coffeeImp.pourCoffeeImp();     }      } } //大杯 public class SuperSizeCoffee extends Coffee {   public SuperSizeCoffee() {setCoffeeImp();}   public void pourCoffee()   {     CoffeeImp coffeeImp = this.getCoffeeImp();     //我们以重复次数来说明是冲中杯还是大杯 ,重复5次是大杯     for (int i = 0; i < 5; i++)     {       coffeeImp.pourCoffeeImp();     }      } } 上面分别是中杯和大杯的具体实现.下面再对行为CoffeeImp进行继承: //加奶 public class MilkCoffeeImp extends CoffeeImp {   MilkCoffeeImp() {}   public void pourCoffeeImp()   {     System.out.println("加了美味的牛奶");   } } //不加奶 public class FragrantCoffeeImp extends CoffeeImp {   FragrantCoffeeImp() {}   public void pourCoffeeImp()   {     System.out.println("什么也没加,清香");   } } Bridge模式的基本框架我们已经搭好了,别忘记定义中还有一句:动态结合,我们现在可以喝到至少四种咖啡: 1.中杯加奶 2.中杯不加奶 3.大杯加奶 4.大杯不加奶 看看是如何动态结合的,在使用之前,我们做个准备工作,设计一个单态类(Singleton)用来hold当前的CoffeeImp: public class CoffeeImpSingleton {   private static CoffeeImp coffeeImp;   public CoffeeImpSingleton(CoffeeImp coffeeImpIn)    {this.coffeeImp = coffeeImpIn;}   public static CoffeeImp getTheCoffeeImp()   {     return coffeeImp;   } } 看看中杯加奶 和大杯加奶 是怎么出来的: //拿出牛奶 CoffeeImpSingleton coffeeImpSingleton = new CoffeeImpSingleton(new MilkCoffeeImp()); //中杯加奶 MediumCoffee mediumCoffee = new MediumCoffee(); mediumCoffee.pourCoffee(); //大杯加奶 SuperSizeCoffee superSizeCoffee = new SuperSizeCoffee(); superSizeCoffee.pourCoffee(); 注意: Bridge模式的执行类如CoffeeImp和Coffee是一对一的关系, 正确创建CoffeeImp是该模式的关键, Bridge模式在EJB中的应用 EJB中有一个Data Access Object (DAO)模式,这是将商业逻辑和具体数据资源分开的,因为不同的数据库有不同的数据库操作.将操作不同数据库的行为独立抽象成一个行为接口DAO.如下: 1.Business Object (类似Coffee) 实现一些抽象的商业操作:如寻找一个用户下所有的订单 涉及数据库操作都使用DAOImplementor. 2.Data Access Object (类似CoffeeImp) 一些抽象的对数据库资源操作 3.DAOImplementor 如OrderDAOCS, OrderDAOOracle, OrderDAOSybase(类似MilkCoffeeImp FragrantCoffeeImp) 具体的数据库操作,如"INSERT INTO "等语句,OrderDAOOracle是Oracle OrderDAOSybase是Sybase数据库. 4.数据库 (Cloudscape, Oracle, or Sybase database via JDBC API) <淘宝热门商品:
 

39.00 元 

双皇冠AAA级天然墨西哥彩眼黑曜石手链

 

59.00 元 

doob多布-皇冠商铺机器猫一家现货供应


来源:程序员网

小小豆叮

与 James Clark 齐步并进

对标记语言主要权威人士的采访(和分析) Uche Ogbuji(uche.ogbuji@fourthought.com) 首席顾问,Fourthought, Inc. 2002 年 7 月 James Clark 是一位在标记语言界有目共睹的最有成就的开发人员。在他为 SGML 和 XML 作出贡献的杰出职业生涯中,他一直从事与标准本身相关的工作,他就标记语言在哪些方面要符合传统代码提出了重要的实践性观点,最重要的是,他编写的许多程序将 XML(以及之前的 SGML)从抽象的设想变成具体的实践。在本文中,就 XML 领域的实际发展、现状和未来,Uche Ogbuji 对 James Clark 进行了采访。作者还对讨论的问题提供了自己的分析。 2001 年 12 月,XML 2001 会议委员会将首届 XML 杯授予了 James Clark。该奖项是为了表彰他对 XML 社区做出的诸多成就,没有人对他应得的这个奖项表示怀疑。如果您曾用过标记语言做过任何什么事情,那么您可能就用到了 James Clark 编写的代码: 那些已经利用 Linux Documentation Project 的 Linux 用户用到了 Clark 的 DSSSL 处理器(一种针对 SGML 的 XSLT 处理器)Jade。 Clark 的 sgmls 是世界上使用最广泛的 SGML 解析器。 expat 或 XT(分别是解析器和 XSLT 处理器)被许许多多 XML 开发人员使用。的确,就它在 Python、Perl 和 Apache 项目中的流行程度而言,expat 明显是使用最广泛的 XML 解析器之一。 详细信息请在http://www-900.ibm.com/developerWorks/cn/xml/x-jclark/index.shtml?n-x-09261中浏览 <淘宝热门商品:
 

9.80 元  

恒睿日本长筒棉袜批发网

疯狂促销 韩国进口复古百搭格子围巾风扉全球明星必备 只要9.8

 

145.00 元 

八心八箭瑞士钻石六爪旁镶钻经典钻戒指


来源:程序员网

小小豆叮

浅议Web服务

浅议Web服务 作者-阿 金 随着互连网络的广泛应用和发展,特别是.NET技术的升温和市场的日渐成熟,越来越多软件开发商在为到底是选择微软公司的.NET还是SUN公司的J2EE作为自己开发平台和工具而感到左右为难。一般说来,绝大多数公司根据市场情况,客户需求,开发成本,升级成本,培训成本,产品价格,兼容性,可靠性、安全性等选择了其中之一。也有少数有实力的公司准备开发两套独立的产品,以满足不同的客户需求。更多的公司希望自己开发的产品能相互移植,特别是从微软公司的.NET移植到SUN公司的J2EE。既能利用微软的产品相对便宜,开发成本低,开发效率高,又可拥有J2EE所具有的开放性、跨平台性、安全性,扩大自己的客户群。 美国 神鸟(Stryon)公司即将推出iNET产品将有能力让软件开发商用微软公司的.NET开发的应用利用J2EE技术无缝地移植到非Windows平台上。iNET相当于.NET的JAVA实现。它由一个IL2JAVA转换工具,用JAVA实现的.NET框架类库等组成。能集成Tomcat,IBM WebSphere ,Sun one , BEA WebLogic,Oracle9i,等多种用以实现ASP.NET和Web service的Web服务器。 是的,这就是Web服务。一切都是因为Web服务的出现,使得.NET和J2EE争夺的焦点已不完全是对象模型之间的战争或者编程语言选美竞赛了。Web服务使用基于 XML 的消息处理作为基本的数据通讯方式,消除使用不同组件模型、操作系统和编程语言的系统之间存在的差异,使异类系统能够作为单个计算网络协同运行。开发人员可以用像过去在创建分布式应用程序时使用组件一样的方式创建将来自各种源的Web服务组合在一起的应用程序。 Web 服务所实现的最基本的方案是向它的客户端提供某个基本功能以供其使用。也可以以复合方式使用Web服务来集成一组似乎完全不同的现有应用程序。还能创建构成端对端工作流解决方案的应用程序(如企业到企业交易中的解决方案)。 Web服务是建立在一些通用协议的基础上,如HTTP,SOAP,XML,WSDL,UDDI等。这些协议在涉及到操作系统、对象模型和编程语言的选择时,没有任何倾向,因此将会有很强的生命力。但具体到Web服务编程时,.NET和J2EE有一些区别。.NET Web服务可用C#,VB,JScript等语言编写,还能利用一些Windows资源;而J2EE Web服务一般使用JAVA语言及J2EE资源,像Bean,EJB,CORBA等。它们在编程环境,语法结构,管理配置等方面也各有自己的特色。iNET Web服务用JAVA语言实现了.NET 类库中提供的Web服务APIs。它能把用户用.NET开发的Web服务移植到与平台无关的JAVA。因是JAVA,故也可利用JAVA的资源。 进行Web服务调用时发生的过程与进行常规方法调用时发生的过程类似。主要的差别在于,不是调用位于客户端应用程序中的方法,而是根据指定的传输(如 HTTP)生成请求消息。由于Web 服务方法可能位于另一台计算机上,因此Web 服务处理请求所需的信息必须通过网络传递给承载Web 服务的服务器。Web 服务处理此信息并通过网络将结果发送回客户端应用程序。这就是可编程的 Internet 可以预见,作为 Internet下的一个革命性进步,Web服务必将开创一个分布式应用程序开发的新时代。 <淘宝热门商品:
 

35.00 元  

〓朩玲〓网游点卡专卖店『无分店无小号!无手机充值卡!』

【五钻自动发货】跑跑卡丁车40元400点专用卡【充值看商品说明】

 

 

皇冠舒友阁 顶级特效美容护肤 效果才是硬道理


来源:程序员网

小小豆叮

设计模式之Proxy(代理)

理解并使用设计模式,能够培养我们良好的面向对象编程习惯,同时在实际应用中,可以如鱼得水,享受游刃有余的乐趣. Proxy是比较有用途的一种模式,而且变种较多,应用场合覆盖从小结构到整个系统的大结构,Proxy是代理的意思,我们也许有代理服务器等概念,代理概念可以解释为:在出发点到目的地之间有一道中间层,意为代理. 设计模式中定义: 为其他对象提供一种代理以控制对这个对象的访问. 为什么要使用Proxy? 1.授权机制 不同级别的用户对同一对象拥有不同的访问权利,如Jive论坛系统中,就使用Proxy进行授权机制控制,访问论坛有两种人:注册用户和游客(未注册用户),Jive中就通过类似ForumProxy这样的代理来控制这两种用户对论坛的访问权限. 2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动. 举例两个具体情况: (1)如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片. (2)如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象. 总之原则是,对于开销很大的对象,只有在使用它时才创建,这个原则可以为我们节省很多宝贵的Java内存. 所以,有些人认为Java耗费资源内存,我以为这和程序编制思路也有一定的关系. 如何使用Proxy? 以Jive论坛系统为例,访问论坛系统的用户有多种类型:注册普通用户 论坛管理者 系统管理者 游客,注册普通用户才能发言;论坛管理者可以管理他被授权的论坛;系统管理者可以管理所有事务等,这些权限划分和管理是使用Proxy完成的. Forum是Jive的核心接口,在Forum中陈列了有关论坛操作的主要行为,如论坛名称 论坛描述的获取和修改,帖子发表删除编辑等. 在ForumPermissions中定义了各种级别权限的用户: public class ForumPermissions implements Cacheable { /** * Permission to read object. */ public static final int READ = 0; /** * Permission to administer the entire sytem. */ public static final int SYSTEM_ADMIN = 1; /** * Permission to administer a particular forum. */ public static final int FORUM_ADMIN = 2; /** * Permission to administer a particular user. */ public static final int USER_ADMIN = 3; /** * Permission to administer a particular group. */ public static final int GROUP_ADMIN = 4; /** * Permission to moderate threads. */ public static final int MODERATE_THREADS = 5; /** * Permission to create a new thread. */ public static final int CREATE_THREAD = 6; /** * Permission to create a new message. */ public static final int CREATE_MESSAGE = 7; /** * Permission to moderate messages. */ public static final int MODERATE_MESSAGES = 8; ..... public boolean isSystemOrForumAdmin() {   return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]); } ..... } 因此,Forum中各种操作权限是和ForumPermissions定义的用户级别有关系的,作为接口Forum的实现:ForumProxy正是将这种对应关系联系起来.比如,修改Forum的名称,只有论坛管理者或系统管理者可以修改,代码如下: public class ForumProxy implements Forum { private ForumPermissions permissions; private Forum forum; this.authorization = authorization; public ForumProxy(Forum forum, Authorization authorization, ForumPermissions permissions) { this.forum = forum; this.authorization = authorization; this.permissions = permissions; } ..... public void setName(String name) throws UnauthorizedException, ForumAlreadyExistsException {   //只有是系统或论坛管理者才可以修改名称   if (permissions.isSystemOrForumAdmin()) {     forum.setName(name);   }   else {     throw new UnauthorizedException();   } } ... } 而DbForum才是接口Forum的真正实现,以修改论坛名称为例: public class DbForum implements Forum, Cacheable { ... public void setName(String name) throws ForumAlreadyExistsException {   ....   this.name = name;   //这里真正将新名称保存到数据库中   saveToDb();   .... } ... } 凡是涉及到对论坛名称修改这一事件,其他程序都首先得和ForumProxy打交道,由ForumProxy决定是否有权限做某一样事情,ForumProxy是个名副其实的"网关","安全代理系统". 在平时应用中,无可避免总要涉及到系统的授权或安全体系,不管你有无意识的使用Proxy,实际你已经在使用Proxy了. 我们继续结合Jive谈入深一点,下面要涉及到工厂模式了,如果你不了解工厂模式,请看我的另外一篇文章:设计模式之Factory 我们已经知道,使用Forum需要通过ForumProxy,Jive中创建一个Forum是使用Factory模式,有一个总的抽象类ForumFactory,在这个抽象类中,调用ForumFactory是通过getInstance()方法实现,这里使用了Singleton(也是设计模式之一,由于介绍文章很多,我就不写了,看这里),getInstance()返回的是ForumFactoryProxy. 为什么不返回ForumFactory,而返回ForumFactory的实现ForumFactoryProxy? 原因是明显的,需要通过代理确定是否有权限创建forum. 在ForumFactoryProxy中我们看到代码如下: public class ForumFactoryProxy extends ForumFactory {   protected ForumFactory factory;   protected Authorization authorization;   protected ForumPermissions permissions;   public ForumFactoryProxy(Authorization authorization, ForumFactory factory,   ForumPermissions permissions)   {     this.factory = factory;     this.authorization = authorization;     this.permissions = permissions;   }   public Forum createForum(String name, String description)       throws UnauthorizedException, ForumAlreadyExistsException   {     //只有系统管理者才可以创建forum     if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {       Forum newForum = factory.createForum(name, description);       return new ForumProxy(newForum, authorization, permissions);     }     else {       throw new UnauthorizedException();   } } 方法createForum返回的也是ForumProxy, Proxy就象一道墙,其他程序只能和Proxy交互操作. 注意到这里有两个Proxy:ForumProxy和ForumFactoryProxy. 代表两个不同的职责:使用Forum和创建Forum; 至于为什么将使用对象和创建对象分开,这也是为什么使用Factory模式的原因所在:是为了"封装" "分派";换句话说,尽可能功能单一化,方便维护修改. Jive论坛系统中其他如帖子的创建和使用,都是按照Forum这个思路而来的. 以上我们讨论了如何使用Proxy进行授权机制的访问,Proxy还可以对用户隐藏另外一种称为copy-on-write的优化方式.拷贝一个庞大而复杂的对象是一个开销很大的操作,如果拷贝过程中,没有对原来的对象有所修改,那么这样的拷贝开销就没有必要.用代理延迟这一拷贝过程. 比如:我们有一个很大的Collection,具体如hashtable,有很多客户端会并发同时访问它.其中一个特别的客户端要进行连续的数据获取,此时要求其他客户端不能再向hashtable中增加或删除 东东. 最直接的解决方案是:使用collection的lock,让这特别的客户端获得这个lock,进行连续的数据获取,然后再释放lock. public void foFetches(Hashtable ht){   synchronized(ht){     //具体的连续数据获取动作..   } } 但是这一办法可能锁住Collection会很长时间,这段时间,其他客户端就不能访问该Collection了. 第二个解决方案是clone这个Collection,然后让连续的数据获取针对clone出来的那个Collection操作.这个方案前提是,这个Collection是可clone的,而且必须有提供深度clone的方法.Hashtable就提供了对自己的clone方法,但不是Key和value对象的clone,关于Clone含义可以参考专门文章. public void foFetches(Hashtable ht){   Hashttable newht=(Hashtable)ht.clone(); } 问题又来了,由于是针对clone出来的对象操作,如果原来的母体被其他客户端操作修改了, 那么对clone出来的对象操作就没有意义了. 最后解决方案:我们可以等其他客户端修改完成后再进行clone,也就是说,这个特别的客户端先通过调用一个叫clone的方法来进行一系列数据获取操作.但实际上没有真正的进行对象拷贝,直至有其他客户端修改了这个对象Collection. 使用Proxy实现这个方案.这就是copy-on-write操作. Proxy应用范围很广,现在流行的分布计算方式RMI和Corba等都是Proxy模式的应用. 更多Proxy应用,见http://www.research.umbc.edu/~tarr/cs491/lectures/Proxy.pdf Sun公司的 Explore the Dynamic Proxy API Dynamic Proxy Classes <淘宝热门商品:
 

¥:9.99 

【黑龙江商盟】棋子儿平价美妆店-烟熏彩妆/假睫毛大全/新娘用品

买十送一全网最低价高级无痕透明根部自然浓密凌乱假睫毛仿真毛发

 

¥:6.98 

四皇冠 值得您收藏的包店 冲五冠 5i贝贝外贸包店◢

◣四冠◆贝妈家◢出口英国★荔枝纹钉扣简约短款钱包◆特价6.99


来源:程序员网

小小豆叮

一个MySQL数据库的操作包

数据库操作可以中WEB开发中最常用到的,很多Java开发工具都提供了自动的Data bean WinZard.只要数据库建立好,相应的操作数据库的Bean就基本可以自动完成,本人使用Jcreator开发bean,手工录入觉得也不是很麻烦的事情,下面我常用的数据库操作bean,完全可以对付访问量不是很大的系统 : Mysql类: import java.sql.*; import java.io.*; /** * 处理数据库的连接和访问 * @author sanware bqlr * @version 1.01 */ public class Mysql { private Connection conn = null; private Statement stmt = null; private PreparedStatement prepstmt = null; //这是一个全局类,里面放置数据库的参数,如数据库主机 访问用户名 密码等 private static BeansConstants CONST = BeansConstants.getInstance(); /** * 构造数据库的连接和访问类 */ public Mysql() throws Exception { Class.forName(CONST.dbdriver); conn = DriverManager.getConnection(CONST.dburl); stmt = conn.createStatement(); } public Mysql(String sql) throws Exception { Class.forName(CONST.dbdriver); conn = DriverManager.getConnection(CONST.dburl); this.prepareStatement(sql); } /** * 返回连接 * @return Connection 连接 */ public Connection getConnection() { return conn; } /** * PreparedStatement * @return sql 预设SQL语句 */ public void prepareStatement(String sql) throws SQLException { prepstmt = conn.prepareStatement(sql); } /** * 设置对应值 * @param index 参数索引 * @param value 对应值 */ public void setString(int index,String value) throws SQLException { prepstmt.setString(index,value); } public void setInt(int index,int value) throws SQLException { prepstmt.setInt(index,value); } public void setBoolean(int index,boolean value) throws SQLException { prepstmt.setBoolean(index,value); } public void setDate(int index,Date value) throws SQLException { prepstmt.setDate(index,value); } public void setLong(int index,long value) throws SQLException { prepstmt.setLong(index,value); } public void setFloat(int index,float value) throws SQLException { prepstmt.setFloat(index,value); } //File file = new File("test/data.txt"); //int fileLength = file.length(); //InputStream fin = new java.io.FileInputStream(file); //mysql.setBinaryStream(5,fin,fileLength); public void setBinaryStream(int index,InputStream in,int length) throws SQLException { prepstmt.setBinaryStream(index,in,length); } public void clearParameters() throws SQLException { prepstmt.clearParameters(); } /** * 返回预设状态 */ public PreparedStatement getPreparedStatement() { return prepstmt; } /** * 返回状态 * @return Statement 状态 */ public Statement getStatement() { return stmt; } /** * 执行SQL语句返回字段集 * @param sql SQL语句 * @return ResultSet 字段集 */ public ResultSet executeQuery(String sql) throws SQLException { if (stmt != null) { return stmt.executeQuery(sql); } else return null; } public ResultSet executeQuery() throws SQLException { if (prepstmt != null) { return prepstmt.executeQuery(); } else return null; } /** * 执行SQL语句 * @param sql SQL语句 */ public void executeUpdate(String sql) throws SQLException { if (stmt != null) stmt.executeUpdate(sql); } public void executeUpdate() throws SQLException { if (prepstmt != null) prepstmt.executeUpdate(); } /** * 关闭连接 */ public void close() throws Exception { if (stmt != null) { stmt.close(); stmt = null; } if (prepstmt != null) { prepstmt.close(); prepstmt = null; } conn.close(); conn = null; } } Mysql建立好后,以后涉及数据库的操作,只要对象化Mysql就可以: private String page_navlink_insert="insert into page_navlink values (?,?,?,?)"; public void insertnavlink() throws Exception {   ResultSet rs=null;   try {     Mysql mysql = new Mysql(page_navlink_insert);     mysql.setInt(1,this.siteid);     mysql.setInt(2,this.pageid);     mysql.setString(3,this.navlinkname);     mysql.setString(4,this.pagefile);     mysql.executeUpdate();     mysql.close();     mysql = null;   } catch (Exception ex) {     throw new Exception("insertnavlink()"+ex.getMessage());   } } 在Jsp中,就可以直接使用一句语句使用insertnavlink()了: <jsp:useBean id="NAV" scope="session" class="mysite.Navlink" /> <jsp:setProperty name="NAV" property="*" /> ........ NAV.insertnavlink(); ...... 频繁访问数据库,需要使用连接池,在tomcat 4.0中配置JNDI,稍微修改一下上面程序就可使用连接池.Tomcat的连接池配置和J2EE类似,因此程序不用修改,也可直接运行在J2EE上. 也可以使用第三方连接池, 如很有名的Poolman. <淘宝热门商品:
 

198.00 元  

野葛根丰胸胶囊 植物萃取 天然健康

 

88.00 元  

【广州商盟】外贸男装、男鞋工厂直接供货批发零售

〖亿贝特价〗外贸原单Versace范思哲多LOGO特色羊毛衫、毛衣V灰紫


来源:程序员网

小小豆叮

设计模式之Decorator(油漆工)

Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这两种实体在Decorator模式中是必须的. Decorator定义: 动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活. 为什么使用Decorator? 我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的. 使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能. 如何使用? 举Adapter中的打桩示例,在Adapter中有两种类:方形桩 圆形桩,Adapter模式展示如何综合使用这两个类,在Decorator模式中,我们是要在打桩时增加一些额外功能,比如,挖坑 在桩上钉木板等,不关心如何使用两个不相关的类. 我们先建立一个接口: public interface Work {   public void insert(); } 接口Work有一个具体实现:插入方形桩或圆形桩,这两个区别对Decorator是无所谓.我们以插入方形桩为例: public class SquarePeg implements Work{   public void insert(){     System.out.println("方形桩插入");   } } 现在有一个应用:需要在桩打入前,挖坑,在打入后,在桩上钉木板,这些额外的功能是动态,可能随意增加调整修改,比如,可能又需要在打桩之后钉架子(只是比喻). 那么我们使用Decorator模式,这里方形桩SquarePeg是decoratee(被刷油漆者),我们需要在decoratee上刷些"油漆",这些油漆就是那些额外的功能. public class Decorator implements Work{   private Work work;   //额外增加的功能被打包在这个List中   private ArrayList others = new ArrayList();   //在构造器中使用组合new方式,引入Work对象;   public Decorator(Work work)   {     this.work=work;        others.add("挖坑");     others.add("钉木板");   }   public void insert(){     newMethod();   }      //在新方法中,我们在insert之前增加其他方法,这里次序先后是用户灵活指定的      public void newMethod()   {     otherMethod();     work.insert();   }   public void otherMethod()   {     ListIterator listIterator = others.listIterator();     while (listIterator.hasNext())     {       System.out.println(((String)(listIterator.next())) + " 正在进行");     }   } } 在上例中,我们把挖坑和钉木板都排在了打桩insert前面,这里只是举例说明额外功能次序可以任意安排. 好了,Decorator模式出来了,我们看如何调用: Work squarePeg = new SquarePeg(); Work decorator = new Decorator(squarePeg); decorator.insert(); Decorator模式至此完成. 如果你细心,会发现,上面调用类似我们读取文件时的调用: FileReader fr = new FileReader(filename); BufferedReader br = new BufferedReader(fr); 实际上Java 的I/O API就是使用Decorator实现的,I/O变种很多,如果都采取继承方法,将会产生很多子类,显然相当繁琐. Jive中的Decorator实现 在论坛系统中,有些特别的字是不能出现在论坛中如"打倒XXX",我们需要过滤这些"反动"的字体.不让他们出现或者高亮度显示. 在IBM Java专栏中专门谈Jive的文章中,有谈及Jive中ForumMessageFilter.java使用了Decorator模式,其实,该程序并没有真正使用Decorator,而是提示说:针对特别论坛可以设计额外增加的过滤功能,那么就可以重组ForumMessageFilter作为Decorator模式了. 所以,我们在分辨是否真正是Decorator模式,以及会真正使用Decorator模式,一定要把握好Decorator模式的定义,以及其中参与的角色(Decoratee 和Decorator). <淘宝热门商品:
 

268.00 元 

绝对NO1新版mirifem魔力丰丰胸片

 

98.00 元 

08新款 日式V领子二件套+黑色领带假二件套 本店热销款


来源:程序员网

小小豆叮

无线精英的奥秘:荷兰人最了解

聚焦 Ed Alkema John Papageorge(john@mediaoverdrive.com) 总裁,Media Overdrive 2002 年 9 月 荷兰人在无线技术方面已经经历了几个发展阶段。据阿姆斯特丹的无线开发人员 Ed Alkema 所说,“我们已了解了它的所有奥秘。” 无线开发人员将学习由 Alkema 开发的一些诀窍,这些诀窍可以解决他采用新近引入的 WAP 时遇到的早期挫折。开发人员还将了解到荷兰人对 i-mode 的看法。尽管 Alkema 及其公司致力于创建健壮的、可伸缩的无线商业应用程序,但当开发人员发现被 Alkema 称为“真正的杀手无线应用程序”的应用程序时,我敢打赌他们一定会很惊奇。 虽然 Ed Alkema 在投身无线业界之前只拥有极其普通的开发背景,但他目前是位于阿姆斯特丹的 Bwirelezz 中负责平台集成的副总裁。 1995 年,Alkema 创立了 Tinspark,这是一家由 Agency.com 收购的因特网软件开发公司。在约两年前创立 Bwirelezz 之前,他在 Agency.com 致力于电子商业解决方案和体系结构。 “无线将有光明的未来这个预言为人们所知是在 2000 年初,所以我本人和一些朋友决定进入无线竞技场。”Alkema 说道,“Bwirelezz 是一家为企业构建软件的公司,使他们的后端系统能够通过无线设备访问。该公司主要关注于 WAP,但现在我们构建 WAP/i-mode/SMS/J2ME 的解决方案。” 详细文章请在http://www-900.ibm.com/developerWorks/cn/java/j-wi-elite5/index.shtml浏览 <淘宝热门商品:
 

 

纤体·丽颜New Concept茶坊 纯天然美容瘦身品位花饮

 

96.00 元 

奥地利进口 专柜礼盒 天然水晶 施家经典STARS


来源:程序员网

小小豆叮

修正Java中wait方法超时语意模糊性的一种方案

邓辉、孙鸣 (dhui@263.net) 2002 年 9 月 Java语言中内建了对于多线程的支持,可以非常方便的创建、控制线程以及在线程之间进行同步操作。另外,为了支持更为高级的线程间同步机制,比如:类似于POSIX中的条件变量,Java在Object类中提供了wait、notify和notifyAll方法,使得所有的类都隐式的继承了这些方法。特别地,为了提供对于程序健壮性方面的考虑,在Java中提供了对于wait方法超时语意的支持。但是Java在对于wait方法超时语意的支持方面存在模糊性,即在调用具有超时语意的wait方法返回时,无法区分是由于notify的通知还是由于超时触发的。因此应用开发者在构建需要具有超时语意的应用时,就必须负责对这种语意模糊性进行区分,本文将对这一问题进行剖析,并给出一个比较通用的解决方案。 详细文章请在http://www-900.ibm.com/developerWorks/cn/java/l-threadwait/index.shtml <淘宝热门商品:
 

35.00 元  

〓朩玲〓网游点卡专卖店『无分店无小号!无手机充值卡!』

【五钻自动发货】跑跑卡丁车40元400点专用卡【充值看商品说明】

 

50.00 元  

韩服CASH之家

韩服 HF 跑跑卡丁车 新劳迪 劳迪Introduction 永久 支持韩文名


来源:程序员网

小小豆叮

摩托罗拉收购J2ME技术领先公司 4thpass

2002年9月16日,摩托罗拉在美国宣布收购总部位于西雅图的4thpass公司,摩托罗拉将把4thpass公司的移动应用系统(MAS)整合到其强大的J2ME技术系列产品中。摩托罗拉这次战略性举措就是希望为客户创造更多的业务收入,同时降低管理无线Java™ 2 平台,Micro Edition (J2ME™) 的成本。   MAS已经在全球范围得到商业应用。目前,4thpass公司在世界各地的商业伙伴包括了如西班牙的Telefonica Moviles,Nextel 和韩国的LG等运营商。4thpass公司也通过其增值代理伙伴如爱立信和西门子销售其产品。MAS解决方案包括一个Java下载服务器——一个用以保证应用程序准确地传递到设备的智能供应系统。MAS给运营商提供了实现信息计费的多种途径,同时也为这些运营商提供先进的程序激活技术和相关控制技术,保证程序在无线设备及网络上的正常运行。MAS管理并确保J2ME应用程序及其它移动内容信息通过无线网络传递到手机,并允许移动用户能够对应用程序进行升级和定制,如应用于移动设备上的无线游戏。   这次收购预计将在9月完成。去年,摩托罗拉曾对4thpass公司进行过投资。本次收购同样由摩托罗拉属下的摩托罗拉风险投资公司(Motorola Ventures)组织完成。   “通过将4thpass公司的成功的下载、计费及供应技术结合到摩托罗拉自身的产品系列中,摩托罗拉将拓展其在帮助运营商部署应用服务,以提高其ARPU值方面的策略。” 摩托罗拉战略和业务开发公司副总裁Scott Durchslag先生说,“这次收购清楚地表明了摩托罗拉正在实行的全面投资能增强我们实力的“三层”发展战略。我们投资的领域将(1)增强我们核心的手机业务;(2)将核心业务拓展到软件及技术解决方案领域;(3)在新兴的但是具有战略意义的领域创造成长空间。”   “4thpass公司在业界是广为人知的J2ME软件头号供应商。通过成功合作我们很好地满足了欧洲、亚洲、拉丁美洲以及美国各地移动运营商的需求。”摩托罗拉公司个人通信事业部全球副总裁兼总经理Mike Bordelon补充道,“我们期待着将4thpass公司的解决方案整合到我们的产品系列中,从而为运营商以及Java合作伙伴提供更好的产品和服务”。   在将J2ME技术广泛应用于无线通信领域,摩托罗拉是无可争议的领导厂商。除了致力于建立关键的开放的J2ME标准,以及第一个推出整合了J2ME技术的手机外,摩托罗拉仍将继续为客户提供一整套解决方案,包括了众多的具备J2ME技术的手机产品,定制的应用程序和内容,以及旨在帮助软件开发人员设计和检验新的无线应用的完整服务开发商合作项目。   “很明显,Java是目前无线市场上的主导力量,它已经成为运营商推出数据服务的关键。作为一个公司及在无线数据方案领域领先的开发商,加入摩托罗拉后,4thpass公司进入一个新的发展阶段。”4thpass的共同创始人Mazin Ramadan和Zeyad Ramadan说,“摩托罗拉和4thpass公司将一起为全球运营商提供最好的、完整的和经济的解决方案。”   4th Pass公司(包括其在西雅图的总部)将作为摩托罗拉公司个人通信事业部的一部分来运营。 <淘宝热门商品:
 

16.0元  

【珠三角商盟】联合利众●减肥瘦身●丰胸美乳●私处保养●美容

 

¥:4.00 

蓉蓉de美女加工厂 打造淘宝最低价


来源:程序员网

小小豆叮