转自:http://blog.sina.com.cn/s/blog_ab3fbf1b0101jbxz.html

Apache Jakarta Commons项目非常有用。我曾在许多不同的项目上或直接或间接地使用各种流行的commons组件。其中的一个强大的组件就是BeanUtils。我将说明如何使用BeanUtils将local实体bean转换为对应的value 对象:

BeanUtils.copyProperties(aValue, aLocal)

上面的代码从aLocal对象复制属性到aValue对象。它相当简单!它不管local(或对应的value)对象有多少个属性,只管进行复制。我们假设local对象有100个属性。上面的代码使我们可以无需键入至少100行的冗长、容易出错和反复的get和set方法调用。这太棒了!太强大了!太有用了!

现在,还有一个坏消息:使用BeanUtils的成本惊人地昂贵!我做了一个简单的测试,BeanUtils所花费的时间要超过取数据、将其复制到对应的value对象(通过手动调用get和set方法),以及通过串行化将其返回到远程的客户机的时间总和。所以要小心使用这种威力!

如果您有BeanUtils和类似的实用程序方面的体验,请与我交流分享。

+prakash

Beanutils用了魔术般的反射技术,实现了很多夸张有用的功能,都是C/C++时代不敢想的。无论谁的项目,始终一天都会用得上它。我算是后知后觉了,第一回看到它的时候居然错过。

1.属性的动态getter,setter

在这框架满天飞的年代,不能事事都保证执行getter,setter函数了,有时候属性是要需要根据名字动态取得的,就像这样:  

BeanUtils.getProperty(myBean,"code");

而BeanUtils更强的功能是直接访问内嵌对象的属性,只要使用点号分隔。

BeanUtils.getProperty(orderBean, "address.city");

相比之下其他类库的BeanUtils通常都很简单,不能访问内嵌的对象,所以经常要用Commons BeanUtils替换它们。

BeanUtils还支持List和Map类型的属性。如下面的语法即可取得顾客列表中第一个顾客的名字

BeanUtils.getProperty(orderBean, "customers[1].name");

其中BeanUtils会使用ConvertUtils类把字符串转为Bean属性的真正类型,方便从HttpServletRequest等对象中提取bean,或者把bean输出到页面。

而PropertyUtils就会原色的保留Bean原来的类型。

2.beanCompartor 动态排序

还是通过反射,动态设定Bean按照哪个属性来排序,而不再需要在bean的Compare接口进行复杂的条件判断。

List peoples = ...; // Person对象的列表 Collections.sort(peoples, new BeanComparator("age"));

如果要支持多个属性的复合排序,如"Order By lastName,firstName"

ArrayList sortFields = new ArrayList(); sortFields.add(new BeanComparator("lastName")); sortFields.add(new BeanComparator("firstName")); ComparatorChain multiSort = new ComparatorChain(sortFields); Collections.sort(rows,multiSort);

其中ComparatorChain属于jakata commons-collections包。

如果age属性不是普通类型,构造函数需要再传入一个comparator对象为age变量排序。

另外, BeanCompartor本身的ComparebleComparator, 遇到属性为null就会抛出异常, 也不能设定升序还是降序。

这个时候又要借助commons-collections包的ComparatorUtils.

Comparator mycmp = ComparableComparator.getInstance();

mycmp = ComparatorUtils.nullLowComparator(mycmp); //允许null

mycmp = ComparatorUtils.reversedComparator(mycmp); //逆序

Comparator cmp = new BeanComparator(sortColumn, mycmp);

3.Converter 把Request或ResultSet中的字符串绑定到对象的属性

经常要从request,resultSet等对象取出值来赋入bean中,下面的代码谁都写腻了,如果不用MVC框架的绑定功能的话。

String a = request.getParameter("a"); bean.setA(a); String b = ....

不妨写一个Binder:

MyBean bean = ...; HashMap map = new HashMap(); Enumeration names = request.getParameterNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); map.put(name, request.getParameterValues(name)); } BeanUtils.populate(bean, map);

其中BeanUtils的populate方法或者getProperty,setProperty方法其实都会调用convert进行转换。

但Converter只支持一些基本的类型,甚至连java.util.Date类型也不支持。而且它比较笨的一个地方是当遇到不认识的类型时,居然会抛出异常来。

对于Date类型,我参考它的sqldate类型实现了一个Converter,而且添加了一个设置日期格式的函数。

