亚洲欧洲日产韩国在线,亚洲一久久久久久久久,亚洲AV无码之国产精品http://www.tkk7.com/lonun/zh-cnSat, 10 May 2025 12:11:26 GMTSat, 10 May 2025 12:11:26 GMT60基于Struts2+Spring+JPA的添刪改查示例http://www.tkk7.com/lonun/archive/2008/04/02/190296.html天 一天 一Wed, 02 Apr 2008 02:44:00 GMThttp://www.tkk7.com/lonun/archive/2008/04/02/190296.htmlhttp://www.tkk7.com/lonun/comments/190296.htmlhttp://www.tkk7.com/lonun/archive/2008/04/02/190296.html#Feedback6http://www.tkk7.com/lonun/comments/commentRss/190296.htmlhttp://www.tkk7.com/lonun/services/trackbacks/190296.html 

一、新建項目
先在eclipse中新建一個maven項目,如下圖:

填寫id、version等,點finish。項目就建好了。下面是項目建好之后的樣子:

二、配置環境

1、添加依賴包

選中項目,右鍵——Maven2——Add Dependency,如下圖:

打開添加依賴包界面后添加包:struts2.0.11、spring2.0.6、hibernate-annotations3.2、hibernate-entitymanager3.2、hibernate3.2、servlet2.4、javax-persistence、mysql-connector-java5.0.4、spring-aop2.0.6、aspectjweaver1.5.3、struts2-spring-plugin2.0.11、junit、spring-mock2.0.6。

2、配置web.xml文件

在WEB-INF下新建文件web.xml
輸入如下內容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Struts 2</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

用過struts1.x的人會發現這里沒有了servlet,而是一個filter,是的,這是struts2和struts1的一個不同之處。

在src/main/resource下新建文件struts.xml,這里是和struts1.x不一樣的地方。
輸入如下內容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="Struts2_MESSAGE" extends="struts-default"
namespace="/message">
</package>
</struts>

簡單解釋一下,constant的作用是自定義一些struts2的屬性,在struts2的包里帶了一個struts.properties文件,里邊設定了很多默認的struts2的運行參數,但是這些有時候是需要改變一下的,因此就提供了constant來覆蓋struts.properties中屬性。而package的作用可以簡單的看做把應用分模塊。package有個屬性叫namespace,上面我們配置為/message,假設這個package中還有一個名叫hello的action,那么我們訪問這個action的url就是:http://域名/message.hello.action。

本文的示例程序是一個簡單的留言添刪改查,所以取名叫message。

3、配置spring

在WEB-INF下新建文件applicationContext.xml,輸入如下內容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
</beans>

在web.xml文件中加入如下內容:

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

 用過spring的人應該知道這個listener的作用是啟動spring容器。

4、配置jpa和spring的jpa支持

在src/main/resource下新建文件夾META-INF,然后在這個文件夾中新建文件persistence.xml,輸入如下內容:

<?xml version="1.0" encoding="utf-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="app-unit"
transaction-type="RESOURCE_LOCAL">
</persistence-unit>
</persistence>

可能有人會發現,怎么jpa的配置文件只有這么點了,這其實是因為我們用的spring的jpa支持,數據庫配置信息都放到spring的配置文件里了,后面就會看到。

然后打開前面新建的文件applicationContext.xml,在beans節點內添加如下內容:

<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost/message?createDatabaseIfNotExist=true" />
<property name="username" value="root" />
<property name="password" value="123" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="generateDdl" value="false" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>

看,數據庫配置信息出現了

這里的username和password需要根據你的實際情況修改。

5、集成struts2和spring

打開struts.xml文件,添加如下內容:

<constant name="struts.objectFactory" value="spring" />
<constant name="struts.objectFactory.spring.autoWire" value="type" />

 到這里,配置基本完成。

三、新建域模型

我們先創建一個域模型Message,包括name、title、ip、content、inputTime等字段,代碼如下:

package com.struts.sample.domain;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
private String name;
private String title;
private String ip;
private String content;
private Date inputTime;
getter and setter...
}

