Two useful liks:
http://jibbering.com/faq/faq_notes/closures.html#clMem
http://javascript.weblogsinc.com/2005/03/07/javascript-memory-leaks/

文章来源:http://blueoxygen.dflying.net/3/archive/69_no_more_crap_about_ie_memeory_leak.html

posted @ 2006-03-16 11:19 BlueO2 阅读(281) | 评论 (0)编辑 收藏

Venkman is a Javascript Debugger as a FireFox extenstion.It's at least powerful than IE's default script debugger(not Visual InterDev's).You can watch varaiable,set breakpoint and use "step over" "step into" "step out" "continue" buttons to debug your niffy javascript codes.
It's ease to use.And tutorial is HERE:http://www.svendtofte.com/code/learning_venkman/index.php

文章来源:http://blueoxygen.dflying.net/3/archive/75_ajax_tool_box---venkman.html

posted @ 2006-03-16 11:19 BlueO2 阅读(379) | 评论 (0)编辑 收藏

eclipsePOJO used by Hibernate needs to implement hashCode() and equals() method.That's a kind of stuffy work and will be done many many times during development.Some IDEs support automatical generation feature such as IDEA.Eclipse famous plug-in--MyElipse also suppots but it's not free of charge.
I think nearly all JAVAers know Apache Commons open source project.We can use Commons lib to generate hashCode() and equals() method.I wanna tell you that there is also a plugin for Eclipse called Commons4E which help you generate hasCode() and equals().
It also can generate toString() and compareTo() method.That's a smart plugin.Enjoy it.Link



文章来源:http://blueoxygen.dflying.net/3/archive/79_hibernate_pojos_good_assistant-commons_for_eclipse.html

posted @ 2006-03-16 11:19 BlueO2 阅读(422) | 评论 (0)编辑 收藏

Hibernate and Lazy Initialization

Hibernate object relational mapping offers both lazy and non-lazy modes of object initialization. Non-lazy initialization retrieves an object and all of its related objects at load time. This can result in hundreds if not thousands of select statements when retrieving one entity. The problem is compounded when bi-directional relationships are used, often causing entire databases to be loaded during the initial request. Of course one could tediously examine each object relationship and manually remove those most costly, but in the end, we may be losing the ease of use benefit sought in using the ORM tool.

The obvious solution is to employ the lazy loading mechanism provided by hibernate. This initialization strategy only loads an object's one-to-many and many-to-many relationships when these fields are accessed. The scenario is practically transparent to the developer and a minimum amount of database requests are made, resulting in major performance gains. One drawback to this technique is that lazy loading requires the Hibernate session to remain open while the data object is in use. This causes a major problem when trying to abstract the persistence layer via the Data Access Object pattern. In order to fully abstract the persistence mechanism, all database logic, including opening and closing sessions, must not be performed in the application layer. Most often, this logic is concealed behind the DAO implementation classes which implement interface stubs. The quick and dirty solution is to forget the DAO pattern and include database connection logic in the application layer. This works for small applications but in large systems this can prove to be a major design flaw, hindering application extensibility.


Being Lazy in the Web Layer

Fortunately for us, the Spring Framework has developed an out of box web solution for using the DAO pattern in combination with Hibernate lazy loading. For anyone not familiar with using the Spring Framework in combination with Hibernate, I will not go into the details here, but I encourage you to read Hibernate Data Access with the Spring Framework. In the case of a web application, Spring comes with both the OpenSessionInViewFilter and the OpenSessionInViewInterceptor. One can use either one interchangeably as both serve the same function. The only difference between the two is the interceptor runs within the Spring container and is configured within the web application context while the Filter runs in front of Spring and is configured within the web.xml. Regardless of which one is used, they both open the hibernate session during the request binding this session to the current thread. Once bound to the thread, the open hibernate session can transparently be used within the DAO implementation classes. The session will remain open for the view allowing lazy access the database value objects. Once the view logic is complete, the hibernate session is closed either in the Filter doFilter method or the Interceptor postHandle method. Below is an example of the configuration of each component:

Interceptor Configuration

<beans> 
  <bean id="urlMapping"     
     class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">    
       <property name="interceptors">
         <list>
              <ref bean="openSessionInViewInterceptor"/>
         </list>
       </property>
       <property name="mappings">
  ...
  </bean>
  ...
  <bean name="openSessionInViewInterceptor"  
    class="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor">
       <property name="sessionFactory"><ref bean="sessionFactory"/></property>
  </bean>
</beans>
 

Filter Configuration

<web-app>
 ...      
  <filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>
      org.springframework.orm.hibernate.support.OpenSessionInViewFilter
    </filter-class>
   </filter>
  ...      
  <filter-mapping>
    <filter-name>hibernateFilter</filter-name>
     <url-pattern>*.spring</url-pattern>
  </filter-mapping>
  ...
</web-app>

Implementing the Hibernate DAO's to use the open session is simple. In fact, if you are already using the Spring Framework to implement your Hibernate DAO's, most likely you will not have to change a thing. The DAO's must access Hibernate through the convenient HibernateTemplate utility, which makes database access a piece of cake. Below is an example DAO.

Example DAO

public class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO  {      
 
       public Product getProduct(Integer productId) {
              return (Product)getHibernateTemplate().load(Product.class, productId);
       }
 
       public Integer saveProduct(Product product) {
              return (Integer) getHibernateTemplate().save(product);
       }       
 
       public void updateProduct(Product product) {
              getHibernateTemplate().update(product);
       }
 }

Being Lazy in the Business Layer

Even outside the view, the Spring Framework makes it easy to use lazy load initialization, through the AOP interceptor HibernateInterceptor. The hibernate interceptor transparently intercepts calls to any business object configured in the Spring application context, opening a hibernate session before the call, and closing the session afterward. Let's run through a quick example. Suppose we have an interface BusinessObject:

public interface BusinessObject { 
     public void doSomethingThatInvolvesDaos(); 
}</pre><p><font size="2">The class BusinessObjectImpl implements BusinessObject:</font></p>
<p />
<pre>public class BusinessObjectImpl implements BusinessObject {
    public void doSomethingThatInvolvesDaos() {
        // lots of logic that calls
        // DAO classes Which access 
        // data objects lazily
    }
}

Through some configurations in the Spring application context, we can instruct the HibernateInterceptor to intercept calls to the BusinessObjectImpl allowing it's methods to lazily access data objects. Take a look at the fragment below:

<beans>
    <bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
         <property name="sessionFactory">
           <ref bean="sessionFactory"/>
         </property>
    </bean>
    <bean id="businessObjectTarget" class="com.acompany.BusinessObjectImpl">
       <property name="someDAO"><ref bean="someDAO"/></property>
    </bean>
    <bean id="businessObject" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="target"><ref bean="businessObjectTarget"/></property>
         <property name="proxyInterfaces">
           <value>com.acompany.BusinessObject</value>
         </property>
         <property name="interceptorNames">
           <list>
              <value>hibernateInterceptor</value>
           </list>
         </property>
     </bean>            
</beans>
 
 

When the businessObject bean is referenced, the HibernateInterceptor opens a hibernate session and passes the call onto the BusinessObjectImpl. When the BusinessObjectImpl has finished executing, the HibernateInterceptor transparently closes the session. The application code has no knowledge of any persistence logic, yet it is still able to lazily access data objects.

Being Lazy in your Unit Tests

Last but not least, we'll need the ability to test our lazy application from J-Unit. This is easily done by overriding the setUp and tearDown methods of the TestCase class. I prefer to keep this code in a convenient abstract TestCase class for all of my tests to extend.

public abstract class MyLazyTestCase extends TestCase {
 
        private SessionFactory sessionFactory;
        private Session session;
	
        public void setUp() throws Exception {
	    super.setUp();
	    SessionFactory sessionFactory = (SessionFactory) getBean(\"sessionFactory&quot<img alt=";)" src="http://www.dflying.net/plugins/smileys/icons/default/wink_smile.gif" />;
	    session = SessionFactoryUtils.getSession(sessionFactory, true);
	    Session s = sessionFactory.openSession();
	    TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s));
 
        }
 
        protected Object getBean(String beanName) {
            //Code to get objects from Spring application context
        }
	
        public void tearDown() throws Exception {
	    super.tearDown();
	    SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
	    Session s = holder.getSession(); 
	    s.flush();
	    TransactionSynchronizationManager.unbindResource(sessionFactory);
	    SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory);
        }
}