要把这个Converter注册,需要如下语句:

ConvertUtilsBean convertUtils = new ConvertUtilsBean();

DateConverter dateConverter = new DateConverter();

convertUtils.register(dateConverter,Date.class);

//因为要注册converter,所以不能再使用BeanUtils的静态方法了,必须创建BeanUtilsBean实例

BeanUtilsBean beanUtils = new BeanUtilsBean(convertUtils,new PropertyUtilsBean());

beanUtils.setProperty(bean, name, value);

4 其他功能

4.1 PropertyUtils,当属性为Collection,Map时的动态读取:

Collection: 提供index

BeanUtils.getIndexedProperty(orderBean,"items",1);

或者

BeanUtils.getIndexedProperty(orderBean,"items[1]");

Map: 提供Key Value

BeanUtils.getMappedProperty(orderBean, "items","111");//key-value goods_no=111

或者

BeanUtils.getMappedProperty(orderBean, "items(111)")

4.2 PropertyUtils,获取属性的Class类型

public static Class getPropertyType(Object bean, String name)

4.3 ConstructorUtils,动态创建对象

public static Object invokeConstructor(Class klass, Object arg)

4.4 MethodUtils,动态调用方法

MethodUtils.invokeMethod(bean, methodName, parameter);

4.5 动态Bean 见用DynaBean减除不必要的VO和FormBean

一、概述

第一次看到BeanUtils包,是在Struts项目中,作为Struts一个工具来使用的,

估计功能越弄越强,就移到Common项目中了吧。

BeanUtils一共有四个package:

org.apache.commons.beanutils

org.apache.commons.beanutils.converters

org.apache.commons.beanutils.locale

org.apache.commons.beanutils.locale.converters

后三个包主要是用于数据的转换,围绕着一个Converter接口,该接口只有一个方法:

java.lang.Object convert(java.lang.Class type, java.lang.Object value) ,

用于将一个value转换成另一个类型为type的Object。在一些自动化的应用中应该会有用。

这里不作评论,以后有兴趣了,或者觉得有用了,再行研究。

这里只讲第一个包。

二、测试用的Bean

在开始所有的测试之前,我写了一个简单的Bean,以便于测试,代码如下:

package test.jakarta.commons.beanutils;

public class Month {

private int value;

private String name;

private int[] days={11,22,33,44,55};

public Month(int v, String n){

value=v;

name=n;

}

public String getName() {

return name;

}

public int getValue() {

return value;

}

public void setName(String name) {

this.name = name;

}

public void setValue(int value) {

this.value = value;

}

public String toString() {

return value+"("+name+")";

}

public int[] getDays() {

return days;

}

public void setDays(int[] is) {

days = is;

}

}

三、BeanUtils

这是一个主要应用于Bean的Util(呵呵,这个解释很绝吧),以下是其中几个方法的例子

//static java.util.Map describe(java.lang.Object bean)

//这个方法返回一个Object中所有的可读属性,并将属性名/属性值放入一个Map中,另外还有

//一个名为class的属性,属性值是Object的类名,事实上class是java.lang.Object的一个属性

Month month=new Month(1, "Jan");

try {

Map map=BeanUtils.describe(month);

Set keySet=map.keySet();

for (Iterator iter = keySet.iterator(); iter.hasNext();) {

Object element = (Object) iter.next();

System.out.println("KeyClass:"+element.getClass().getName());

System.out.println("ValueClass:"+map.get(element).getClass().getName());

System.out.print(element+"\t");

System.out.print(map.get(element));

System.out.println();

}

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

}

输出为:

KeyClass:java.lang.String

ValueClass:java.lang.String

value 1

KeyClass:java.lang.String

ValueClass:java.lang.String

class class test.jakarta.commons.beanutils.Month

KeyClass:java.lang.String

ValueClass:java.lang.String

name Jan

注意到所有Map中的key/value都是String,而不管object中实际的值是多少。

与此对应的还有static void populate(java.lang.Object bean, java.util.Map properties)

用于将刚才describe出的Map再装配成一个对象。

再看这样一段代码

曹晓钢也许还记得,为了取一个不确定对象的property,着实花了不少时间,

难度不大,但要做到100%的正确,仍然需要付出很大的精力。

//static java.lang.String getProperty(java.lang.Object bean, java.lang.String name)

Month month=new Month(1, "Jan");

try {

System.out.println(BeanUtils.getProperty(month,"value"));

} catch (Exception e) {

e.printStackTrace();

}

//输出是:1

与getProperty类似的还有getIndexedProperty, getMappedProperty,

以getIndexedProperty为例:

Month month=new Month(1, "Jan");

try {

System.out.println(BeanUtils.getIndexedProperty(month,"days",1));

System.out.println(BeanUtils.getIndexedProperty(month,"days[1]"));

} catch (Exception e) {

e.printStackTrace();

}

这两个调用是相同的。

BeanUtils中还有一个方法:

static void copyProperties(java.lang.Object dest, java.lang.Object orig)

它真是太有用,还记得struts中满天飞的都是copyProperties,我甚至怀疑整个BeanUtils最初

是不是因为这个方法的需求才写出来的。

它将对象orig中的属性复制到dest中去。

四、PropertyUtils

这个类和BeanUtils类很多的方法在参数上都是相同的,但返回值不同。

BeanUtils着重于"Bean",返回值通常是String,而PropertyUtils着重于属性,

它的返回值通常是Object。

五、ConstructorUtils

这个类中的方法主要分成两种,一种是得到构造方法,一种是创建对象。

事实上多数时候得到构造方法的目的就是创建对象,这里只介绍一下创建对象。

//static java.lang.Object ConstructorUtils.invokeConstructor

//(java.lang.Class klass, java.lang.Object[] args)

//根据一个java.lang.Class以及相应的构造方法的参数,创建一个对象。

Object obj=ConstructorUtils.invokeConstructor(Month.class, {new Integer(1), "Jan"});

Month month=(Month)obj;

try {

System.out.println(BeanUtils.getProperty(month,"value"));

} catch (Exception e) {

e.printStackTrace();

}

输出证明,构造方法的调用是成功的。

如果需要强制指定构造方法的参数类型,可以这样调用:

Object[] args={new Integer(1), "Jan"};

Class[] argsType={int.class, String.class};

Object obj;

obj = ConstructorUtils.invokeExactConstructor(Month.class, args, argsType);

Month month=(Month)obj;

System.out.println(BeanUtils.getProperty(month,"value"));

argsType指定了参数的类型。

六、ConstructorUtils补遗

创建对象还有一个方法:invokeExactConstructor,该方法对参数要求

更加严格,传递进去的参数必须严格符合构造方法的参数列表。

例如:

Object[] args={new Integer(1), "Jan"};

Class[] argsType={int.class, String.class};

Object obj;

//下面这句调用将不会成功,因为args[0]的类型为Integer,而不是int

//obj = ConstructorUtils.invokeExactConstructor(Month.class, args);

//这一句就可以,因为argsType指定了类型。

obj = ConstructorUtils.invokeExactConstructor(Month.class, args, argsType);

Month month=(Month)obj;

System.out.println(BeanUtils.getProperty(month,"value"));

七、MethodUtils

与ConstructorUtils类似,不过调用的时候,通常需要再指定一个method name的参数。

八、DynaClass/DynaBean

这似乎是BeanUtils中最有趣的部分之一了,很简单,简单到光看这两个接口中的方法会不明白

为什么要设计这两个接口。不过看到ResultSetDynaClass后,就明白了。下面是java doc中的代码:

ResultSet rs = ...;

ResultSetDynaClass rsdc = new ResultSetDynaClass(rs);

Iterator rows = rsdc.iterator();

while (rows.hasNext()) {

DynaBean row = (DynaBean) rows.next();

... process this row ...

}

rs.close();

原来这是一个ResultSet的包装器,ResultSetDynaClass实现了DynaClass,它的iterator方法返回一个

ResultSetIterator,则是实现了DynaBean接口。

在获得一个DynaBean之后,我们就可以用

DynaBean row = (DynaBean) rows.next();

System.out.println(row.get("field1")); //field1是其中一个字段的名字

再看另一个类RowSetDynaClass的用法,代码如下:

String driver="com.mysql.jdbc.Driver";

String url="jdbc:mysql://localhost/2hu?useUnicode=true&characterEncoding=GBK";

String username="root";

String password="";

java.sql.Connection con=null;

PreparedStatement ps=null;

ResultSet rs=null;