@Entity是jpa的注解,表示這個類與一個表對應,如果沒有知名表明,那么就和message這個表對應,系統啟動是jpa會自動創建這個表。
@Id也是jpa注解,標識這個字段是主鍵。
@GeneratedValue(strategy = GenerationType.TABLE)是指定一個主鍵生成策略。

四、Service層的實現

接口就不帖出來了,直接把實現類寫出來。

package com.struts.sample.service;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.struts.sample.domain.Message;
public class MessageServiceImpl implements MessageService {
@PersistenceContext EntityManager em;
public void setEm(EntityManager em) {
this.em = em;
}
public List<Message> find(final String queryString, final int rowStartIdx, final int rowCount,
final Object... values){
Query query = em.createQuery(queryString);
if (values != null)
for (int i = 0; i < values.length; i++)
query.setParameter(i + 1, values[i]);
if(rowStartIdx>0){
query.setFirstResult(rowCount);
}
if(rowCount>0){
query.setMaxResults(rowCount);
}
return query.getResultList();
}
public void save(Message msg){
this.em.persist(msg);
}
public void del(Long id){
this.em.remove(this.get(id));
}
public Message get(Long id){
return this.em.find(Message.class, id);
}
public void update(Message msg){
this.em.merge(msg);
}
public Message getBy(String field, Object value) {
String queryString = "select msg from Message msg where msg."+field+"=:value";
Query query = this.em.createQuery(queryString).setParameter("value", value);
List<Message> msgs = query.getResultList();
if(msgs.size()>1){
throw new java.lang.IllegalStateException(
"worning  --more than one object find!!");
}else if(msgs.size()==1){
return msgs.get(0);
}else{
return null;
}
}
}

注意這一句@PersistenceContext EntityManager em;容器啟動的時候會去創建messageService,創建的時候會發現這個注解:@PersistenceContext,然后容器會把EntityManager注入到這里。
接下來我們需要讓spring知道我們有這樣一個bean需要它來加載。打開配置文件applicationContext.xml,加上如下內容:

<bean id="messageService" class="com.struts.sample.service.MessageServiceImpl" />

現在我們來寫測試用例,spring為我們測試jpa提供了一個基類:org.springframework.test.jpa.AbstractJpaTests。
首先,我們在src/test/resource目錄下新建一個文件applicationContext.xml,內容與src/main/resource/applicationContext.xml的內容一樣。
接下來我們寫一個測試用例AbstractJpaTests ,代碼如下:

package com.struts.sample.service;
import java.util.Date;
import org.springframework.test.jpa.AbstractJpaTests;
import com.struts.sample.domain.Message;
public class MessageServiceImplTest extends AbstractJpaTests {
@Override
protected String[] getConfigLocations() {
return new String[]{"classpath:applicationContext.xml"};
}
private MessageService service;
public void setService(MessageService service) {
this.service = service;
}
public void testSave(){
Message msg = new Message();
msg.setContent("xxxxxxxxxxxxxxxxx");
msg.setName("tianyi");
msg.setInputTime(new Date());
msg.setTitle("www.easyjf.com");
msg.setIp("123.123.132.123");
service.save(msg);
assertNotNull(msg.getId());
Message msg2 = service.getBy("name", "tianyi");
assertNotNull(msg);
}
}

運行這個測試程序,當你看到綠色的條條,說明你測試成功了。

五、Action層的實現

Service層已經實現并測試通過,接下來我們該寫Action了。Struts2支持POJO的action,不需要繼承或者實現任何類或者接口,可以很方便的測試。這個例子中我們就采用POJO式的action。代碼如下:

package com.struts.sample.action;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.struts.sample.domain.Message;
import com.struts.sample.service.MessageService;
public class MessageAction {
private Message message;
private Long id;
private MessageService service;
private List<Message> msgs = new ArrayList<Message>();
private Integer pages = 0;
private Integer pageSize = 0;
public List<Message> getMsgs() {
return msgs;
}
public void setMsgs(List<Message> msgs) {
this.msgs = msgs;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getPages() {
return pages;
}
public void setPages(Integer pages) {
this.pages = pages;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
public String List(){
this.msgs = this.service.find("select msg from Message msg", pages, pageSize, null);
return "success";
}
public String Save(){
message.setInputTime(new Date());
if(message.getId()!=null){
this.service.update(message);
}else{
this.service.save(message);
}
return this.List();
}
public String Del(){
if(id==null){
return "error";
}else{
this.service.del(id);
}
return this.List();
}
public String Edit(){
if(id==null){
return "error";
}else{
this.message = this.service.get(id);
}
return "success";
}
public void setService(MessageService service) {
this.service = service;
}
}

代碼很簡單,但是卻實現了添刪改查的功能,struts2確實比struts1好用多了。Struts2中可以將一個POJO作為action,就像上面的action。在用戶訪問到這個action的時候struts2會根據前臺提交進來的數據自動將必要的字段進行注入。
以save為例,當我們訪問到這個方法的時候,前臺表單域會有message.title、message.name、message.content等變量,struts2會根據這些前臺變量的名字將他們注入到MessageAction中的message中。而如果我們是執行的修改操作,那么前臺還會傳遞一個id到服務端,struts2又會自動將這個值注入到id中。
需要注意的是,如果你希望某個字段被注入,那么你應該提供一個setter,如果你同時希望這個字段能在頁面中被訪問,那么你還應該為它提供一個getter。

接下來我們來配置struts2,前面我們只是將struts2運行所需的環境配置起來了,現在我們需要配置新添加的Action。
打開struts.xml文件,在package節點中添加如下內容:

<action name="message_*" class="com.struts.sample.action.MessageAction" method="{1}">
<result>List.jsp</result>
</action>

這個配置文件大家可能有點不明白,怎么還有“*”、“{1}”這種東西?,F在我簡單解釋一下。struts2的action配置中支持通配符,message_*大家應該能明白,“*”就代表任意的東西,訪問的時候可以用message_aaa、message_bbb等,這些請求都會被交給MessageAction來處理,但是會不會有正確的結果還要看后面的method="{1}"這個東西。method屬性使得一個action中的一個方法就可以處理一個請求,這意味著我們不需要寫大量的action,而可以把一些相關的處理放到一個action中?,F在我們來說說這個“{1}”,實際上“{1}”是代表前面name中的通配符的位置,struts會將第一個“*”代表的那一串字符串截取下來,作為method的值。在這個例子中,假設我們用message_aaa.action來訪問的話,那么struts會調用MessageAction的aaa方法。struts2的這種通配符可以支持多個,如果有兩個,那么"{1}"就代表第一個"*"所匹配的字符串,"{2}"就代表第二個"*"匹配的字符串,以此類推。

后臺的東西到這里就差不多了,剩下的就是頁面了。

六、頁面

是一個很簡單的示例,只有一個個頁面。在webapp目錄下新建目錄message,在message目錄下新建文件List.jsp,輸入如下內容:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>message</title>
</head>
<body>
<s:iterator value="msgs">
<table style="border:1px solid #cccccc; margin-top:10px;" width="700">
<tr>
<td>標題:<s:property value="title" /></td>
<td>發表時間:<s:property value="inputTime" /></td>
</tr>
<tr>
<td colspan="2" height="100" style="padding:10px;">留言內容:
<div style="border:1px dotted #dddddd">
<p>  <s:property value="content" /></p>
</div></td>
</tr>
<tr>
<td>作者:<s:property value="name" /></td>
<td>操作:<a href='<s:url action="message_Edit">
<s:param name="id" value="id" /></s:url>'>Edit</a>
<a href='<s:url action="message_Del">
<s:param name="id" value="id" /></s:url>'>
Delete
</a></td>
</tr>
</table>
<hl/>
</s:iterator>
<s:form action="message_Save" >
<s:hidden name="message.id" />
<s:textfield name="message.title" label="標題" />
<s:textarea name="message.content" label="內容" />
<s:textfield name="message.name" label="作者" />
<s:submit label="提交" />
</s:form>
</body>
</html>

到這里基本完工了,我們運行一下,看看結果。
打開瀏覽器輸入http://localhost:8080/message/message_List.action,居然是錯誤界面,錯誤信息如下:

這是為什么呢,原來我們沒有為service配置事務。打開applicationContext.xml,添加如下內容:

<aop:config>
<aop:advisor
pointcut="execution(* com.struts.sample.service.*.*(..))"
advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="insert*" />
<tx:method name="update*" />
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

運行試試,應該沒有問題了吧!運行界面如下:

 

 們添加一條記錄看看,我隨便填了一條,點submit:

這里,我們的第一個示例就宣告完成了,如果有什么錯誤,還請大家指正。

源碼下載:struts-sample.rar

本文為原創,同時在easyjf官方博客發表:http://www.easyjf.com/blog/html/20080402/1474562.html。歡迎轉載,轉載請保留出處。



天 一 2008-04-02 10:44 發表評論
]]>
EasyJWeb結合Ext的一個全新的Ajax示例http://www.tkk7.com/lonun/archive/2008/01/11/174540.html天 一天 一Fri, 11 Jan 2008 02:55:00 GMThttp://www.tkk7.com/lonun/archive/2008/01/11/174540.htmlhttp://www.tkk7.com/lonun/comments/174540.htmlhttp://www.tkk7.com/lonun/archive/2008/01/11/174540.html#Feedback7http://www.tkk7.com/lonun/comments/commentRss/174540.htmlhttp://www.tkk7.com/lonun/services/trackbacks/174540.html閱讀全文