文章来源:http://blueoxygen.dflying.net/3/archive/84_hibernate_performance_tuning.html

posted @ 2006-03-16 11:19 BlueO2 阅读(639) | 评论 (0)编辑 收藏

写了一些sample在我的Blog上面。还没入门的朋友可以看看
http://blueoxygen.dflying.net/3/archive/20_prototype_samples.html

posted @ 2006-03-16 11:18 BlueO2 阅读(259) | 评论 (0)编辑 收藏

为AJAX贴贴脸系列文章。第一篇为AJAX贴贴脸之入门篇。本示例部分操作利用了prototype类库,相关知识请查阅
示例为我们以前经常遇到过的动态列表问题,当选择一个下拉框的时候,另外一个的数据将动态产生。
result.jpg
这是个极其简单的应用。不过我们讲由简入繁,最后的示例会展现Google Suggest类型的自动提示。而且我们会不停的对整个示例重构,标题的1-1也表明有1-2等。
1-1是完全自己处理AJAX的各种问题,1-2预计引入其他类库来操作XML,1-3预计用buffalo完成此示例。之后每个示例如果有必要都会有此类对比。由于代码很简单并且有注释,所以文章以代码即可展现应用。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Dynamic List </title>
<meta name="Generator" content="EditPlus">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<script src="./script/prototype.js"></script>
<script>
var xmlHttp;    //XHR Object
function refreshBookList() {

   var bookCate = $F('bookCate');
   
//clear Books select box
   if(bookCate == ""){
    clearBookList();
    
return;
   }
   
//we use XML file directly for demonstrating.
   //In real application,you should generate *.xml file by server side
   var url;
   
if(bookCate == "SAP"){
    url 
= "./SAP.xml";
   }
else {
    url 
= "./SIEBEL.xml"
   }
   
var pars = "";
   
//Create a new XHR object
   xmlHttp = new Ajax.Request(url,{method: 'get',onComplete: handleListChange});
}
//remove list values of select box
function clearBookList() {
    
var books = $('bookList');
    
while(books.childNodes.length >0){
        books.removeChild(books.childNodes[
0]);
    }
}
//callback function
function handleListChange(originalRequest){
    clearBookList();
    
var books = $('bookList');
    
var results = originalRequest.responseXML;
    
var option = null;
    
var booksXML = results.getElementsByTagName("books")[0];
    
for(var i = 0; i < booksXML.childNodes.length;i++){
        
//get book tag
        var listItem = booksXML.childNodes[i];
        option 
= document.createElement('option');
        option.appendChild(document.createTextNode(listItem.firstChild.nodeValue));
        books.appendChild(option);
    }
}
</script>
</head>