try {

Class.forName(driver).newInstance();

con = DriverManager.getConnection(url);

ps=con.prepareStatement("select * from forumlist");

rs=ps.executeQuery();

//先打印一下,用于检验后面的结果。

while(rs.next()){

System.out.println(rs.getString("name"));

}

rs.beforeFirst();//这里必须用beforeFirst,因为RowSetDynaClass只从当前位置向前滚动

RowSetDynaClass rsdc = new RowSetDynaClass(rs);

rs.close();

ps.close();

List rows = rsdc.getRows();//返回一个标准的List,存放的是DynaBean

for (int i = 0; i

DynaBean b=(DynaBean)rows.get(i);

System.out.println(b.get("name"));

}

} catch (Exception e) {

e.printStackTrace();

}

finally{

try {

con.close();

} catch (Exception e) {

}

}

是不是很有趣?封装了ResultSet的数据,代价是占用内存。如果一个表有10万条记录,rsdc.getRows()

就会返回10万个记录。@_@

需要注意的是ResultSetDynaClass和RowSetDynaClass的不同之处:

1,ResultSetDynaClass是基于Iterator的,一次只返回一条记录,而RowSetDynaClass是基于

List的,一次性返回全部记录。直接影响是在数据比较多时ResultSetDynaClass会比较的快速,

而RowSetDynaClass需要将ResultSet中的全部数据都读出来(并存储在其内部),会占用过多的

内存,并且速度也会比较慢。

2,ResultSetDynaClass一次只处理一条记录,在处理完成之前,ResultSet不可以关闭。

3,ResultSetIterator的next()方法返回的DynaBean其实是指向其内部的一个固定

对象,在每次next()之后,内部的值都会被改变。这样做的目的是节约内存,如果你需要保存每

次生成的DynaBean,就需要创建另一个DynaBean,并将数据复制过去,下面也是java doc中的代码:

ArrayList results = new ArrayList(); // To hold copied list

ResultSetDynaClass rsdc = ...;

DynaProperty properties[] = rsdc.getDynaProperties();

BasicDynaClass bdc =

new BasicDynaClass("foo", BasicDynaBean.class,

rsdc.getDynaProperties());

Iterator rows = rsdc.iterator();

while (rows.hasNext()) {

DynaBean oldRow = (DynaBean) rows.next();

DynaBean newRow = bdc.newInstance();

PropertyUtils.copyProperties(newRow, oldRow);

results.add(newRow);

}

事实上DynaClass/DynaBean可以用于很多地方,存储各种类型的数据。自己想吧。嘿嘿。

九、自定义的CustomRowSetDynaClass

两年前写过一个与RowSetDynaClass目标相同的类,不过多一个功能,就是分页,只取需要的数据,

这样内存占用就会减少。

先看一段代码:

String driver="com.mysql.jdbc.Driver";

String url="jdbc:mysql://localhost/2hu?useUnicode=true&characterEncoding=GBK";

String username="root";

String password="";

java.sql.Connection con=null;

PreparedStatement ps=null;

ResultSet rs=null;

try {

Class.forName(driver).newInstance();

con = DriverManager.getConnection(url);

ps=con.prepareStatement("select * from forumlist order by name");

rs=ps.executeQuery();

//第二个参数表示第几页,第三个参数表示页的大小

CustomRowSetDynaClass rsdc = new CustomRowSetDynaClass(rs, 2, 5);

//RowSetDynaClass rsdc = new RowSetDynaClass(rs);

rs.close();

ps.close();

List rows = rsdc.getRows();

for (int i = 0; i

DynaBean b=(DynaBean)rows.get(i);

System.out.println(b.get("name"));

}

} catch (Exception e) {

e.printStackTrace();

}

finally{

try {

con.close();

} catch (Exception e) {

}

}

在这里用到了一个CustomRowSetDynaClass类,构造方法中增加了page和pageSize两个参数,

这样,不管数据库里有多少条记录,最多只取pageSize条记录,若pageSize==-1,则功能和

RowSetDynaClass一样。这在大多数情况下是适用的。该类的代码如下:

package test.jakarta.commons.beanutils;

import java.io.;

import java.sql.
;

import java.util.*;

import org.apache.commons.beanutils.*;

public class CustomRowSetDynaClass implements DynaClass, Serializable {

// ----------------------------------------------------------- Constructors

public CustomRowSetDynaClass(ResultSet resultSet) throws SQLException {

this(resultSet, true);

}

public CustomRowSetDynaClass(ResultSet resultSet, boolean lowerCase)

throws SQLException {

this(resultSet, 1, -1, lowerCase);

}

public CustomRowSetDynaClass(

ResultSet resultSet,

int page,

int pageSize,

boolean lowerCase)

throws SQLException {

if (resultSet == null) {

throw new NullPointerException();

}

this.lowerCase = lowerCase;

this.page = page;

this.pageSize = pageSize;

introspect(resultSet);

copy(resultSet);

}

public CustomRowSetDynaClass(ResultSet resultSet, int page, int pageSize)

throws SQLException {

this(resultSet, page, pageSize, true);

}

// ----------------------------------------------------- Instance Variables

protected boolean lowerCase = true;

protected int page = 1;

protected int pageSize = -1;

protected DynaProperty properties[] = null;

protected Map propertiesMap = new HashMap();

protected List rows = new ArrayList();

// ------------------------------------------------------ DynaClass Methods

public String getName() {

return (this.getClass().getName());

}

public DynaProperty getDynaProperty(String name) {

if (name == null) {

throw new IllegalArgumentException("No property name specified");

}

return ((DynaProperty) propertiesMap.get(name));

}

public DynaProperty[] getDynaProperties() {

return (properties);

}

public DynaBean newInstance()

throws IllegalAccessException, InstantiationException {

throw new UnsupportedOperationException("newInstance() not supported");

}

// --------------------------------------------------------- Public Methods

public List getRows() {

return (this.rows);

}

// ------------------------------------------------------ Protected Methods

protected void copy(ResultSet resultSet) throws SQLException {

int abs = 0;

int rowsCount = 0;

int currentPageRows = 0;

resultSet.last();

rowsCount = resultSet.getRow();

if (pageSize != -1) {

int totalPages = (int) Math.ceil(((double) rowsCount) / pageSize);

if (page > totalPages)

page = totalPages;

if (page < 1)

page = 1;

abs = (page - 1) * pageSize;

//currentPageRows=(page==totalPages?rowsCount-pageSize*(totalPages-1):pageSize);

} else

pageSize = rowsCount;

if (abs == 0)

resultSet.beforeFirst();

else

resultSet.absolute(abs);

//int

while (resultSet.next() && ++currentPageRows <= pageSize) {

DynaBean bean = new BasicDynaBean(this);

for (int i = 0; i < properties.length; i++) {

String name = properties[i].getName();

bean.set(name, resultSet.getObject(name));

}

rows.add(bean);

}

}

protected void introspect(ResultSet resultSet) throws SQLException {

// Accumulate an ordered list of DynaProperties

ArrayList list = new ArrayList();

ResultSetMetaData metadata = resultSet.getMetaData();

int n = metadata.getColumnCount();

for (int i = 1; i <= n; i++) { // JDBC is one-relative!

DynaProperty dynaProperty = createDynaProperty(metadata, i);

if (dynaProperty != null) {

list.add(dynaProperty);

}

}

// Convert this list into the internal data structures we need

properties =

(DynaProperty[]) list.toArray(new DynaProperty[list.size()]);

for (int i = 0; i < properties.length; i++) {

propertiesMap.put(properties[i].getName(), properties[i]);

}

}

protected DynaProperty createDynaProperty(

ResultSetMetaData metadata,

int i)

throws SQLException {

String name = null;

if (lowerCase) {

name = metadata.getColumnName(i).toLowerCase();

} else {

name = metadata.getColumnName(i);

}

String className = null;

try {

className = metadata.getColumnClassName(i);

} catch (SQLException e) {

// this is a patch for HsqlDb to ignore exceptions

// thrown by its metadata implementation

}

// Default to Object type if no class name could be retrieved

// from the metadata

Class clazz = Object.class;

if (className != null) {

clazz = loadClass(className);

}

return new DynaProperty(name, clazz);

}

protected Class loadClass(String className) throws SQLException {

try {

ClassLoader cl = Thread.currentThread().getContextClassLoader();

if (cl == null) {

cl = this.getClass().getClassLoader();

}

return (cl.loadClass(className));

} catch (Exception e) {

throw new SQLException(

"Cannot load column class '" + className + "': " + e);

}

}

}

大部分代码从BeanUtils的源码中取得,只做了简单的修改,没有加多余的注释。如果要正式使用,

需要再做精加工。

