??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品1区,国产在线资源,国产在线视频你懂得http://www.aygfsteel.com/killvin/category/8033.htmlzh-cnWed, 28 Feb 2007 03:53:09 GMTWed, 28 Feb 2007 03:53:09 GMT60q发问题及控制手D?http://www.aygfsteel.com/killvin/archive/2006/04/06/39542.htmlkillvinkillvinThu, 06 Apr 2006 02:57:00 GMThttp://www.aygfsteel.com/killvin/archive/2006/04/06/39542.html http://www.cnblogs.com/zhenyulu/articles/208799.html

W??q发问题及控制手D?/h1>

什么是q发问题Q假设有q么一家书吧,֮可以到那里喝茶读书。顾客拿着选好要读的图书到柜台登记Q然后找个地方去阅读Q走时图书归q店家。有一天,一个顾客相中了一本书后正要拿ȝ讎ͼ另一个顾客的手也抓住了这仅有的一本书Qƈ发问题出C。两个顾客要d一本书Q互不相让,q让店主伤透了脑筋。这个案例仅仅是众多q发问题中的一个微部分,但从中我们可以看出ƈ发问题主要出现在多个用户Ҏ限资源进行访问的时候,如果解决不好会直接媄响系l的有效、正常运行。数据库是一个共享的资源Qƈ发问题的出现是必不可免的Q如何识别ƈ发类型ƈ加以控制是这一章重点要讲述的内宏V?/p>

本章分成两大部分,一部分主要讲Visual FoxPro中ƈ发控制机制。VFP中ƈ发控制相对简单,数据加锁的Ş式比较单一Q非帔R合作ؓ初步了解q发问题的切入点。第二部分以SQL Server 2000、ADO.NET以及C#Z要工P深入了解q发一致性问题、封锁协议、事务隔ȝ内容Q难度相对较深。象一些更为深入的q发控制手段Q例如多_度锁和意象锁{内容在本章中将不做深入讨论Q感兴趣可以参考相关书c?/p>

 

[实在不好意思COPY别h的成果,不过q篇文章出奇的精彩,ƈ发操作的来龙去脉说的清清楚楚Q也是我正要扄Q比JAVAEYE上面所谓的专家叫嚷着什?悲观??乐观?而不解是原因要强的多Q值得收藏]



killvin 2006-04-06 10:57 发表评论
]]>
About unsaved-value [resource : javaeye] http://www.aygfsteel.com/killvin/archive/2006/03/02/33297.htmlkillvinkillvinThu, 02 Mar 2006 12:45:00 GMThttp://www.aygfsteel.com/killvin/archive/2006/03/02/33297.html当你昑ּ的用session.save()或者session.update()操作一个对象的时候,实际上是用不?SPAN style="COLOR: #ffa34f">unsaved-value的。某些情况下(父子表关联保?Q当你在E序中ƈ没有昑ּ的用save或者update一个持久对象,那么Hibernate需要判断被操作的对象究竟是一个已l持久化q的持久对象Q是一个尚未被持久化过的内存时对象。例如:

java代码: 

  Session session = ...;
  Transaction tx = ...;
  
  Parent parent = (Parent) session.load(Parent.class, id);
  
  Child child = new Child();
  child.setParent(parent);
  child.setName("sun");
  
 10 parent.addChild(child);
 11 s.update(parent);
 12 
 13 s.flush();
 14 tx.commit();
 15 s.close();



在上例中Q程序ƈ没有昑ּ的session.save(child); 那么Hibernate需要知道childI竟是一个时对象,q是已经在数据库中有的持久对象。如果child是一个新创徏的时对?本例中就是这U情?Q那么Hibernate应该自动产生session.save(child)q样的操作,如果child是已l在数据库中有的持久对象Q那么Hibernate应该自动产生session.update(child)q样的操作?

因此我们需要暗CZ下HibernateQ究竟child对象应该对它自动saveq是update。在上例中,昄我们应该暗示Hibernate对child自动saveQ而不是自动update。那么Hibernate如何判断I竟对child是saveq是update呢?它会取一下child的主键属?child.getId() Q这里假设id?java.lang.Integercd的。如果取到的Id值和hbm映射文g中指定的unsave-value相等Q那么Hibernate认ؓchild是新的内存时对象,发送saveQ如果不相等Q那么Hibernate认ؓchild是已l持久过的对象,发送update?

unsaved-value="null" (默认情况Q适用于大多数对象cd主键 Integer/Long/String/...)

当Hibernate取一下child的IdQ取出来的是null(在上例中肯定取出来的是null)Q和unsaved-value讑֮值相{,发送save(child)

当Hibernate取一下child的idQ取出来的不是nullQ那么和unsaved-value讑֮g相等Q发送update(child)

例如下面的情况:

java代码: 

  Session session = ...;
  Transaction tx = ...;
  
  Parent parent = (Parent) session.load(Parent.class, id);
  Child child = (Child) session.load(Child.class, childId);
  
  child.setParent(parent);
  child.setName("sun");
  
 10 parent.addChild(child);
 11 s.update(parent);
 12 
 13 s.flush();
 14 tx.commit();
 15 s.close();



child已经在数据库中有了,是一个持久化的对象,不是新创建的Q因此我们希望Hibernate发送update(child)Q在该例中,Hibernate取一下child.getId()Q和unsave-value指定的null比对一下,发现不相{,那么发送update(child)?

BTW: parent对象不需要操心,因ؓE序昑ּ的对parent有load操作和update的操作,不需要Hibernate自己来判断究竟是saveq是update了。我们要注意的只是child对象的操作。另?SPAN style="COLOR: #ffa34f">unsaved-value
是定义在Childcȝ主键属性中的?

java代码: 

 1 <class name="Child" table="child">
 2 <id column="id" name="id" type="integer" unsaved-value="null">
 3   <generator class="identity"/>
 4 </id>
 5 ...
 6 </class>



如果主键属性不是对象型Q而是基本cdQ如int/long/double/...Q那么你需要指定一个数值型?SPAN style="COLOR: #ffa34f">unsaved-value
Q例如:

java代码: 

 1 unsaved-null="0"



在此提醒大家Q很多h以ؓ对主键属性定义ؓint/longQ比定义为Integer/Longq行效率来得高,认ؓ基本cd不需要进行对象的装和解构操作,因此喜欢把主键定义ؓint/long的。但实际上,Hibernate内部L把主键{换ؓ对象型进行操作的Q就你定义为int/long型的QHibernate内部也要q行一ơ对象构造操作,q回l你的时候,q要q行解构操作Q效率可能反而低也说不定。因此大家一定要扭{一个观点,在Hibernate中,主键属性定义ؓ基本cdQƈ不能够比定义为对象型效率来的高,而且也多了很多麻烦,因此大家使用对象型的Integer/Long定义主键?

unsaved-value="none"?
unsaved-value="any"

M要用在主键属性不是通过Hibernate生成Q而是E序自己setId()的时候?

在这里多说一句,强烈使用Hibernate的id generatorQ或者你可以自己扩展Hibernate的id generatorQ特别注意不要用有实际含义的字D当做主键来用!例如用户cUserQ很多h喜欢用用L陆名U做Z键,q是一个很不好的习惯,当用L和其他实体类有关联关pȝ时候,万一你需要修改用L陆名Uͼ一改就需要改好几张表中的数据。偶合性太高,而如果你使用无业务意义的id generatorQ那么修改用户名Uͼ只修改user表就行了?

p个问题引甛_来,如果你严格按照这个原则来设计数据库,那么你基本上是用不到手工来setId()的,你用Hibernate的id generatorOK了。因此你也不需要了解当

unsaved-value="none"?
unsaved-value="any"

I竟有什么含义了。如果你非要用assigned不可Q那么l解释一下:

unsaved-value="none" 的时候,׃不论主键属性ؓM|都不可能为noneQ因此HibernateL对child对象发送update(child)

unsaved-value="any" 的时候,׃不论主键属性ؓM|都肯定ؓanyQ因此HibernateL对child对象发送save(child)

大多数情况下Q你可以避免使用assignedQ只有当你用复合主键的时候不得不手工setId()Q这时候需要你自己考虑I竟怎么讄unsaved-value了,Ҏ你自q需要来定?

BTW: Gavin King强烈不徏议用composite-idQ强烈徏议用UserType?

因此Q如果你在系l设计的时候,遵@如下原则Q?

1、用Hibernate的id generator来生成无业务意义的主键,不用有业务含义的字D做主键Q不使用assigned?

2、用对象类?String/Integer/Long/...)来做主键Q而不使用基础cd(int/long/...)做主?

3、不使用composite-id来处理复合主键的情况Q而用UserType来处理该U情c?/SPAN>

那么你永q用的是unsaved-value="null" Q不可能用到any/none/..了?/SPAN>


killvin 2006-03-02 20:45 发表评论
]]>
Update & SavaOrUpdate [author : robbine resource : Javaeye] http://www.aygfsteel.com/killvin/archive/2006/03/02/33296.htmlkillvinkillvinThu, 02 Mar 2006 12:44:00 GMThttp://www.aygfsteel.com/killvin/archive/2006/03/02/33296.html先来Ҏ念:

在Hibernate中,最核心的概念就是对PO的状态管理。一个PO有三U状态:

1、未被持久化的VO
此时是一个内存对象VOQ由JVM理生命周期

2、已被持久化的POQƈ且在Session生命周期?
此时映射数据库数据,由数据库理生命周期

3、曾被持久化q,但现在和Session已经detached了,以VO的n份在q行
q种和Session已经detached的POq能够进入另一个SessionQl进行PO状态管理,此时它就成ؓPO的第二种状态了?SPAN style="COLOR: red">q种PO实际上是跨了Sessionq行了状态维护的?/SPAN>

在传l的JDO1.x中,PO只有前面两种状态,一个PO一旦脱PMQ就丧失了状态了Q不再和数据库数据关联,成ؓ一个纯_的内存VOQ它即ɘq入一个新的PMQ也不能恢复它的状态了?

Hibernate强的地方在于,一个POqSession之后Q还能保持状态,再进入一个新的Session之后Q就恢复状态管理的能力Q但此时状态管理需要用session.update或者session.saveOrUpdateQ这是Hibernate Reference中提到的“requires a slightly different programming model ?

现在正式q入本话题:

单的来说Qupdate?SPAN style="COLOR: #ffa34f">saveOrUpdate是用来对跨Session的POq行状态管理的?/SPAN>

假设你的PO不需要跨Session的话Q那么就不需要用刎ͼ例如你打开一个SessionQ对POq行操作Q然后关闭,之后q个PO你也不会再用CQ那么就不需要用update?

因此Q我们来看看上例Q?
java代码: 

 1 Foo foo=sess.load(Foo.class,id);
 2 foo.setXXX(xxx);
 3 sess.flush();
 4 sess.commit();



PO对象foo的操作都在一个Session生命周期内完成,因此不需要显式的q行sess.update(foo)q样的操作。Hibernate会自动监到foo对象已经被修改过Q因此就向数据库发送一个update的sql。当然如果你非要加上sess.update(foo)也不会错Q只不过q样做没有Q何必要?

而跨Session的意思就是说q个PO对象在Session关闭之后Q你q把它当做一个VO来用Q后来你在Session外面又修改了它的属性,然后你又x开一个SessionQ把VO的属性修改保存到数据库里面,那么你就需要用update了?

java代码: 

  // in the first session
  Cat cat = (Cat) firstSession.load(Cat.class, catId);
  Cat potentialMate = new Cat();
  firstSession.save(potentialMate);
  
  // in a higher tier of the application
  cat.setMate(potentialMate);
  
  // later, in a new session
 10 secondSession.update(cat)// update cat
 11 secondSession.update(mate); // update mate
 12 



cat和mate对象是在W一个session中取得的Q在W一个session关闭之后Q他们就成了PO的第三种状态,和Session已经detached的POQ此时他们的状态信息仍然被保留下来了。当他们q入W二个session之后Q立d可以q行状态的更新。但是由于对cat的修Ҏ作:cat.setMate(potentialMate); 是在Session外面q行的,Hibernate不可能知道cat对象已经被改q了Q第二个Sessionq不知道q种修改Q因此一定要昑ּ的调用secondSession.update(cat); 通知HibernateQcat对象已经修改了,你必d送update的sql了?

所以update的作用就在于此,它只会被用于当一个PO对象跨Sessionq行状态同步的时候才需要写。而一个PO对象当它不需要跨Sessionq行状态管理的时候,是不需要写update的?

再谈?SPAN style="COLOR: #ffa34f">saveOrUpdate
的用场:

saveOrUpdate和update的区别就在于在跨Session的PO状态管理中QHibernate对PO采取何种{略?

例如当你写一个DAOImpl的时候,让cat对象增加一个mateQ如下定义:
java代码: 

1 public void addMate(Cat cat, Mate mate) {
 2     Session session = ...;
 3     Transacton tx = ...;
 4     session.update(cat);
 5     cat.addMate(mate);
 6     tx.commit();
 7     session.close();
 8 };



昄你是需要把Hibernate的操作封装在DAO里面的,让业务层的程序员和Web层的E序员不需要了解HibernateQ直接对DAOq行调用?

此时问题来了:上面的代码运行正有一个必要的前提Q那是Ҏ调用参数cat对象必须是一个已l被持久化过的POQ也是来说Q它应该首先从数据库查询出来Q然后才能这L。但是业务层的程序员昄不知道这U内部的玄妙Q如果他的业务是现在增加一个catQ然后再增加它的mateQ他昄会这栯用,new一个cat对象出来Q然后就addMateQ?

java代码: 

 1 Cat cat = new Cat();
 2 cat.setXXX();
 3 daoimpl.addMate(cat,mate);



但是h意看Q这个cat对象只是一个VOQ它没有被持久化q,它还不是POQ它没有资格调用addMateҎQ因此调用addMateҎ不会真正往数据库里面发送update的sqlQ这个cat对象必须先被save到数据库Q在真正成ؓ一个PO之后Q才具备addMate的资根{?

你必这h操作Q?

java代码: 

 1 Cat cat = new Cat();
 2 cat.setXXX();
 3 daoimpl.addCat(cat);
 4 daoimpl.addMate(cat, mate);



先持久化catQ然后才能对catq行其他的持久化操作。因此要求业务层的程序员必须清楚cat对象处于何种状态,到底是第一U,q是W三U。如果是W一U,p先saveQ再addMateQ如果是W三U,q接addMate?

但是最致命的是Q如果整个Y件分层很多,业务层的E序员他拿到q个cat对象也可能是上层Web应用层传递过来的catQ他自己也不知道q个catI竟是VOQ没有被持久化过Q还是已l被持久化过Q那么他Ҏ没有办法写E序了?

所以这LDAOImpl昄是有问题的,它会对业务层的程序员造成很多~程上的陷阱Q业务层的程序员必须深刻的了解他调用的每个DAO对PO对象q行了何U状态管理,必须深刻的了解他的PO对象在Q何时候处于什么确切的状态,才能保证~程的正性,昄q是做不到的Q但是有?SPAN style="COLOR: #ffa34f">saveOrUpdate
Q这些问题就q刃而解了?

现在你需要修改addMateҎQ?

java代码: 

1 public void addMate(Cat cat, Mate mate) {
 2     Session session = ...;
 3     Transacton tx = ...;
 4     session.saveOrUpdate(cat);
 5     cat.addMate(mate);
 6     tx.commit();
 7     session.close();
 8 };



如上Q如果业务层的程序员传进来的是一个已l持久化q的PO对象Q那么Hibernate会更新cat对象(假设业务层的E序员在Session外面修改qcat的属?Q如果传q来的是一个新new出来的对象,那么向数据库saveq个PO对象?

BTW: Hibernate此时I竟采取更新cat对象Q还是save cat对象Q取决于unsave-value的设定?

q样Q业务层的程序员׃必再操心PO的状态问题了Q对于他们来_不管cat是new出来的对象,只是一个VO也好Q还是从数据库查询出来的的PO对象也好Q全部都是直接addMateOK了:



killvin 2006-03-02 20:44 发表评论
]]>
StrutsFileUpload http://www.aygfsteel.com/killvin/archive/2006/03/02/33295.htmlkillvinkillvinThu, 02 Mar 2006 12:43:00 GMThttp://www.aygfsteel.com/killvin/archive/2006/03/02/33295.html


StrutsFileUpload
File Upload - Simple Example
HTML
This isn't specific to Struts, but gives a simple example of the HTML required to upload a single file.

Two things are needed in the html page. Firstly, the form needs to specify an enctype of multipart/form-data and secondly an form control of type file.

JSP
The above HTML can be generated using the Struts tags in the following way

<html:form action="/uploadMyFile.do" enctype="multipart/form-data">

Select File: <html:file property="myFile">

<html:submit value="Upload File"/>

</html:form>

ActionForm
The ActionForm needs a property of type FormFile.

Regular ActionForms
import org.apache.struts.upload.FormFile;

public class MyActionForm extends ActionForm {

private FormFile myFile;

public void setMyFile(FormFile myFile) {
this.myFile = myfile;
}

public FormFile getMyFile() {
return myFile;
}
}

Dyna ActionForms
In the struts-config.xml

<form-bean name="myForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="myFile" type="org.apache.struts.upload.FormFile"/>
</form-bean>

Whats Needed in the Action
Nothing special really, just retrieve the FormFile from the ActionForm, as you would any other property, and process it as you like. You can get the file name, size and file contents from the FormFile.

public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {

MyActionForm myForm = (MyActionForm)form;

// Process the FormFile
FormFile myFile = myForm.getMyFile();
String contentType = myFile.getContentType();
String fileName = myFile.getFileName();
int fileSize = myFile.getFileSize();
byte[] fileData = myFile.getFileData();
...
}

File Upload Configuration
The following parameters can be set in the <controller> element of the struts-config.xml to configure file upload:

bufferSize - The size (in bytes) of the input buffer used when processing file uploads. Default is 4096.

maxFileSize - The maximum size (in bytes) of a file to be accepted as a file upload. Can be expressed as a number followed by a "K", "M", or "G", which are interpreted to mean kilobytes, megabytes, or gigabytes, respectively. Default is 250M.

multipartClass - The fully qualified Java class name of the multipart request handler class to be used with this module. Defaults is org.apache.struts.upload.CommonsMultipartRequestHandler.

tempDir - Temporary working directory to use when processing file uploads.

Above taken from the Configuration section in the User Guide.

Plugging in an Alternative File Upload Mechanism
By default Struts uses Commons File Upload.

Alternative implementations can be plugged as long as they implement the org.apache.struts.upload.MultipartRequestHandler interface and Struts configured to use that implementation by specifying it in the multipartClass parameter in the <controller> element of the struts-config.xml

Fair Warning: The MultipartRequestHandler interface is almost certain to change in a Struts 1.3 or higher release.


killvin 2006-03-02 20:43 发表评论
]]>
վ֩ģ壺 | ƽ| | ɽ| ǿ| | ɳ| °Ͷ| ͬ| ¸| | ̨| | | | | DZ| Դ| ٸ| Դ| | Ʊ| ĵ| | | | | ٷ| | ͨ| ν| | | | Դ| | ƽ| | | | |