在Struts1.1-1.2中如果不想沒有登錄的用戶訪問一些action,可以擴(kuò)展RequestProcessor,并重載processProprocess方法,在其中進(jìn)行驗(yàn)證
public class CustomRequestProcessor
extends RequestProcessor {
protected boolean processPreprocess (
HttpServletRequest request,
HttpServletResponse response) {
HttpSession session = request.getSession(false);
//If user is trying to access login page
// then don't check
if( request.getServletPath().equals("/loginInput.do")
|| request.getServletPath().equals("/login.do") )
return true;
//Check if userName attribute is there is session.
//If so, it means user has allready logged in
if( session != null &&
session.getAttribute("userName") != null)
return true;
else{
try{
//If no redirect user to login Page
request.getRequestDispatcher
("/Login.jsp").forward(request,response);
}catch(Exception ex){
}
}
return false;
}
}
相應(yīng)的,在struts-config.xml中加入controller元素
<controller>
<set-property property="processorClass"
value="com.sample.util.CustomRequestProcessor"/>
</controller>
但剛才看到在Struts1.3中,已經(jīng)不再使用RequestProcessor,而是用ComposableRequestProcessor 來實(shí)現(xiàn)自定義的request響應(yīng)。
三個(gè)@Entity類Tc, Tracer, Track是三向關(guān)聯(lián)的的表, @Embeddable類TcTracer則存儲(chǔ)著三個(gè)表的ForeignKey
@Entity
@Table(name= "tc", catalog="first_hiber")
public class Tc {
@org.hibernate.annotations.CollectionOfElements
@JoinTable(name="tc_tracer", joinColumns=@JoinColumn(name="tc_id"))
private Set<TcTracer> tcTracers = new HashSet<TcTracer>();
@Id @GeneratedValue
@Column(name="tc_id", nullable= false)
private Long id;
}
@Embeddable
@Table(name="tc_tracer")
public class TcTracer {
@org.hibernate.annotations.Parent
private Tc tc;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="tracer_id", nullable=false, updatable=false)
private Tracer tracer;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="track_id", nullable=false, updatable=false)
private Track track;
}
如上,將TcTracer作為Tc的子元素,從而實(shí)現(xiàn)Tc的三相關(guān)聯(lián)。
用HQL可以通過特定的Tc,Tracer得到對(duì)應(yīng)的所有Track:
select tctracers.track
from Tc tc
join tc.tcTracers tctracers
where tc.name="tc name"
and tctracers.tracer.name="tracer name"
List<Track> tracks = session.createQuery(HQL).list();
今天調(diào)試程序的時(shí)候,發(fā)現(xiàn)插入數(shù)據(jù)時(shí)老是拋出異常:"a different object with the same identifier value was already associated with the session"
起初以為是override hashCode()的方法不對(duì)。后來google查了查多數(shù)問題都出現(xiàn)在detached對(duì)象之后,再鏈接session由于對(duì)象的改變而出現(xiàn)的異常。
最后發(fā)現(xiàn)原來問題很簡單....是在用annotation重寫mapping的時(shí)候,忘記給@Id加上@GeneratedValue,導(dǎo)致第一個(gè)row insert后,再次insert時(shí)沒有生成新的id!
看來annotation雖然方便了mapping,但由于和代碼集中在一塊了,很容易出現(xiàn)疏忽大意的錯(cuò)誤,而且一般都不會(huì)注意到-.-
想起了python的SQLObject, SQLAlchemy,雖然功能沒有Hibernate豐富,但是簡單實(shí)用!
通常為了實(shí)現(xiàn)entity class的雙向association,每添加一組實(shí)例在java中需要兩行代碼:
persion.getAddresses().add(address);
address.getPersons().add(person);
但對(duì)Hibernate而已,上面的代碼會(huì)被轉(zhuǎn)化為兩條insert語句,
為了避免這樣的情況出現(xiàn)需要定義inverse屬性,告訴Hibernate persion和address之間的關(guān)系:
// !file: Person.class
public class Person {
// ...
@ManyToMany(
targetEntity= Address.class,
cascade = CascadeType.ALL,
)
@JoinTable(
name="persion_address",
joinColumns= {@JoinColumn(name="person_id")},
inverseJoinColumns= {@JoinColumn(name="address_id")}
)
private Set<Address> adressses = new HashSet<Address> (0);
// ...
}
// !file: Address.class
public class Address {
// ...
@ManyToMany(
targetEntity= Persion.class,
cascade = CascadeType.ALL,
mappedBy = "addresses"
)
private Set<Person> persons = new HashSet<Person>();
// ...
}
上面的兩個(gè)annotation告訴Hibernate,Person是主,對(duì)Address中persons屬性的修改將不會(huì)產(chǎn)生SQL語句。
Hibernate里,如果是Many-to-many的關(guān)系,可以任意設(shè)置主class。
通常,還可以將添加刪除關(guān)系的代碼包裝起來:
// !file: Person.class
public class Person {
// ...
public void addAddress(Address address) {
this.getAddresses().add(address);
address.getPersons().add(this);
}
public void removeAddress(Address address) {
this.getAddresses().remove(address);
address.getPersons().remove(this);
}
//...
}
http://www.box.net/shared/102b5irypc
差不多把平時(shí)用的上的讀完了,真感覺受益匪淺。不但詳細(xì)的介紹了Hibernate的特性用法,而且其中介紹的ORM基本概念,灌輸?shù)腛RM的思想也正是我所需要的。
對(duì)一個(gè)新手來說,business key, surrogate key, entity type, value type, transient, persistent, detached, persistence context...這些是什么概念,為什么要提出來,以及怎樣實(shí)現(xiàn)的在書中都會(huì)有簡單明了的解釋。
不多說了,現(xiàn)在把書放出來,誰看誰知道;)
posted @
2007-03-23 08:21 hijeff 閱讀(2291) |
評(píng)論 (7) |
編輯 收藏
之前都是用最蠢的方法:SQL建立數(shù)據(jù)庫相關(guān)的表,然后再Java寫映射寫配置文件.....
實(shí)際上使用Hibernate自帶的工具hbm2ddl,建立根據(jù)你的對(duì)象建立數(shù)據(jù)庫是很愜意的一件事;)
首先當(dāng)然要建好POJO object, XML Mapping File(也可以使用工具根據(jù)POJO class建立),配置文件(hibernate.cfg.xml)
然后運(yùn)行下面的Java代碼
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class SchemaUtil {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SchemaExport schemaExport= new SchemaExport(cfg);
schemaExport.create(false, true);
}
}
再看看數(shù)據(jù)庫,表是不是已經(jīng)幫你建好了,對(duì)于我這樣不熟悉數(shù)據(jù)庫的人真是太方便了
Technorati : Hibernate, Java, database, persistence
Del.icio.us : Hibernate, Java, database, persistence
posted @
2007-03-21 00:56 hijeff 閱讀(5280) |
評(píng)論 (4) |
編輯 收藏
內(nèi)容詳實(shí),通俗易懂
決定花幾天時(shí)間好好的讀讀這本書,系統(tǒng)的學(xué)習(xí)Hibernate。
Technorati : Hibernate, Java, Persistence
Del.icio.us : Hibernate, Java, Persistence
Set set = new HashSet(Arrays.asList(array));
Web程序的編碼問題主要有三個(gè)方面:
- 程序文件的編碼;
- 輸出頁面到客戶端的編碼;
- 用戶響應(yīng)到服務(wù)器端的編碼。
以設(shè)置為UTF-8為例,可以用如下方法解決。
1. 對(duì)于程序文件的編碼
直接在Eclipse或者其他IDE,editor中將文件編碼設(shè)為UTF-8即可。
2.輸出頁面
對(duì)于JSP頁面,加入以下代碼
<%@ page contentType="text/html; charset=UTF-8"%>
如果在IE或者Firefox中還不能正常顯示,還可以在Html標(biāo)識(shí)下加入下面的頭信息
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
3. 響應(yīng)到服務(wù)器端
我使用的是Tomcat,沒有可以直接設(shè)置接受響應(yīng)編碼的方法(真是太佩服了!),但可以通過寫一個(gè)Filter實(shí)現(xiàn)編碼轉(zhuǎn)化。
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SetCharacterEncodingFilter implements Filter {
protected String encoding = null;
protected FilterConfig filterConfig = null;
protected boolean ignore = true;
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
if (ignore || (request.getCharacterEncoding() == null)) {
String encoding = selectEncoding(request);
if (encoding != null)
request.setCharacterEncoding(encoding);
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
String value = filterConfig.getInitParameter("ignore");
if (value == null)
this.ignore = true;
else if (value.equalsIgnoreCase("true"))
this.ignore = true;
else if (value.equalsIgnoreCase("yes"))
this.ignore = true;
else
this.ignore = false;
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding);
}
}
將SetCharacterEncodingFilter放到程序的編譯目錄下,再在web.xml中添加相應(yīng)屬性
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>hijeff.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Tomcat就會(huì)將用戶通過HTTP響應(yīng)的字符轉(zhuǎn)化為UTF-8的編碼了
via
- Pass an instance of java.util.Properties to Configuration.setProperties().
- Place hibernate.properties in a root directory of the classpath.
- Set System properties using java -Dproperty=value.
- Include <property> elements in hibernate.cfg.xml .