<body>
<form  action="#">
    Book Categroies:
    
<select name="bookCate" id="bookCate" onchange="refreshBookList();">
        
<option>Select One</option>
        
<option value="SAP">SAP Books</option>
        
<option value="SIEBLE">SIEBEL Books</option>
    
</select>
    
<br/><br/>
    
<select name="bookList" id="bookList" size="6" style="width:300px"></select>
    
<br/>
</form>
</body>
</html>
SAP.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<books>
<book>
ABAP
</book>
<book>
BW
</book>
<book>
FI module
</book>
</books>
SIEBEL.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<books>
<book>
SIEBEL
</book>
<book>
CRM
</book>
</books>

posted @ 2006-02-23 14:52 BlueO2 阅读(327) | 评论 (0)编辑 收藏

AJAX与服务器端通讯,虽然XHR对象的介入使得我们可以异步处理用户请求,但是另外一个细节也暴露给我,我们如何与服务器统一通信的契约?

目前比较公认的有三种数据传输交互方式:XHTML Fragment,JSON,XML。当然也有不同的声音,这里也会介绍。

  • XHTML片断
这种方式也被称为AHAH, 目前很多遗留系统想沾AJAX的光改善一下交互,节省一下带宽,大多数采用了此种方式。我们以 Struts为例子,比如在页面上有一个按钮,点击后得到现在我收藏的图书列表,则此图书列表(Table元素组成)便可以以XHTML片断的形式返回客户端,然后利用XHR对象的responseText属性得到,设知道某DIV中。
for (Iterator it = sortedPresidentsList.iterator(); it.hasNext();) {
HashMap hm 
= (HashMap)it.next();
html 
+= "<tr>";
html 
+= "<td>" + (String)hm.get("firstName"+ "</td>";
html 
+= "<td>" + (String)hm.get("middleName"+ "</td>";
html 
+= "<td>" + (String)hm.get("lastName"+ "</td>";
html 
+= "<td>" + (String)hm.get("firstYearInOffice"+ "</td>";
html 
+= "<td>" + (String)hm.get("lastYearInOffice"+ "</td>";
html 
+= "</tr>";
}

html 
+= "</table>";

// Write the HTML to response
response.setContentType("text/html");
PrintWriter out 
= response.getWriter();
out.println(html);
out.flush();

    这是一个Struts的例子,Action中response直接flush输出。当然也可以让Struts导向到结果jsp页面,请求的XHR可以得到jsp生成的HTML内容。
    缺点是:当返回有Form的内容的时候会崩溃。CSS样式设置复杂。

    • XML

    XML在很多AJAX示例当中作为数据传递的标准。而XML具有很好的数据语义描述性,服务器端生成方式众多,而几乎所有浏览器都支持对XML 的解析。以JavaScript解析服务器端返回的XML为例子,只需要XHR的responseXML属性即可获得XML由javascript解析 (请看我在BlogJAVA写的操作示例) 而XML的产生方式似乎所有人都认准了

    <channel>

    <title>Dan's Data</title>
    <description>New and interesting computer hardware, gadgets and toys reviewed. And letters. Lots of letters.</description>
    <link>http://www.dansdata.com/</link>

    <item>
    <title>Ultrasone HFI-650 headphones</title>
    <description>They look like the 550s, they feel like the 550s, they've got marketing buzzwords like the 550s - are they worth the extra money?</description>
    <link>http://www.dansdata.com/quickshot025.htm</link>
    </item>..


    一类,似乎这样子语义描述更清楚。但是我从michael那里得到启示,确实,用此类方式传输数据几乎无法在客户端统一处理。从我的showcase中大家也可以看到,Javascript解析XML后更新DOM简直就是体力活,枯燥且容易出错,而此种XML返回的数据则会千差万别,以寻找特定tag的节点的方式怎么能统一处理呢?于是,第二种XML传输方式应运而生。

    <list>
    <type>java.util.List</type>
    <map>
    <type>yourapp.domain.Book</type>
    <string>title</string>
    <string>JavaScript, the Definitive Guide</string>
    <string>publisher</string>
    <string>O'Reilly</string>
    <string>author</string>
    <string>David Flanagan</string>
    <string>cover</string>
    <string>/images/cover_defguide.jpg</string>
    <string>blurb</string>
    <string>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</string>
    </map>
    <map>
    <type>yourapp.domain.Book</type>
    <string>title</string>
    <string>DOM Scripting</string>
    <string>publisher</string>
    <string>Friends of Ed</string>
    <string>author</string>
    <string>Jeremy Keith</string>
    <string>cover</string>
    <string>/images/cover_domscripting.jpg</string>
    <string>blurb</string>
    <string>Praesent et diam a ligula facilisis venenatis.</string>
    </map>
    </list>

    这样子只要客户端和服务器端达成共识string long int等代表的数据类型就可以在两端还原成自己可用的对象。而这也是micheal认为真正的AJAX应该有的形态,其中AJAX引擎便承担起了这份工作。
    缺点:XML的构造和解析在没有类库辅助的情形下是一个灾难,而XML文件的传输效率似乎也不如简单的文本高。我讲会在后面的blog中提及XML文件的产生方法,以及客户端一些解析的框架。

    • JSON

    JSON是JavaScript Object Notation的缩写,是一份规范,定义了极其简单的数据描述形式。几乎在所有主流语言上都有实现。JSON对象是名/值对的集合,所以一个简单的JSON对象为:
    var testObj={
    "name" : david,
    "sex" : Male,
    "work" : SE
    }
    客户端javascript调用eval()就可以解析由服务器端产生的JSON串。var jsonExpression =
    ( + req.responseText + );
    var customer = eval(jsonExpression);
    而服务器端(JAVA)也有相应的lib来操作:JSONObject 的toString()
    缺点:虽然JSON简洁高效,但是转化为Javascript对象通过eval()也就是说,AJAX的传输邦定在了JSON上面,这样,总会让人不很放心。并且JSON对象难于阅读与理解,不如XML直观。

    除了会在下一篇AJAX的blog介绍JAVA对象序列化到XML以外,会一些从头开始构建应用的例子,其中不会使用buffalo DWR一类的框架,我会尝试选用不同的方案作为数据传输方式供大家参考。

    posted @ 2006-02-23 11:15 BlueO2 阅读(482) | 评论 (0)编辑 收藏

     总结了Hibernate中实体对象与数据的映射方式……图文并茂,配置实例代码,为david吃饱了撑着之大作。

    1 Entity's relation

    1.1 One to One

    一个对象的一个实例对应另一个对象的一个实例从数据库角度描述,一个表中的一条记录对应另外一个表中唯一一条记录

    public class Image{
    private Long id;
    private String imgName;
    private Blog value; //to store binary of image
    ......
    }
    Image.hbm.xml
    <class name="Image" dynamic-update="true">
    <id...
    <property...
    </class>

    public class Product{
    private Long id;
    private String name;
    private double price;
    private Image photo;
    }
    <class name=...dynamic-update="true" lazy="true"
    <id...
    <property...
    <one-to-one name="photo" class="package.Image" cascade="all" outer-join="auto" constrained="false"/>
    </class>

    1.2 Many to One

    一个对象对应另一个对象的多个实例,从数据库角度描述,是在一个数据表中的一条记录对应另外一个数据表中对条记录.

    public class PersonalCompute{
    private Long computerId;
    private String cpu;
    ......
    private Programmer owner;
    }
    <class name="Programmer" table="Programmer">
    <id...
    <property...
    </class>

    <class name="PersonalCompute" table="PCS">
    <id....
    <property...
    <many-to-one name="owner" column="programmerId" class="Programmer">
    </many-to-one>

    1.3 One to Many

    The same example as Many to One.But we stand at Programmer class's view point.
    public class Programmer{
    ...
    private Set computers = new HashSet();
    }

    <class name="Programmer" table="Programmer">
    <id...
    <property...
    <set name="computers" inverse="true"
    cascade="all">
    <key column="programmerId" />
    <one-to-many class="PersonalComputers">
    </one-to-many>
    </set>

    2 Collection

    2.1 Map

    <class name="Team">
    ...
    <map name="members">
    <key foreign-key="fk">
    <column name="teamNumber">
    </key>
    <index column="teamRole" type="string"/>
    <element column="name" ...
    </map>


    showcase:
    Team team1 = new Team();
    team1.setName(xx);
    team1.getMembers.put("index","content");
    ......
    sess.save...

    2.1.1 many-to-any

    2.1.2 One to many

    单单使用Map做存储往往无法表达复杂的对象,如果要讲对象 map进行映射:
    One Team,multi-members
    Public class Member{
    ...
    private Team team;
    }
    <class name="Team">
    ...
    <map name="members" inverse="false">
    <key column="team" foreign-key="fk"/>
    <index type="string" column="teamRole"/>
    <one-to-many class="Member"/>
    </map>
    <class name="member">
    <id...
    <property...
    <many-to-one name="team" />

    showcase:
    Team team = new Team();
    team.setName("xx");
    Member mem1 = new Member();
    mem1.setXX
    mem1.setXX
    Member mem2 = new Member();
    mem2.setXX
    mem2.setXX
    team.getMembers().put("xx",mem1);
    team.getMembers().put("xx2",mem2);

    2.1.3 many to many

    <class name="Team">
    <id
    <propery
    <map name="members" inverse="false" table="teamHasMembers">
    <key column="team" foreign-key="fk"/>
    <index type="string" column="teamRole"/>
    <many-to-many class="member" outer-join="auto">
    <column name="member"/>
    </many-to-many>
    </map>

    <class name="Member">
    <id
    <property
    <map name="teams" table="memberAtTeams">
    <key....

    teamRole is their common key of Map.
    Team

    id

    name

    2

    team2

    Member

    di

    name

    age

    1

    davy

    23

    memberAtTeams

    member

    team

    teamRole

    1

    2

    coach

    teamHasMembers

    team

    member

    teamRole

    2

    1

    coach

    2.1.4 Composite-index

    Index 可以是一个类。
    public class Position{
    private String role;
    private String scene;
    public Position()....
    getter...
    setter...
    }
    <class name="Team">
    <id...
    <property...
    <map name="members" inverse="false">
    <key column="team" foreign-key="fk"/>
    <composite-index class="Position">
    <key-property..
    <key-property...
    </composite-index>
    <one-to-many class="Member"/>
    </map>
    ...

    <class name="Member">
    <id...
    <property...
    <many-to-one name="team"/>
    </class>

    index-many-to-one

    index-many-to-many

    index-many-to-any

    2.1.5 composite-element

    <import class="Member"/>
    <class name="Team">
    <id...
    <property...
    <map name="members" table="teamMembers">
    <key column="teamId"/>
    <index...
    <composite-element class="Member">
    <parent name="parent"/>
    <property...
    <property...
    </composite-element>
    </map>

    2.2 Set

    <class name="Team">
    <..
    <set name="members" inverse="false">
    <key column="team" foreign-key="fk"/>
    <elemnet column="name" type="string"/>
    </set>

    2.2.1 one-to-many

    <set name="xx" column="">
    <key column="" foreign-key="fk"/>
    <one-to-many class="BB"/>
    </set>

    2.2.2 many-to-many

    <class name="Team">
    <id..
    <property...
    <set name="members" inverse="false" table="teamHasMembers">
    <key column="team" foreign-key="fk">
    <many-to-many class="Member" outer-join="auto">
    <column name="member"/>
    </set>
    </class>

    <class name="Member">
    <id..
    <property...
    <set name="members" inverse="true" table="memberAtTeams">
    <key column="member" foreign-key="fk">
    <many-to-many class="Member" outer-join="auto">
    <column name="team"/>
    </set>
    </class>

    2.2.3 many-to-any

    2.2.4 composite-element

    2.3 List

    <list name="members" inverse="false">
    <key column="team" foreign-key="fk"/>
    <index column="teamMember"/>
    <element column="name" type="string"/>
    </list>

    2.3.1 one-to-many

    2.3.2 many-to-many

    2.3.3 many-to-many

    2.3.4 composite-element

    2.4 Bag

    It can contains JDK's Collection and List interface type's object.

    2.5 idBag

    bag相比多出了collection-id属性

    <ibdbag name="">
    <collection-id column="mbid" type="long">
    <generator class="hilo"/>
    </collection-id>
    <key..
    <element..
    </idbag>

    2.6 array

    public class Team{
    //...
    private String[] members;
    }

    <array name="members" inverse="false">
    <key column="team" foreign-key="fk"/>
    <index column="teamNumber"/>
    <element column="name" type="string"/>
    </array>

    3 Component

    <class name="Country">
    <id..
    <property...
    <component name="position">
    <property...
    </component>
    Public class Country{
    //..
    private Position position;
    }

    3.1 One-to-one

    3.2 many-to-one

    3.3 dynamic-component

    4 Dynamic class

    <dynamic-class entity-name="Country">
    <id name="id" type="long">
    <generator class="hilo"/>
    </id>
    <property name="name" column="NAME" type="string"/>
    </..

    4.1 One-to-one

    4.2 many-to-one

    5 Mapping type

    5.1 Java type to SQL type

    5.2 3.0 enmu

    5.3 user defined data type

    need implements org.hibernate.usertype.CompositeUserType or org.hibernate.usertype.UserType interface.

    6 Class Hierarchy's mapping

    6.1 Subclasses are saved in on Table

    6.1.1 discriminator

    Sapmle:

    Class AbstractParent{
    String id;
    /*important*/
    String discriminator
    }
    Class ChildA{
    String childA;
    }
    Class ChildB{
    String childB;
    }

    =========DB=========

    colum name

    data type

    memo

    id

    varchar

    childA

    varchar

    childB

    varchar

    class_type

    varchar

    used to identify subclass:A B

    ========mapping config file====
    <class name="AbstractParent" table="PARENT" abstract="true">
    <id...
    <discriminator column="CLASS_TYPE" type="string"/>
    <property......
    <subclass name="ChildA" discriminator-value="A">
    <property name="childA"/>
    </subclass>
    <subclass......

    id generator

    · increment

    · identity

    · sequence

    · hilo

    · seqhilo

    · uuid

    · guid

    · native

    · assigned

    · foreign

    composite id

    <composite-id>
    <key-property name=""/>
    <key-property name=""/>
    </composite-id>

    6.2 Subclasses are saved in separated Table

    不为父类Container建立映射文件 BoxBottle的映射文件也如没有关系一样普通的建立 但是对Container取得操作

    List pcs = sess.createQuery("from com.be.david.Container").list();
    if(!cs.isEmpty()){
    ...
    }
    会将BoxContainer数据都取出来 这是Hibernate默认隐式完成的

    6.3 Parent Class and Subclasses are saved in separated Table

    <class name="Container" table="CONTAINER">
    <id...
    <property...
    <joined-subclass name="Box" table="CONTAINER_BOX">
    <key column="ContainerId"/>
    <property...
    </joined-subclass>
    <joined-subclass name="Bottle" table="CONTAINER_BOTTLE">
    <key...
    <property...
    </joined-subclass>
    </class>

    6.4 One PO multi-table

    public Class Person{
    牋牋燬tring id;
    牋牋燬tring name;
    牋牋燬tring sex;
    牋牋燬tring address;
    牋牋燬tring city;
    牋牋燬tring zipcode;
    }
    we wanna save address related attributes(blue ones).Use join
    <class name="Person" table="PERSON">
    <id...
    <property ...
    <join table="ADDRESS">
    <key column="addressID"/>
    <property name="address"/>
    ...
    </join>
    </class>

    6.5 Class A Class B not inherited from Parent Class

    6.5.1 subselect

    We can use subselct to make ChildA and ChildB standalone.So how can we get all data including ChindA and ChildB?

    <class name="ChildA" table="parent">
    <id...
    <property...
    </class>
    <class name="ChildB" table="parent">
    <id...
    <property...
    </class>
    <class name="Parent" mutable="false">
    <subselect>
    select * from ChildA
    union
    select * from ChildB
    </subselect>
    <sychronize table="ChildA"/>
    <sychronize table="ChildB"/>
    <id...
    <property...
    </class>

    posted @ 2006-02-22 12:45 BlueO2 阅读(964) | 评论 (0)编辑 收藏

         摘要: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE> New Document </TITLE><META NAME="Ge...  阅读全文

    posted @ 2006-02-15 22:58 BlueO2 阅读(924) | 评论 (0)编辑 收藏

    虽然struts上传下载文件很简单,但是封装一下还是好地。
    /*
    * $Id: DownloadAction.java 164530 2005-04-25 03:11:07Z niallp $
    *
    * Copyright 2004-2005 The Apache Software Foundation.
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *      http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */



    package org.apache.struts.actions;

    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;

    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.apache.struts.action.Action;
    import org.apache.struts.action.ActionForm;
    import org.apache.struts.action.ActionForward;
    import org.apache.struts.action.ActionMapping;


    /**
    * This is an abstract base class that minimizes the amount of special coding
    * that needs to be written to download a file. All that is required to use
    * this class is to extend it and implement the <code>getStreamInfo()</code>
    * method so that it returns the relevant information for the file (or other
    * stream) to be downloaded. Optionally, the <code>getBufferSize()</code>
    * method may be overridden to customize the size of the buffer used to
    * transfer the file.
    *
    * @since Struts 1.2.6
    */

    public abstract class DownloadAction extends Action {

        /**
         * If the <code>getBufferSize()</code> method is not overridden, this is
         * the buffer size that will be used to transfer the data to the servlet
         * output stream.
         */

        protected static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

        /**
         * Returns the information on the file, or other stream, to be downloaded
         * by this action. This method must be implemented by an extending class.
         *
         * @param mapping  The ActionMapping used to select this instance.
         * @param form     The optional ActionForm bean for this request (if any).
         * @param request  The HTTP request we are processing.
         * @param response The HTTP response we are creating.
         *
         * @return The information for the file to be downloaded.
         *
         * @throws Exception if an exception occurs.
         */

        protected abstract StreamInfo getStreamInfo(ActionMapping mapping,
                ActionForm form, HttpServletRequest request,
                HttpServletResponse response)
                throws Exception;

        /**
         * Returns the size of the buffer to be used in transferring the data to
         * the servlet output stream. This method may be overridden by an extending
         * class in order to customize the buffer size.
         *
         * @return The size of the transfer buffer, in bytes.
         */

        protected int getBufferSize() {
            return DEFAULT_BUFFER_SIZE;
        }

        /**
         * Process the specified HTTP request, and create the corresponding HTTP
         * response (or forward to another web component that will create it).
         * Return an <code>ActionForward</code> instance describing where and how
         * control should be forwarded, or <code>null</code> if the response has
         * already been completed.
         *
         * @param mapping  The ActionMapping used to select this instance.
         * @param form     The optional ActionForm bean for this request (if any).
         * @param request  The HTTP request we are processing.
         * @param response The HTTP response we are creating.
         *
         * @throws Exception if an exception occurs.
         */

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

            StreamInfo info = getStreamInfo(mapping, form, request, response);
            String contentType = info.getContentType();
            InputStream stream = info.getInputStream();

            try {
                response.setContentType(contentType);
                copy(stream, response.getOutputStream());
            } finally {
                if (stream != null) {
                    stream.close();
                }
            }

            // Tell Struts that we are done with the response.
            return null;
        }

        /**
         * Copy bytes from an <code>InputStream</code> to an
         * <code>OutputStream</code>.
         *
         * @param input  The <code>InputStream</code> to read from.
         * @param output The <code>OutputStream</code> to write to.
         *
         * @return the number of bytes copied
         *
         * @throws IOException In case of an I/O problem
         */

        public int copy(InputStream input, OutputStream output)
                throws IOException {
            byte[] buffer = new byte[getBufferSize()];
            int count = 0;
            int n = 0;
            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
                count += n;
            }
            return count;
        }

        /**
         * The information on a file, or other stream, to be downloaded by the
         * <code>DownloadAction</code>.
         */

        public static interface StreamInfo {

            /**
             * Returns the content type of the stream to be downloaded.
             *
             * @return The content type of the stream.
             */

            public abstract String getContentType();

            /**
             * Returns an input stream on the content to be downloaded. This stream
             * will be closed by the <code>DownloadAction</code>.
             *
             * @return The input stream for the content to be downloaded.
             */

            public abstract InputStream getInputStream() throws IOException;
        }

        /**
         * A concrete implementation of the <code>StreamInfo</code> interface which
         * simplifies the downloading of a file from the disk.
         */

        public static class FileStreamInfo implements StreamInfo {

            /**
             * The content type for this stream.
             */

            private String contentType;

            /**
             * The file to be downloaded.
             */

            private File file;

            /**
             * Constructs an instance of this class, based on the supplied
             * parameters.
             *
             * @param contentType The content type of the file.
             * @param file        The file to be downloaded.
             */

            public FileStreamInfo(String contentType, File file) {
                this.contentType = contentType;
                this.file = file;
            }

            /**
             * Returns the content type of the stream to be downloaded.
             *
             * @return The content type of the stream.
             */

            public String getContentType() {
                return this.contentType;
            }

            /**
             * Returns an input stream on the file to be downloaded. This stream
             * will be closed by the <code>DownloadAction</code>.
             *
             * @return The input stream for the file to be downloaded.
             */

            public InputStream getInputStream() throws IOException {
                FileInputStream fis = new FileInputStream(file);
                BufferedInputStream bis = new BufferedInputStream(fis);
                return bis;
            }
        }

        /**
         * A concrete implementation of the <code>StreamInfo</code> interface which
         * simplifies the downloading of a web application resource.
         */

        public static class ResourceStreamInfo implements StreamInfo {

            /**
             * The content type for this stream.
             */

            private String contentType;

            /**
             * The servlet context for the resource to be downloaded.
             */

            private ServletContext context;

            /**
             * The path to the resource to be downloaded.
             */

            private String path;

            /**
             * Constructs an instance of this class, based on the supplied
             * parameters.
             *
             * @param contentType The content type of the file.
             * @param context     The servlet context for the resource.
             * @param path        The path to the resource to be downloaded.
             */

            public ResourceStreamInfo(String contentType, ServletContext context,
                    String path) {
                this.contentType = contentType;
                this.context = context;
                this.path = path;
            }

            /**
             * Returns the content type of the stream to be downloaded.
             *
             * @return The content type of the stream.
             */

            public String getContentType() {
                return this.contentType;
            }

            /**
             * Returns an input stream on the resource to be downloaded. This stream
             * will be closed by the <code>DownloadAction</code>.
             *
             * @return The input stream for the resource to be downloaded.
             */

            public InputStream getInputStream() throws IOException {
                return context.getResourceAsStream(path);
            }
        }
    }

    posted @ 2005-12-07 17:21 BlueO2 阅读(699) | 评论 (1)编辑 收藏

    仅列出标题
    共3页: 上一页 1 2 3 下一页 

    posts - 29, comments - 3, trackbacks - 0, articles - 0

    Copyright © BlueO2