#
iBatis2之SqlMap配置總結(18條)
訂閱
SqlMap的配置是iBatis中應用的核心。這部分任務占據了iBatis開發的70的工作量。
1、命名空間:
<sqlMap namespace="Account">,在此空間外要引用此空間的元素,則需要加上命名空間名。
2、實體的別名:
<typeAlias alias="Account" type="com.lavasoft.ibatissut.simple.domain.entity.Account"/>
如果有用到的全名的地方,可以用別名代替,受命名空間約束。
3、插入操作
對于自增主鍵的表,插入可以不配置插入的主鍵列。否則是必須的。
4、獲取主鍵
插入語句之前配置:主要是針對Sequence主鍵而言,插入前必須指定一個主鍵值給要插入的記錄。Oracle、DB2亦如此,方法是在插入語句標簽<insert....>之前配置上:
<insert id="insertAccount" parameterClass="Account">
<selectKey resultClass="long" keyProperty="sctId">
SELECT SEQ_TEST.NEXTVAL FROM DUAL
</selectKey>
insert into .... ........
</insert>
插入語句之后配置:蛀牙是針對自增主鍵的表而言,這類表在插入時不需要主鍵,而是在插入過程自動獲取一個自增的主鍵。比如MySQL
<insert id="insertAccount" parameterClass="Account">
<selectKey resultClass="long" keyProperty="sctId">
SELECT LAST_INSERT_ID()
</selectKey>
insert into .... ........
</insert>
當然,是否需要配置<selectKey>根據情況,只要能保證記錄有主鍵即可。一旦配置了<selectKey>,就可以在執行插入操作時獲取到新增記錄的主鍵。
6、SQL入參parameterClass
插入語句入參:parameterClass="類別名" 來設定。
查詢語句入參:可以設定類別名,也可以設定為map,也可以設定為iBatis支持的原生類型(比如string、int、long等),當只有一個原生類型入參時,則在SQL中用value關鍵字來引用。比如:
<select id="getById" parameterClass="long" resultMap="result_base">
select * from customer where id = #value#
</select>
map是最強大的入參方式,任何入參方式都可以轉換為這種入參方式,因為iBatis僅接受一個入參,當幾個參數分布在不同對象中的時候,將這些對象的屬性(或者對象本身put)到map中,然后一次傳遞給sql語句是非常有效。可以自己寫一個將對象或者對象集合轉換為map的工具(我已經實現一個了)。
另外,map的中的元素(比如pobj)是個復雜對象,則還可以在SQL中以#pobj.protyename#的格式來引用其中內嵌的屬性。當然不推薦這么干。
7、返回值參數類型
返回值參數也同樣有兩種類型,一種是對象類型resultClass="Account",一種是resultMap="AccountResult"。這兩種類型的選擇常常會令人迷惑不解,一言明其理:
當結果集列名和類屬性名完全對應的時候,則應該使用resultClass來指定查詢結果類型。當然有些列明不對應,可以在sql中使用as重命名達到一致的效果。
當查詢結果列名和類屬性名對應不上的時候,應該選擇resultMap指定查詢結果集類型。否則,則查詢出來填充的對象屬性為空(數字的為0,對象的為null)。
但是實際上resultMap是對一個Java Bean的映射,需要先定義xml的映射后,才可以引用,例如:
<resultMap id="AccountResult" class="Account">
<result property="id" column="ACC_ID"/>
<result property="firstName" column="ACC_FIRST_NAME"/>
<result property="lastName" column="ACC_LAST_NAME"/>
<result property="emailAddress" column="ACC_EMAIL"/>
</resultMap>
resultMap映射的結果的目的就是要將查詢的結果集綁定到映射對象的屬性上。
不管使用哪種返回值參數類型,其最終目的就是要把每條記錄映射到一個類的對象或者對象集合上,如果有某個類屬性映射不上,則在得到的這個對象或對象集合中這個屬性為空。映射的屬性可以是表與實體中的一部分。不要同時使用兩種返回值參數類型,這樣只會令人迷惑。
8、查詢結果集分組
查詢結果集排序有兩種方式:一是在結果集映射上定義<resultMap id="result" class="bar" groupBy="id">,另一種就是在SQL語句中分組。建議在SQL語句中分組,以獲得更大的可控制性。
9、SQL中參數的引用
SQL中引用parameterClass的參數有三種方式:
iBatis內置支持的類型,比如int、string,使用#value#來引用,這個value是關鍵字,不可變。
map類型的參數,使用#keyName#來引用,keyName為鍵名。
復雜對象的參數,使用#propertyName#來引用,propertyName類屬性的名字。
10、模糊查詢中參數的引用
模糊查詢是針對字符串而言的,如果遇到兩個單引號要包含一個參數,則不能再用#來引用變量了,而應該改為$,比如:'%$varName$%',當然,也可以使用 '%' || #varname# || '%' 來繞過此問題。
11、SQL片段
可以通過<sql id="sql_xxx">...</sql>定義SQL片段,然后<include refid="sql_xxx"/>來在各種語句中引用。達到服用目的,
12、動態SQL
可以通過使用動態SQL來組織靈活性更大的更通過的SQL,這樣極大減少了編碼量,是iBatis應用的第二大亮點。
比如:一個動態的where條件
<dynamic prepend="where">
<isNotEmpty prepend="and" property="$$$$$">
$name like '%'|| #$name# ||'%'
</isNotEmpty>
<isGreaterThan prepend="and" property="$$$$$" compareValue="$$$number">
$code like '%'|| #$code# ||'%'
</isGreaterThan>
</dynamic>
當然,prepend表示鏈接關鍵字,可以為任何字符串,當為sql關鍵字時,iBatis自動判斷是否應該添加該關鍵字。該語法也很簡單,關鍵是要會用心思考組織動態SQL。
這里面有一點要注意:區別<isNotEmpty>和<isNotNull>區別,當為空空串時<isNotEmpty>返回true,當為空串時<isNotNull>返回真。哈哈,自己體會吧,說了反而啰嗦。
13、結果集映射繼承
結果集映射的繼承的目的是為了映射定義的復用,比如下面定義了兩個映射,AccountResult繼承了base:
<resultMap id="base" class="Account">
<result property="id" column="ACC_ID"/>
<result property="firstName" column="ACC_FIRST_NAME"/>
<result property="lastName" column="ACC_LAST_NAME"/>
</resultMap>
<resultMap id="AccountResult" class="Account" extends="Account.base">
<result property="emailAddress" column="ACC_EMAIL"/>
</resultMap>
這樣,就很容易擴展了一個映射策略。
14、查詢注入
查詢注入是在一個查詢中嵌入另外一個查詢,這樣做的目的是為了實現實體對象之間的關聯關聯關系(一對一、一對多、多對多)分單項雙向。有關這些內容,是比較復雜的,筆者對此做了深入研究,并分別寫了三篇來講述。
查詢注入的實現就是在實體屬性為另外一個實體或者實體集合的時候,引入一個相關的查詢來實現,例如,客戶和訂單的映射關系:
public class Customer {
private Long id;
private String name;
private String address;
private String postcode;
private String sex;
private List<Orders> orderlist = new ArrayList<Orders>();
<resultMap id="result" class="customer">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="address" column="address"/>
<result property="postcode" column="postcode"/>
<result property="sex" column="sex"/>
<result property="orderlist" column="id" select="orders.findByCustomerId"/>
</resultMap>
在這個映射中,為了查詢客戶的時候,能查詢到相關的訂單,可以在映射orderlist屬性的時候,將其指向另外一個查詢orders.findByCustomerId,這個查詢是以Customer的id為參數來查詢的。
select="orders.findByCustomerId"這個查詢定義如下:
<select id="findByCustomerId" resultMap="result_base" parameterClass="long">
select * from orders where customerId = #value#
</select>
原理就是這么簡單,然后根據實際情況,可以自由實現實體間的關聯關系。
14、iBatis的分頁查詢
iBatis的分頁有兩種方式,一點都不神秘,不要被網上的流言所迷惑。
第一種方式:結果集篩選分頁。先執行部分頁的SQL查詢語句,然后得到一個ResultSet,然后根據分頁范圍選擇有效的記錄填充到對象中,最終以集合的形式返回。對于10w條一下的記錄的表,不存在性能問題,如果存在,你可以選擇第二中方式。
第二種方式:SQL分頁,通過組裝分頁類型的SQL來實現分頁。這個關鍵在于分頁參數的傳遞和分頁SQL的構建。分頁SQL構件每種數據庫都不一樣,不說了。分頁參數的傳遞卻可以通用。我主張用map分裝入參,連同分頁參數一塊傳遞進來,就搞定了。如果原來沒有考慮到分頁,而用的是對象做參數,則可以通過apache 的 beanutils組件來實現一個object到map之間的轉換工具,問題迎刃而解。
當然,這還不是分頁查詢應用的最高境界。思考,分頁需要計算一個總記錄數,記錄數執行的sql返回值是count(?),條件是除了分頁以外的條件,因此應該將查詢SQL靜態分開,以MySQL為例,可以將查詢分為查什么,和什么條件兩部分,在條件部分對分頁參數進行動態判斷,如果分頁參數就不分頁,如果有則分頁。這樣最后只需要兩個組裝的sql就可以計算總數和分頁查詢了。大大簡化了問題的難度。 Oracle的解決思路也一樣,不一樣的地方就是拼裝分頁SQL改變了。
15、執行存儲過程的配置
SQL Map 通過<procedure>元素支持存儲過程。下面的例子說明如何使用具有輸出參數
的存儲過程。
<parameterMap id="swapParameters" class="map">
<parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
<parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>
<procedure id="swapEmailAddresses" parameterMap="swapParameters">
{call swap_email_address (?, ?)}
</procedure>
調用上面的存儲過程將同時互換兩個字段(數據庫表)和參數對象(Map)中的兩個 email地址。如果參數的 mode 屬性設為 INOUT 或 OUT,則參數對象的值被修改。否則保持不變。
注意!要確保始終只使用 JDBC 標準的存儲過程語法。參考 JDBC 的 CallableStatement
文檔以獲得更詳細的信息。
16、就是iBatis中各種id的命名了,這個看起來小菜一碟,但是搞砸了會很痛苦。建議如果有DAO層的話,DAO接口的名字和SQL語句id的名字保持一致。同時,在DAO中將save和update封裝為一個方法(從Hibernate中學來的),這是非常好的。也可以直接在SQL層將插入和更新柔和在一塊,太復雜,有點影響效率,這見機行事了。
另外Spring提供了各種數據操作模板,通過模板,擦做數據也就是“一句話”的問題,寫個DAO還有必要么,尤其對iBatis來說,根本沒有必要。這樣,就需要在領域活動層的設計上下功夫了。
18、偷懶的最高境界,讓程序去干哪里80%的體力活。自己僅僅把把關。任何重復的活動都有規律可循的,一旦發現了其中的規律,你就可以想辦法把自己從中解脫出來。
iBatis也不例外,每個表都有增刪改查、分頁等操作。對應在每個DAO方法上亦如此。可以通過數據庫生成sqlmap、entity、dao,然后將這些東西改吧改吧就完成大部分的工作量。本人已經實現過了,當然開發這個工具的前提是你對iBatis有深入研究和理解。
-------------------------------------------------
下面是iBatis開發指南中內容:
附錄:容易出錯的地方
本附錄是譯者添加的,列出了初學者容易出錯的地方,作為完成快速入門課程后的學習
筆記,可以讓初學者少走些彎路。僅供參考。
1) 在 parameterMap 和 resultMap 中,字段數據類型是 java.sql.Types 類定義的常量名
稱。常用的數據類型包括 BLOB,CHAR,CLOB,DATE,LONGVARBINARY,
INTEGER,NULL,NUMERIC,TIME,TIMESTAMP 和 VARCHAR 等。
2) 對于數據表中 NULLABLE 的字段,必須在 parameterMap 和 resultMap 中指定字段
的數據類型。
3) 對于數據類型是 DATE,CLOB 或 BLOB 的字段,最好在 parameterMap 和 resultMap中指定數據類型。
4) 對于二進制類型的數據,可以將 LONGVARBINARY 映射成 byte[]。
5) 對于文本類型較大的數據,可以將 CLOB 映射成 String。
6) Java Bean 必須擁有缺省的構造器(即無參數的構造器)。
7) Java Bean 最好實現 Serializable 接口,以備應用的進一步擴展。
本人認為:盡量避免在每個入參后面附加參數的類型。以保持配置簡潔,并且本人在長期開發中,沒有發現必須要那么做。
Struts2傳值比struts1.X要方便多了。主要包括:頁面--->Action Action--->頁面兩個方面 (1):頁面到--->Action ,其中頁面寫法如下: <s:form action="/ssh/reg.action" method="post"> <s:textfield label="UserName:" name="username"></s:textfield> //在action中直接寫username屬性和get和set方法
<s:textfield label="Age:" name="person.age"></s:textfield> //在action中寫對象Person person和get和set方法。注意:此處絕對不能寫類名:Person,而應該是對象person
<s:textfield label="Address:" name="person.address"></s:textfield> // 和person.age類似
<s:submit value="Login"></s:submit>
</s:form>
(2):action類寫法:可以繼承或者不繼承ActionSupport類。注意是屬性和get和set方法 public class RegAction extends ActionSupport{
private Person person;
private String username;
private List<Person> personList;
public List<Person> getPersonList() {
return personList;
}
public void setPersonList(List<Person> personList) {
this.personList = personList;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
/**其中還可以加單一屬性,對象,集合(包括list和map)**/
@Override
public String execute() throws Exception {
List<Person> personList1 = new ArrayList<Person>();
Person person = new Person();
person.setAddress("hunan");
person.setAge(25);
Person person1 = new Person();
person1.setAddress("beijing");
person1.setAge(35);
personList1.add(person);
personList1.add(person1);
this.setPersonList(personList1);
return SUCCESS;
}
}
(3):action---->頁面 (1):單一屬性:<s:property value="username"/> //屬性名 (2):對象:<s:property value="person.address"/> // 對象名+屬性名 (3):list對象:List對象和Map對象
<s:iterator value="personList" id="Person"> // value是集合對象名,id是別名,可以隨便取 <s:property value="#Person.age"/> // #+別名+屬性名 其中#符號不可以缺少。
<s:property value="#Person.address"/> // 同上
</s:iterator>
(4)
<s:iterator value="map" id="id" status="st"> // value是集合對象名,id是別名,也可省,status也可以省。 key : <s:property value='key'/> // map的key值,其中,values只能為key或者value,不能為其他。
value:<s:property vlaue='value'/> //同上
</s:iterator>
總結:在傳值的時候,也可以采用servlet或者struts1.X的方式用request,session 進行傳值。比如:request/session.setAttribute(name,values)等方式。然后在頁面中,在使用request/session.getAttribute(name);但是不建議這么去做,建議還是用struts2的方式傳值。
struts2不是從strus1.X繼承,而是從xwork繼承而來。在使用struts中,盡量少用到struts的內容。 (1):導入strusts2的基本jar包:struts2-core-2.2.3.1.jar xwork-core-2.2.3.1.jar ognl-3.0.1.jar freemarker-2.3.16.jar commons-logging-1.1.1.jar commons-lang-2.5.jar commons-io-2.0.1.jar commons-fileupload-1.2.2.jar commons-beanutils-1.7.0.jar javassist-3.11.0.GA.jar
(2):編寫jsp頁面。注意:form表單值為:form=“/工程名/包的命名空間(namespace)/包名稱(package)/處理名(action)”
(3):編寫web.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
(4)編寫處理類。該處理類一般繼承于ActionSupport,只需重新excute()方法即可。注意:此處理類也可以是一般的類:(不繼承ActionSupport). 其中的方法名也可以是任意的。但是該處理方法必須要有返回值String,并且這個返回值與struts中的resutl的name值必須一致。比如:
public class Test {
public String testaa(){
System.out.println("Testaa-------Testaa-------Testaa");
return "abc";
}
}
(5):配置struts.xml文件(struts.xml文件必須要放到src目錄下,而不是與action類名在同一個目錄)。其中
(i):package里面的命名空間:namespace可以與package名稱不一致。
(ii):action中Method方法默認是excute,也可以是其他的方法。
(iii):result中的name值不一定是success或者fail。可以是任意值,只需要這個值與處理類中的處理方法返回值一致就可以了。
(iv):struts.xml可以有多個package。
(xv):<constant name="struts.action.extension" value="action,do" />
表示提交地址必須要以.action或者.do結尾格式才能有效。
<?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>
<package name="j2eetest" extends="struts-default" namespace="/j2eetestaa">
<action name="test" class="com.wsw.struts.action.Test" method="testaa">
<result name="abc">/main/success.jsp</result>
<result name="fail">/main/fail.jsp</result>
</action>
</package>
</struts>

一、sql server日期時間函數

Sql Server中的日期與時間函數
1. 當前系統日期、時間
select getdate()

2.
dateadd 在向指定日期加上一段時間的基礎上,返回新的
datetime 值

例如:向日期加上2天
select dateadd(
day,
2,
'2004-10-15')
--返回:2004-10-17 00:00:00.000

3.
datediff 返回跨兩個指定日期的日期和時間邊界數。
select datediff(
day,
'2004-09-01',
'2004-09-18')
--返回:17

4.
datepart 返回代表指定日期的指定日期部分的整數。
select DATEPART(
month,
'2004-10-15')
--返回 10

5.
datename 返回代表指定日期的指定日期部分的字符串
select datename(weekday,
'2004-10-15')
--返回:星期五

6.
day(),
month(),
year()
--可以與datepart對照一下

select 當前日期
=convert(
varchar(
10),
getdate(),
120)

,當前時間
=convert(
varchar(
8),
getdate(),
114)

select datename(dw,
'2004-10-15')

select 本年第多少周
=datename(week,
'2004-10-15')

,今天是周幾
=datename(weekday,
'2004-10-15')
二、日期格式轉換
select CONVERT(
varchar,
getdate(),
120 )
2004-09-12 11:
06:
08
select replace(
replace(
replace(
CONVERT(
varchar,
getdate(),
120 ),
'-',
''),
' ',
''),
':',
'')
20040912110608
select CONVERT(
varchar(
12) ,
getdate(),
111 )
2004/09/12
select CONVERT(
varchar(
12) ,
getdate(),
112 )
20040912
select CONVERT(
varchar(
12) ,
getdate(),
102 )
2004.09.
12

其它我不常用的日期格式轉換方法:

select CONVERT(
varchar(
12) ,
getdate(),
101 )
09/12/2004
select CONVERT(
varchar(
12) ,
getdate(),
103 )
12/09/2004
select CONVERT(
varchar(
12) ,
getdate(),
104 )
12.09.
2004
select CONVERT(
varchar(
12) ,
getdate(),
105 )
12-09-2004
select CONVERT(
varchar(
12) ,
getdate(),
106 )
12 09 2004
select CONVERT(
varchar(
12) ,
getdate(),
107 )
09 12,
2004
select CONVERT(
varchar(
12) ,
getdate(),
108 )
11:
06:
08
select CONVERT(
varchar(
12) ,
getdate(),
109 )
09 12 2004 1
select CONVERT(
varchar(
12) ,
getdate(),
110 )
09-12-2004
select CONVERT(
varchar(
12) ,
getdate(),
113 )
12 09 2004 1
select CONVERT(
varchar(
12) ,
getdate(),
114 )
11:
06:
08.177
舉例:
1.GetDate() 用于sql server :select GetDate()
2.DateDiff('s','2005-07-20','2005-7-25 22:56:32')返回值為 514592 秒
DateDiff('d','2005-07-20','2005-7-25 22:56:32')返回值為 5 天
3.DatePart('w','2005-7-25 22:56:32')返回值為 2 即星期一(周日為1,周六為7)
DatePart('d','2005-7-25 22:56:32')返回值為 25即25號
DatePart('y','2005-7-25 22:56:32')返回值為 206即這一年中第206天
DatePart('yyyy','2005-7-25 22:56:32')返回值為 2005即2005年
附圖
函數 | 參數/功能 |
GetDate( ) | 返回系統目前的日期與時間 |
DateDiff (interval,date1,date2) | 以interval 指定的方式,返回date2 與date1兩個日期之間的差值 date2-date1 |
DateAdd (interval,number,date) | 以interval指定的方式,加上number之后的日期 |
DatePart (interval,date) | 返回日期date中,interval指定部分所對應的整數值 |
DateName (interval,date) | 返回日期date中,interval指定部分所對應的字符串名稱 |
參數 interval的設定值如下:
值 | 縮 寫(Sql Server) | Access 和 ASP | 說明 |
Year | Yy | yyyy | 年 1753 ~ 9999 |
Quarter | Qq | q | 季 1 ~ 4 |
Month | Mm | m | 月1 ~ 12 |
Day of year | Dy | y | 一年的日數,一年中的第幾日 1-366 |
Day | Dd | d | 日,1-31 |
Weekday | Dw | w | 一周的日數,一周中的第幾日 1-7 |
Week | Wk | ww | 周,一年中的第幾周 0 ~ 51 |
Hour | Hh | h | 時0 ~ 23 |
Minute | Mi | n | 分鐘0 ~ 59 |
Second | Ss | s | 秒 0 ~ 59 |
Millisecond | Ms | - | 毫秒 0 ~ 999 |
1. 簡介
Maven是基于項目對象模型(POM),可以通過一小段描述信息來管理項目的構建,報告和文檔的軟件項目管理工具.
如果你已經有十次輸入同樣的Ant targets來編譯你的代碼、jar或者war、生成javadocs,你一定會自問,是否有一個重復性更少卻能同樣完成該工作的方 法。 Maven便提供了這樣一種選擇,將你的注意力從作業層轉移到項目管理層。Maven項目已經能夠知道如何構建和捆綁代碼,運行測試,生成文檔并宿主項目 網頁
2.核心價值
* 簡單
Maven 暴露了一組一致、簡介的操作接口,能幫助團隊成員從原來的高度自定義的、復雜的構建系統中解脫出來,使用Maven現有的成熟的、穩定的組件也能簡 化構建系統的復雜度。
* 交流與反饋
與版本控制系統結合后,多有人都能執行最新的構建并快速得到反饋。此外,自動生成的項目報告也能幫助成員了解項目的狀態,促進團隊的交流。
* 測試驅動開發
TDD強調測試先行,所有產品都應該由測試用例覆蓋。而測試是maven生命周期的最重要組成部分之一,并且Maven有現成的成熟插件支持業界流行的測試框架,如Junit和TestNG。
* 快速構建
只需要一些配置,之后用一條簡單的命令就能讓Maven幫你清理、編譯、測試、打包、部署,然后得到最終產品。[/size]
* 持續集成
更加方便的持續集成
* 富有信息的工作區
2.主要內容
我將會發表一系列課程來講解Maven的應用,基于Maven3.0,主要內容如下:
1)安裝和配置
2)Maven使用入門
3)坐標和依賴
4)Maven倉庫
5) 生命周期和插件
6)聚合與繼承
7)使用Nexus創建私服
8)使用Maven進行測試
9)m2eclipse的使用
10)自動部署maven項目
11)使用Hudson進行持續集成
3. 安裝好JDK
以JDK1.5以上為例
4. Maven 的下載
下載地址:http://maven.apache.org/download.html
5.Maven安裝
將下載到的文件解壓到指定目錄即可,如:C:\maven\apache-maven-3.0.4
6.環境變量的配置
在系統環境變量中新增如下環境變量
M2_HOME: Maven的安裝目錄,如:C:\maven\apache-maven-3.0.4
M2: %M2_HOME%\bin
并在path中添加%M2%,這樣便可以在任何路徑中執行mvn命令
7. 檢測安裝是否成功
Cmd窗口執行命令:mvn –v
得到如下圖所示結果:

8.設置代理
有時候你所在的公司基于安全因素考慮,要求你使用通過安全認證的代理訪問因特網。這時就需要為Maven配置HTTP代理。
在目錄~/.m2/setting.xml文件中編輯如下(如果沒有該文件,則復制$M2_HOME/conf/setting.xml):
Xml代碼

- <proxies>
- <proxy>
- <id>optional</id>
- <active>true</active>
- <protocol>http</protocol>
- <username>proxyuser</username>
- <password>proxypass</password>
- <host>proxy.host.net</host>
- <port>80</port>
- <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
- </proxy>
- </proxies>
8、安裝Maven后每次啟動出現警告信息:
Eclipse is running in a JRE, but a JDK is required
Some Maven plugins may not work when importing projects or updating source folders.
分兩步解決問題:
1. 檢查Eclipse正在使用的JRE
‘Window’ -> ‘Preferences’ -> ‘Java’ -> ‘Installed JREs’ 確定正在使用JDK而非JRE.

如果沒有JDK, 則先新增一個Standard VM.
2. 配置Eclipse.ini
檢查Eclipse配置文件, 增加/編輯以下代碼:
- -vm
- C:\Progra~2\Java\jdk1.6.0_16\jre\bin\javaw
注意事項:
1. 第一行參數名稱, 第二行為值, 不能寫到同一行中
2. 關于第二行的值, 因為不允許出現空格, 所以使用Progra~1或2 替代”Program Files (x86)”.
如果在Program Files下, 請使用Progra~1, 如果在x86下, 則使用Progra~2
3. 在文件中的位置, 不能放到最后(不能在-vmargs之后), 不放心的直接放到文件最前, 如:
- -vm
- C:\Progra~2\Java\jdk1.6.0_16\jre\bin\javaw
- -startup
- .....
- --launcher.defaultAction
- openFile
- -vmargs
- -Dosgi.requiredJavaVersion=1.5
- -Xms240m
- -Xmx912m
上一節講了maven的安裝和配置,這一節我們來學習一下創建一個簡單的Maven項目
1. 用Maven 命令創建一個簡單的Maven項目
在cmd中運行如下命令:
- mvn archetype:generate
- -DgroupId=com.mycompany.app
- -DartifactId=my-app-simple
- -Dversion=1.0
- -DarchetypeArtifactId=maven-archetype-quickstart
即可在當前目錄創建一個簡單的maven項目,當然創建的時候會從Maven庫中下載相關的依賴,耐心等待即可。
maven的大致結構如下:
- my-app
- |-- pom.xml
- `-- src
- |-- main
- | |-- java
- | | `-- com
- | | `-- mycompany
- | | `-- app
- | | `-- App.java
- | `-- resources
- | `-- META-INF
- | `-- application.properties
- `-- test
- `-- java
- `-- com
- `-- mycompany
- `-- app
- `-- AppTest.java
src/main/java : java源文件存放位置
src/main/resource : resource資源,如配置文件等
src/test/java : 測試代碼源文件存放位置
2.簡單POM.xml
打開項目即可看到pom.xml
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.mycompany.app</groupId>
- <artifactId>my-app-simple</artifactId>
- <packaging>jar</packaging>
- <version>1.0</version>
- <name>my-app-simple</name>
- <url>http://maven.apache.org</url>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- </project>
這段代碼中最重要的是包含groupId, artifactId 和 version 的三行。這三個元素定義了一個項目基本的坐標
groupId 定義了項目屬于哪個組,這個組往往和項目所在的組織或公司存在關聯。譬如在googlecode上建立了一個名為myapp的項目,那么groupId就應該是com.googlecode.myapp
artifactId 定義了當前Maven項目在組織中唯一的ID, 可以理解為項目中的模塊, 模塊為Maven中最小單位構件
version 項目的版本
3.運行簡單Maven命令
我們已經創建了最簡單的Maven項目,下面我們來執行一些簡單的構建命令
編譯: compile
在cmd中,將目錄切換到my-app-simple下,執行mvn clean compile
build success之后我們會在my-app-simple下看到新增了一個target目錄,該目錄下存放項目編譯后的文件,如.class文件
清理: clean
cmd目錄my-app-simple下執行命令 mvn clean
會將target文件刪除,即清理項目,該命令可以結合其他命令運行
測試: test
cmd目錄my-app-simple下執行命令 mvn test
會執行src/test/java 下的Junit 測試代碼
當然在執行測試之前會自動執行編譯命令,運行結果如下圖:

打包: package
cmd目錄my-app-simple下執行命令 mvn package
會將項目打成jar包,并放在target目錄中
執行此命令之前會先執行編譯和測試命令
安裝:install
cmd目錄my-app-simple下執行命令 mvn install
會將項目jar包安裝到本地倉庫中,以便其他項目使用
執行此命令之前會先執行編譯,測試,打包命令
摘要: 我們項目中用到的jar包可以通過依賴的方式引入,構建項目的時候從Maven倉庫下載即可。 1. 依賴配置 依賴可以聲明如下: Xml代碼 <project> ... <dependenci...
閱讀全文
1.為什么要定義Maven坐標
在我們開發Maven項目的時候,需要為其定義適當的坐標,這是Maven強制要求的。在這個基礎上,其他Maven項目才能應用該項目生成的構件。
2.Maven坐標詳解
Maven坐標為各種構件引入了秩序,任何一個構件都必須明確定義自己的坐標,而一組Maven坐標是通過一些元素定義的,它們是groupId,artifactId,version,packaging,class-sifer。下面是一組坐標定義:
- <groupId>com.mycompany.app</groupId>
- <artifactId>my-app</artifactId>
- <packaging>jar</packaging>
- <version>0.0.1-SNAPSHOT</version>
下面講解一下各個坐標元素:
groupId :定義當前Maven項目隸屬的實際項目。首先,Maven項目和實際項目不一定是一對一的關系。比如SpringFrameWork這一實際項目,其對應的Maven項目會有很多,如spring-core,spring-context等。這是由于Maven中模塊的概念,因此,一個實際項目往往會被劃分成很多模塊。其次,groupId不應該對應項目隸屬的組織或公司。原因很簡單,一個組織下會有很多實際項目,如果groupId只定義到組織級別,而后面我們會看到,artifactId只能定義Maven項目(模塊),那么實際項目這個層次將難以定義。最后,groupId的表示方式與Java包名的表達方式類似,通常與域名反向一一對應。
artifactId : 該元素定義當前實際項目中的一個Maven項目(模塊),推薦的做法是使用實際項目名稱作為artifactId的前綴。比如上例中的my-app。
version : 該元素定義Maven項目當前的版本
packaging :定義Maven項目打包的方式,首先,打包方式通常與所生成構件的文件擴展名對應,如上例中的packaging為jar,最終的文件名為my-app-0.0.1-SNAPSHOT.jar。也可以打包成war, ear等。當不定義packaging的時候,Maven 會使用默認值jar
classifier: 該元素用來幫助定義構建輸出的一些附件。附屬構件與主構件對應,如上例中的主構件為my-app-0.0.1-SNAPSHOT.jar,該項目可能還會通過一些插件生成如my-app-0.0.1-SNAPSHOT-javadoc.jar,my-app-0.0.1-SNAPSHOT-sources.jar, 這樣附屬構件也就擁有了自己唯一的坐標
1. 三套生命周期
Maven擁有三套相互獨立的生命周期,它們分別為clean,default和site。
每個生命周期包含一些階段,這些階段是有順序的,并且后面的階段依賴于前面的階段,用戶和Maven最直接的交互方式就是調用這些生命周期階段。
以clean生命周期為例,它包含的階段有pre-clean, clean 和 post clean。當用戶調用pre-clean的時候,只有pre-clean得以執行,當用戶調用clean的時候,pre-clean和clean階段會得以順序執行;當用戶調用post-clean的時候,pre-clean,clean,post-clean會得以順序執行。
較之于生命周期階段的前后依賴關系,三套生命周期本身是相互獨立的,用戶可以僅僅調用clean生命周期的某個階段,或者僅僅調用default生命周期的某個階段,而不會對其他生命周期產生任何影響。
2. clean 生命周期
clean生命周期的目的是清理項目,它包含三個階段:
1)pre-clean 執行一些清理前需要完成的工作。
2)clean 清理上一次構建生成的文件。
3)post-clean 執行一些清理后需要完成的工作。
3. default 生命周期
default生命周期定義了真正構件時所需要執行的所有步驟,它是生命周期中最核心的部分,它包含的階段如下:
1) validate 驗證項目是否正確和所有需要的相關資源是否可用
2) initialize 初始化構建
3) generate-sources
4) process-sources 處理源代碼
5) generate-resources
6) process-resources 處理項目主資源文件。對src/main/resources目錄的內容進行變量替換等工作后,復制到項目輸出的主classpath目錄中。
7) compile 編譯項目的主源代碼
8) process-classes
9) generate-test-sources
10) process-test-sources 處理項目測試資源文件
11)generate-test-resources
12) process-test-resources 處理測試的資源文件
13)test-compile 編譯項目的測試代碼
14)process-test-classes
15) test 使用單元測試框架運行測試,測試代碼不會被打包或部署
16)prepare-package 做好打包的準備
17)package 接受編譯好的代碼,打包成可發布的格式
18) pre-integration-test
19) integration-test
20) post integration-test
21) verify
22) install 將包安裝到Maven本地倉庫,供本地其他Maven項目使用
23)deploy 將最終的包復制到遠程倉庫,供其他開發人員和Maven項目使用
4. site 生命周期
site生命周期的目的是建立和發布項目站點,Maven能夠基于POM所包含的信息,自動生成一個友好的站點,方便團隊交流和發布項目信息。該生命周期包含如下階段:
1)pre-site 執行一些在生成項目站點之前需要完成的工作
2)site 生成項目站點文檔
3)post-site 執行一些在生成項目站點之后需要完成的工作
4)site-deploy 將生成的項目站點發布到服務器上
1. 安裝m2eclipse插件
要用Eclipse構建Maven項目,我們需要先安裝meeclipse插件
點擊eclipse菜單欄Help->Eclipse Marketplace搜索到插件Maven Integration for Eclipse 并點擊安裝即可,如下圖:

安裝成成之后我們在Eclipse菜單欄中點擊File->New->Other,在彈出的對話框中會看到如下圖所示:

2. 構建Maven項目
以eclipse3.6為例
1)創建簡單Maven項目
點擊Eclipse菜單欄File->New->Ohter->Maven得到如下圖所示對話框:

選中Maven Project并點擊Next,到下一個對話框繼續點擊Next得到如下對話框

如圖示操作,選擇maven-archetype-quickstart,點擊Next

按圖示填寫好groupId, artfactId,version等信息,點擊Finish。
由此我們成功創建了一個簡單的Maven項目,項目結構如圖所示

2)創建Maven web項目
操作跟創建簡單Maven項目類似,點擊Eclipse菜單File->New->Other->Maven->Maven Project
在選擇maven-archetype的界面進行如下操作:

點擊Next,填寫好相應的groupId,artifactId,version等信息,點擊Finish
得到的Maven web項目結構如下圖所示:

右擊項目,點擊Properties->Project Facets

如上圖可以看到項目為web2.3 java1.5 當然我們也可以改成我們所需要的版本,打開xml文件my-app-web/.settings/org.eclipse.wst.common.project.facet.core.xml,進行修改即可:
- <?xml version="1.0" encoding="UTF-8"?>
- <faceted-project>
- <fixed facet="wst.jsdt.web"/>
- <installed facet="java" version="1.5"/>
- <installed facet="jst.web" version="2.3"/>
- <installed facet="wst.jsdt.web" version="1.0"/>
- </faceted-project>
3)導入Maven項目
在Eclipse project explorer中右擊,在彈出框中選擇import,得到如下圖所示:

選擇Existing Maven Projects,并點擊Next,得到如下圖所示對話框:

選擇一個已經創建好的Maven項目,并點擊Finish。
由此,導入Maven項目成功
3. 運行Maven命令
右擊項目,點擊Run as,如下圖:

即可看到有很多現有的maven命令,點擊即可運行,并在控制臺可以看到運行信息
如果你想運行的maven命令在這里沒有找到,點擊Maven build創建新的命令,操作如下圖所示:

如下圖填入Maven命令,點擊Run即可

新增的maven命令可以通過如下方式找到,并再次運行:

