最近用新的一套web框架做项目,有很多常用的包集成在里面。
这里总结一下:
每天总结三个
commons-dbutil.jar:
对传统操作数据库的类进行二次封装,可以把结果集转化成 List
(1)org.apache.commons.dbutils
DbUtils : 提供如关闭连接、装载 JDBC 驱动程序等常规工作的工具类
QueryRunner : 该类简单化了 SQL 查询,它与 ResultSetHandler 组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
QueryLoader : 属性文件加载器,主要用于加载属性文件中的 SQL 到内存中。
(2)org.apache.commons.dbutils.handlers
ArrayHandler :将ResultSet中第一行的数据转化成对象数组 ArrayListHandler将ResultSet中所有的数据转化成List,List中存放的是Object[]
BeanHandler :将ResultSet中第一行的数据转化成类对象
BeanListHandler :将ResultSet中所有的数据转化成List,List中存放的是类对象
ColumnListHandler :将ResultSet中某一列的数据存成List,List中存放的是Object对象
KeyedHandler :将ResultSet中存成映射,key为某一列对应为Map。Map中存放的是数据
MapHandler :将ResultSet中第一行的数据存成Map映射
MapListHandler :将ResultSet中所有的数据存成List。List中存放的是Map
ScalarHandler :将ResultSet中一条记录的其中某一列的数据存成Object
(3)org.apache.commons.dbutils.wrappers
SqlNullCheckedResultSet :该类是用来对sql语句执行完成之后的的数值进行null的替换。
StringTrimmedResultSet :去除ResultSet中中字段的左右空格。Trim()
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import java.util.Map; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.MapListHandler; public class DbutilsJDBCTest{ public static void main(String[] args) { Connection conn = null; String jdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK"; String jdbcDriver = "com.mysql.jdbc.Driver"; try { DbUtils.loadDriver(jdbcDriver); // Username "root". Password "root" conn = DriverManager.getConnection(jdbcURL, "root", "root"); QueryRunner qRunner = new QueryRunner(); System.out.println("***Using MapListHandler***"); //以下部分代码采用Map存储方式,可以采用Bean的方式代替进行处理 List lMap = (List) qRunner.query(conn, "select title,authors from books", new MapListHandler()); //以下是处理代码,可以抽取出来 System.out.println("title ------------- authors "); for (int i = 0; i < lMap.size(); i++) { Map vals = (Map) lMap.get(i); System.out.println(vals.get("title")+"-------------"+ vals.get("authors")); } } catch (SQLException ex) { ex.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } } /** 上例在处理结果集时,它把数据库中的每一行映射成一个Map,其中列名作为Key,该列对应的值作为Value存放, 查询的所有的数据一起放在一个List里,然后进行处理,当然,一个更明智的处理是直接返回List然后再单独进行处理。 事实上上例返回的结果集中的每一行不必放在一个Map里,你可以放在一个Bean里, 如果使用Bean而不是用Map,那么,你也许需要建立一个Bean,如下: **/ package cn.qtone.test; public class Book { public int id; public String title; public String authors ; public StudentBean() { } public String getAuthors() { return authors; } public void setAuthors(String authors) { this.authors = authors; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } /** 然后简单修改一下DbutilsJDBCTest 中的部分代码即可,代替之后的源代码如下: **/ import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import java.util.Map; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler; public class DbutilsJDBCTest{ public static void main(String[] args) { Connection conn = null; String jdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK"; String jdbcDriver = "com.mysql.jdbc.Driver"; try { DbUtils.loadDriver(jdbcDriver); // Username "root". Password "root" conn = DriverManager.getConnection(jdbcURL, "root", "root"); QueryRunner qRunner = new QueryRunner(); System.out.println("***Using BeanListHandler ***"); //以下部分代码采用Map存储方式,可以采用Bean的方式代替进行处理 List lBeans = (List) qRunner.query(conn," select title,authors from books ", new BeanListHandler(Book.class)); //以下是处理代码,可以抽取出来 System.out.println("title ------------- authors "); for (int i = 0; i < lBeans.size(); i++) { Book vals = (Book) lBeans.get(i); System.out.println(vals.getTitle ()+"-------------"+ vals. getAuthors ()); } } catch (SQLException ex) { ex.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } } /** 采用Map的方式即第一种方式性能要好的多,采用Bean性能比较低可能是因为采用反射的缘故, 采用反射的东东性能和不采用反射的还是有点差距。 **/
commons-mail.jar:
是对 JavaMail进行封装从而简化其操作,
功能:简单文本邮件、带附件的邮件、HTML格式的邮件
代码说明:
// 简单文本邮件 SimpleEmail email = new SimpleEmail(); email.setHostName("mail.fastunit.com"); email.setAuthentication("[email protected]", "***");//邮件服务器验证:用户名/密码 email.setCharset("UTF-8");// 必须放在前面,否则乱码 email.addTo("[email protected]"); email.setFrom("[email protected]", "support"); email.setSubject("subject中文"); email.setMsg("msg中文"); email.send(); // 带附件的邮件 MultiPartEmail email = new MultiPartEmail(); email.setHostName("mail.fastunit.com"); email.setAuthentication("[email protected]", "***"); email.setCharset("UTF-8"); email.addTo("[email protected]"); email.setFrom("[email protected]", "support"); email.setSubject("subject中文"); email.setMsg("msg中文"); EmailAttachment attachment = new EmailAttachment(); attachment.setPath("d:/a.gif");// 本地文件 // attachment.setURL(new URL("http://xxx/a.gif"));//远程文件 attachment.setDisposition(EmailAttachment.ATTACHMENT); attachment.setDescription("a"); attachment.setName("a"); email.attach(attachment); email.send(); // HTML格式邮件 HtmlEmail email = new HtmlEmail(); email.setHostName("mail.fastunit.com"); email.setAuthentication("[email protected]", "***"); email.setCharset("UTF-8"); email.addTo("[email protected]"); email.setFrom("[email protected]", "support"); email.setSubject("subject中文"); email.setHtmlMsg("<b>msg中文</b>"); email.send(); /**** 一些问题:首先是jar包的问题,因为不是只下载commons-mail的jar包, 如果是jdk1.5或者1.5以下的版本,还需要下载sun的mail.jar和jaf的jar包, 如果是jdk6的话只需要mail.jar就可以了。具体下载地址去sun网站自己找找就行了, 然后就是要开启邮箱的smtp服务,具体的进入邮箱进行设置就可以了。一般都很简单。 最后就是gmail,gmail跟其他的邮箱的不同之处在于它的默认端口不是普通的25, 而是465,所以需要在程序中动态设置一下,设置的具体方法就是: email.setSSL(Boolean.TRUE); // 设定是否使用SSL email.setSslSmtpPort("465"); // 设定SSL端口 ***/
Commons-Chain.jar: (参考)
Chain提供实现组织复杂的处理流程的“责任链模式”。
(1).Command接口。它是Commons Chain中最重要的接口,表示在Chain中的具体某一步要执行的命令。它只有一个方法:boolean execute(Context context)。如果返回true,那么表示Chain的处理结束,Chain中的其他命令不会被调用;返回false,则Chain会继续调用下一个Command,直到:
-Command返回true;
-Command抛出异常;
-Chain的末尾;
(2).Context接口。它表示命令执行的上下文,在命令间实现共享信息的传递。Context接口的父接口是Map,ContextBase实现了Context。对于web环境,可以使用WebContext类及其子类(FacesWebContext、PortletWebContext和ServletWebContext)。
(3).Chain接口。它表示“命令链”,要在其中执行的命令,需要先添加到Chain中。Chain的父接口是Command,ChainBase实现了它。
(4).Filter接口。它的父接口是Command,它是一种特殊的Command。除了Command的execute,它还包括一个方法:boolean postprocess(Context context,Exception exception)。Commons Chain会在执行了Filter的execute方法之后,执行postprocess(不论Chain以何种方式结束)。Filter的执行execute的顺序与Filter出现在Chain中出现的位置一致,但是执行postprocess顺序与之相反。如:如果连续定义了filter1和filter2,那么execute的执行顺序是:filter1->filter2;而postprocess的执行顺序是:filter2->filter1。
(5).Catalog接口。它是逻辑命名的Chain和Command集合。通过使用它,Command的调用者不需要了解具体实现Command的类名,只需要通过名字就可以获取所需要的Command实例。
public class Command1 implements Command { public boolean execute(Context arg0) throws Exception { System.out.println("Command1 is done!"); return false; } } public class Command2 implements Command { public boolean execute(Context arg0) throws Exception { System.out.println("Command2 is done!"); return false; } } public class Command3 implements Command { public boolean execute(Context arg0) throws Exception { System.out.println("Command3 is done!"); return true; } }
public class CommandChain extends ChainBase { //增加命令的顺序也决定了执行命令的顺序 public CommandChain(){ addCommand( new Command1()); addCommand( new Command2()); addCommand( new Command3()); } public static void main(String[] args) throws Exception{ Command process = new CommandChain(); Context ctx= new ContextBase(); process.execute( ctx); } }
<?xml version="1.0" encoding="gb2312"?> <catalog> <chain name="CommandChain"> <!-- 定义的顺序决定执行的顺序 --> <command id="command1" className= "chain.Command1"/> <command id="command2" className= "chain.Command2"/> <command id="command3" className= "chain.Command3"/> </chain> <command name="command4" className="chain.Command1"/> </catalog>
public class CatalogLoader { static final String cfgFile= "/chain/chain-cfg.xml"; public static void main(String[] args) throws Exception{ CatalogLoader loader= new CatalogLoader(); ConfigParser parser= new ConfigParser(); parser.parse( loader.getClass().getResource( cfgFile)); Catalog catalog= CatalogFactoryBase.getInstance().getCatalog(); //加载Chain Command cmd= catalog.getCommand("CommandChain"); Context ctx= new ContextBase(); cmd.execute( ctx); //加载Command cmd= catalog.getCommand( "command4"); cmd.execute( ctx); } }
<context-param> <param-name>org.apache.commons.chain.CONFIG_CLASS_RESOURCE</param-name> <param-value>resources/catalog.xml</param-value> </context-param> <listener> <listener-class>org.apache.commons.chain.web.ChainListener</listener-class> </listener>
public class Filter1 implements Filter { public boolean postprocess(Context arg0, Exception arg1) { System.out.println("Filter1 is after done!"); return false; } public boolean execute(Context arg0) throws Exception { System.out.println("Filter1 is done!"); return false; } }
<command id="filter1" className= "chain.Filter1"/> Filter的还有一个常用的用法:对于异常的过滤。当Command抛出异常时,最终中会返回到最开始的调用处。有时期望不抛出这些异常,而在内部消化掉,那么就可以利用Filter。因为Commons Chain确保会调用已经执行了execute方法的Filter的postprocess方法,即使在出现异常时也是如此。因此,对应的 postprocess方法可以写为: public boolean postprocess(Context arg0, Exception arg1) { //返回true,表示非空异常已被处理,无需再抛出。 //否则,异常会被抛出 if( null!= arg1) return true; else return false; }
<?xml version="1.0" encoding="UTF-8"?> <catalog> <chain name="CommandChain"> <command id="command1" className= "chain.Command1"/> <command id="filter1" className= "chain.Filter1"/> <command className="org.apache.commons.chain.generic.LookupCommand" name="chain_command3" optional="true"/> <command id="command2" className= "chain.Command2"/> </chain> <chain name="chain_command3"> <command id="command3" className= "chain.Command3"/> </chain> </catalog>
<?xml version="1.0" encoding="gb2312"?> <catalog> <!-- Command的别名,以后直接使用即可 --> <define name="command1" className="chain.Command1"/> <define name="command2" className="chain.Command2"/> <define name="command3" className="chain.Command3"/> <define name="filter1" className="chain.Filter1"/> <define name="lookupCommand" className="org.apache.commons.chain.generic.LookupCommand"/> <chain name="CommandChain"> <command1 id="1"/> <filter1 id="2"/> <lookupCommand name="chain_command3" optional="true"/> <command2 id="3"/> </chain> <chain name="chain_command3"> <command3 id="3"/> </chain> <command1 name="command4"/> </catalog>