天 一 2008-01-11 10:55 發表評論
]]>
一個基于ajax的聊天室示例應用http://www.tkk7.com/lonun/archive/2008/01/07/173394.html天 一天 一Mon, 07 Jan 2008 09:23:00 GMThttp://www.tkk7.com/lonun/archive/2008/01/07/173394.htmlhttp://www.tkk7.com/lonun/comments/173394.htmlhttp://www.tkk7.com/lonun/archive/2008/01/07/173394.html#Feedback1http://www.tkk7.com/lonun/comments/commentRss/173394.htmlhttp://www.tkk7.com/lonun/services/trackbacks/173394.html  閱讀全文

天 一 2008-01-07 17:23 發表評論
]]>
EasyJWeb注解的使用——簡化Action層的開發http://www.tkk7.com/lonun/archive/2007/12/28/171160.html天 一天 一Fri, 28 Dec 2007 05:36:00 GMThttp://www.tkk7.com/lonun/archive/2007/12/28/171160.htmlhttp://www.tkk7.com/lonun/comments/171160.htmlhttp://www.tkk7.com/lonun/archive/2007/12/28/171160.html#Feedback0http://www.tkk7.com/lonun/comments/commentRss/171160.htmlhttp://www.tkk7.com/lonun/services/trackbacks/171160.html 今天我們來說說action配置時要用的注解@Action,使用這些注解可以大量減少配置文件的編寫。
首先,我們來看看不使用這些注解的時候是怎么做的,以一個hello world程序為例。
首先是action:
public class HelloAction extends AbstractCmdAction
{
    
private IHelloService servie;

    
public IHelloService setService(IHelloService service){
        
this.service = service;
    }


    
public Page doHello(WebForm form, Module module){
        System.out.println(service.sayHello());
        
return null;
    }

}

service:
public interface IHelloService{
    String sayHello();
}

service實現:
public class HelloServiceImpl implements IHelloService
{
    
public String sayHello(){
        
return "hello";
    }

}

如果要使這個程序正常運行,我們還需要配置service和action,easyjweb中默認集成spring,service是在spring的配置文件中配置:
    <bean id="helloService"    class="com.hello.service.impl.HelloServiceImpl">
    
</bean>

現在來配置action,在easyjweb的配置文件中這樣配置:
        <module name="hello" path="/hello" form="" scope="request"
            action
="com.hello.mvc.HelloAction" defaultPage="list"
            inject
="byType">

        
</module>
這里說說這個inject="byType",這樣配置之后在HelloAction中的屬性會自動根據類型來注入。inject還有byName等屬性,意思就是根據名字來注入。如果這里不加這個inject,那么配置文件就應該是這樣寫:
        <module name="hello" path="/hello" form="" scope="request"
            action
="com.hello.mvc.HelloAction" defaultPage="list"
            inject
="byType">
     
<property name="service" ref="helloService" />
        
</module>
property的name屬性對應HelloAction中的service,名字要保持一致。ref對應上面在spring中配置的helloService的id。
到這里,這個程序就可以運行了。
一個簡單的hello程序就用了這么多配置文件,這讓人難以忍受?,F在我們就來說說怎么使用EasyJWeb的注解來簡化配置。
我們修改一下HelloAction的代碼,給這個類加上一個@Action注解:
@Action(path="hello")
public class HelloAction extends AbstractCmdAction
{
    
private IHelloService servie;

    
public IHelloService setService(IHelloService service){
        
this.service = service;
    }


    
public Page doHello(WebForm form, Module module){
        System.out.println(service.sayHello());
        
return null;
    }

}

這樣一來,我們就不需要easyjweb中配置的module了,當使用hello.ejf訪問的時候框架會自動把請求交給HelloAction處理。
現在來簡單介紹一下@Action這個注解。
@Action的各個屬性說明如下:
name用來指Action的名稱,也是在容器中的Bean名稱,我們一般不使用這個屬性。
path用來指定模塊的path值,也即所映射的url,如果不設值該值將會按照缺省的方式處理。
alias用來指定這個模塊的path別名,也就是可以使用其它的一個或多個名稱來訪問這個模塊。
inject用來指定Action中所有業務組件注入方式,默認值為按類型注入。如果為byName則表示按名稱注入,auto表示自動按名稱或類別注入,none則表示不注入。
disInject用來標識不自動注入的屬性。
autoInject用來標識允許自動注入的屬性。
autoToken表示該模塊是否需要開取自動防重復提交功能;
validate表示該模塊是否開取自動驗證功能,默認情況不開啟自動驗證;
view表示該模板的視圖存放子目錄。
scope用來指定這個Action在容器中的創建方式及生命周期,默認值為request,表示每次請求創建一次該對象,若為session則表示個用戶會話創建一個對象,若為singleton表示整個容器中只創建一次該實例。
messageResource表示多國語言屬性文件的存放子目錄。
通常我們只用到path、view、inject這幾個屬性,由于inject的默認值為"AutoJnjectByType",是最常用的,因此通常也不需要顯式指定這個屬性值。而disInject是用來標識不允許注入的屬性的,當我們的action出現了一些不需要注入的屬性時,如logger,我們就需要使用這個屬性來指定哪些是不需要注入的。autoToken則是標識是否開啟防重復提交功能的。



天 一 2007-12-28 13:36 發表評論
]]>
主站蜘蛛池模板: 亚洲成av人片不卡无码久久 | 免费在线观看一区| 色婷婷7777免费视频在线观看| 亚洲av无码乱码国产精品fc2| 国产免费MV大全视频网站| 全亚洲最新黄色特级网站| 国产亚洲综合精品一区二区三区| 日韩免费视频一区| 污污视频网站免费观看| 亚洲日韩涩涩成人午夜私人影院| jizz免费一区二区三区| 亚洲欧洲精品无码AV| a毛片全部播放免费视频完整18| 国产日韩亚洲大尺度高清| 色猫咪免费人成网站在线观看| 亚洲成人午夜在线| 97视频免费观看2区| 亚洲一区在线视频观看| 成人免费无码大片a毛片| 色偷偷噜噜噜亚洲男人| 亚洲不卡无码av中文字幕| 色播在线永久免费视频网站| 亚洲电影中文字幕| 美女视频黄免费亚洲| 亚洲AV女人18毛片水真多| 久久精品亚洲乱码伦伦中文| 毛片在线播放免费观看| 亚洲人成伊人成综合网久久| 日韩高清在线免费观看| 狠狠躁狠狠爱免费视频无码 | 亚洲国产精品成人综合久久久| 成年人视频在线观看免费| 国产亚洲精品美女| 亚洲av无码专区国产乱码在线观看| 免费国产黄网站在线观看可以下载 | 久久亚洲精品视频| 中文字幕无码不卡免费视频| 美女视频黄频a免费| 亚洲国产精品自在线一区二区| 性做久久久久久久免费看| 无码的免费不卡毛片视频|