BeanUtils: 威力和代价(转载)的更多相关文章

  1. xilinx和altera的fpga的不同之处!----如果不知道,你将为之付出代价! --转载

    本人从2004年接触fpga开始,至今已经8年了.开发过altera的flex系列和cyclone3系列:开发过xilinx的vii和v5系列.下面谈谈本人对二者的一些不同,以便引起开发者对一些细节上 ...

  2. [转载]威力导演14旗舰破解版(中文简体)|取消30天限制CyberLink&nb

               2015月9月15日(当地时间),CyberLink讯连科技发布新一代视频编辑软件 — PowerDirector威力导演14,融合了上个版本发布以来的多次更新升级,威力导演依旧 ...

  3. (转载)BeanUtils.copyProperties() 用法

    BeanUtils.copyProperties() 用法 标签: hibernateuserjdbc数据库strutsjava 2009-10-17 23:04 35498人阅读 评论(6) 收藏  ...

  4. BeanUtils.copyProperties与PropertyUtils.copyProperties用法及区别

    一.简介: BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean 通常包含了大量的属性,很多情况下,对Jav ...

  5. BeanUtils 以及BeanUtils.populate使用

    Apache Jakarta Commons项目非常有用.我曾在许多不同的项目上或直接或间接地使用各种流行的commons组件.其中的一个强大的组件就是BeanUtils.我将说明如何使用BeanUt ...

  6. [转载] Bitmap的秘密

    转载自http://www.infoq.com/cn/articles/the-secret-of-bitmap/ 之前已经参加过几次QCon峰会,不过今年QCon 2014 上海峰会对我来说比较特别 ...

  7. [转载]Linux进程调度原理

    [转载]Linux进程调度原理 Linux进程调度原理 Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更多的任务.调度程序会被频繁的执行,所以调度程序要尽可能的高效: 2.加强交 ...

  8. 转载--C++的反思

    转载自http://blog.csdn.net/yapian8/article/details/46983319 最近两年 C++又有很多人出来追捧,并且追捧者充满了各种优越感,似乎不写 C++你就一 ...

  9. BeanUtils.copyProperties用法

    spring的BeanUtils.copyProperties用法 原创 2010年06月03日 13:43:00 标签: spring / struts / 数据库 / 工具 / action 一. ...

随机推荐

  1. Android Studio tips1

    Android Studio 真机测试出现  device can not found 1.安装与手机版本一样的sdk 2.(重要!!)手机的驱动在电脑上没有正确的安装,安装豌豆荚可以解决!

  2. android ListView 九大重要属性详细分析、

    android ListView 九大重要属性详细分析. 1.android ListView 一些重要属性详解,兄弟朋友可以参考一下. 首先是stackFromBottom属性,这只该属性之后你做好 ...

  3. PadLeft 和 PadRight

    1 PadLeft 即:向已知字符串左边补充字符,使整个字符串到达指定长度 CREATE FUNCTION PadLeft ( ),/*原始字符*/ @TotalLength int,/*总长度*/ ...

  4. try--catch--finally中return返回值执行的顺序(区别)

    1.try块中没有抛出异常,try.catch和finally块中都有return语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public static int ...

  5. C++中类似C# region的功能

    使用#pragma region和#pragma endregion关键字,来定义可以展开和收缩的代码区域的开头和结尾, 可以把这些代码行收缩为一行,以后要查看其细节时,可以再次展开它. 例如: // ...

  6. nginx支持pathinfo并且隐藏index.php

    How To Set Nginx Support PATHINFO URL Model And Hide The /index.php/ 就像这样 The URL before setting lik ...

  7. maven项目报:An error occurred while filtering resources

    maven项目在problem中报: An error occurred while filtering resources   解决方法: 右键项目-maven-update project.. 

  8. 一天一经典Reducing the Dimensionality of Data with Neural Networks [Science2006]

    别看本文没有几页纸,本着把经典的文多读几遍的想法,把它彩印出来看,没想到效果很好,比在屏幕上看着舒服.若用蓝色的笔圈出重点,这篇文章中几乎要全蓝.字字珠玑. Reducing the Dimensio ...

  9. HibernateTemplate的一些常用方法总结

    1:get/load存取单条数据 public Teacher getTeacherById(Long id) { return (Teacher)this.hibernateTemplate.get ...

  10. PHP的字符串函数

      1.字符串的连接 字符串可以使用字符串连接符(.)来连接 常见的用途是建立大块的HTML字串代码,赋值号 (=) 连接符 (.) 可以被简写合并为 (.=) 符号 2.在字符串中使用变量 这个功能 ...