#
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命令可以通过如下方式找到,并再次运行: