• 网上图书商城项目学习笔记-001工具类测试


    工具类测试

    工具类分析图

    1.BeanHandler

    2.MapHandler

    3.多表查询映射

    1.CommonUtilsTest.java

     1 package cn.itcast.test;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 import org.junit.Test;
     7 
     8 import cn.itcast.commons.CommonUtils;
     9 
    10 /**
    11  * 测试CommonUtils类
    12 // *   CommonUtils类依赖的jar:commons-beanutils.jar、commons-logging.jar
    13  * @author qdmmy6
    14  *
    15  */
    16 public class CommonUtilsTest {
    17     /**
    18      * 测试uuid()
    19      *   返回一个随机的32长的字符串
    20      *  用途:
    21      *  1. 用来做id,数据库表中的主键是不能重复的,它就是不重复的!
    22      *  2. 激活码也是不能重复的!也可以用它
    23      *  
    24      */
    25     @Test
    26     public void testUuid() {
    27         String s = CommonUtils.uuid();
    28         System.out.println(s);
    29     }
    30     
    31     /**
    32      * 作用:把一个map中的数据封装到javabean中
    33      * 要求:
    34      * 1. 要求map中的key名称与javabean中的属性名称相同
    35      */
    36     @Test
    37     public void testToBean() {
    38         /*
    39          * 1. 创建Map
    40          */
    41         Map<String,Object> map = new HashMap<String,Object>();
    42         map.put("pid", "123");
    43         map.put("pname", "张三");
    44         map.put("age", "23");
    45         map.put("xxx", "XXX");
    46         
    47         // 通过map的数据来创建Person类型的JavaBean对象
    48         Person p = CommonUtils.toBean(map, Person.class);
    49         System.out.println(p);
    50     }
    51 }

     源码:CommonUtils.java

     1 package cn.itcast.commons;
     2 
     3 import java.util.Map;
     4 import java.util.UUID;
     5 
     6 import org.apache.commons.beanutils.BeanUtils;
     7 import org.apache.commons.beanutils.ConvertUtils;
     8 
     9 /**
    10  * 小小工具
    11  * @author qdmmy6
    12  *
    13  */
    14 public class CommonUtils {
    15     /**
    16      * 返回一个不重复的字符串
    17      * @return
    18      */
    19     public static String uuid() {
    20         return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    21     }
    22 
    23     /**
    24      * 把map转换成对象
    25      * @param map
    26      * @param clazz
    27      * @return
    28      * 
    29      * 把Map转换成指定类型
    30      */
    31     @SuppressWarnings("rawtypes")
    32     public static <T> T toBean(Map map, Class<T> clazz) {
    33         try {
    34             /*
    35              * 1. 通过参数clazz创建实例
    36              * 2. 使用BeanUtils.populate把map的数据封闭到bean中
    37              */
    38             T bean = clazz.newInstance();
    39             ConvertUtils.register(new DateConverter(), java.util.Date.class);
    40             BeanUtils.populate(bean, map);
    41             return bean;
    42         } catch(Exception e) {
    43             throw new RuntimeException(e);
    44         }
    45     }
    46 }

    2.JdbcUtilsTest.java

     1 package cn.itcast.test;
     2 
     3 import java.sql.Connection;
     4 import java.sql.SQLException;
     5 
     6 import org.junit.Test;
     7 
     8 import cn.itcast.jdbc.JdbcUtils;
     9 
    10 /**
    11  * JdbcUtils用来获取Connection
    12  *   * 底层使用了c3p0连接池!
    13  *   * 还需要mysql驱动
    14  * @author qdmmy6
    15  *
    16  */
    17 public class JdbcUtilsTest {
    18     /**
    19      * 底层使用了c3p0连接池,说明我们还要提供c3p0配置文件
    20      * @throws SQLException 
    21      */
    22     @Test
    23     public void testGetConnection() throws SQLException {
    24         Connection con = JdbcUtils.getConnection();
    25         System.out.println(con);;
    26         JdbcUtils.releaseConnection(con);
    27         System.out.println(con.isClosed());
    28     }
    29     
    30     /**
    31      * JdbcUtilst还提供了与事务相关的功能
    32      * 
    33      */
    34     @Test
    35     public void testTransaction() {
    36         try {
    37             JdbcUtils.beginTransaction();//开启事务
    38             
    39             // 多次操作
    40             
    41             JdbcUtils.commitTransaction();//提交事务
    42         } catch(Exception e) {
    43             try {
    44                 JdbcUtils.rollbackTransaction();//回滚事务
    45             } catch (SQLException e1) {
    46             }
    47         }
    48     }
    49 }

    源码:JdbcUtils.java

     1 package cn.itcast.jdbc;
     2 
     3 import java.sql.Connection;
     4 import java.sql.SQLException;
     5 
     6 import javax.sql.DataSource;
     7 
     8 import com.mchange.v2.c3p0.ComboPooledDataSource;
     9 
    10 /**
    11  * 使用本类的方法,必须提供c3p0-copnfig.xml文件
    12  * @author qdmmy6
    13  */
    14 public class JdbcUtils {
    15     // 饿汉式
    16     private static DataSource ds = new ComboPooledDataSource();
    17     
    18     /**
    19      * 它为null表示没有事务
    20      * 它不为null表示有事务
    21      * 当开启事务时,需要给它赋值
    22      * 当结束事务时,需要给它赋值为null
    23      * 并且在开启事务时,让dao的多个方法共享这个Connection
    24      */
    25     private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
    26     
    27     public static DataSource getDataSource() {
    28         return ds;
    29     }
    30     
    31     /**
    32      * dao使用本方法来获取连接
    33      * @return
    34      * @throws SQLException
    35      */
    36     public static Connection getConnection() throws SQLException {
    37         /*
    38          * 如果有事务,返回当前事务的con
    39          * 如果没有事务,通过连接池返回新的con
    40          */
    41         Connection con = tl.get();//获取当前线程的事务连接
    42         if(con != null) return con;
    43         return ds.getConnection();
    44     }
    45     
    46     /**
    47      * 开启事务
    48      * @throws SQLException 
    49      */
    50     public static void beginTransaction() throws SQLException {
    51         Connection con = tl.get();//获取当前线程的事务连接
    52         if(con != null) throw new SQLException("已经开启了事务,不能重复开启!");
    53         con = ds.getConnection();//给con赋值,表示开启了事务
    54         con.setAutoCommit(false);//设置为手动提交
    55         tl.set(con);//把当前事务连接放到tl中
    56     }
    57     
    58     /**
    59      * 提交事务
    60      * @throws SQLException 
    61      */
    62     public static void commitTransaction() throws SQLException {
    63         Connection con = tl.get();//获取当前线程的事务连接
    64         if(con == null) throw new SQLException("没有事务不能提交!");
    65         con.commit();//提交事务
    66         con.close();//关闭连接
    67         con = null;//表示事务结束!
    68         tl.remove();
    69     }
    70     
    71     /**
    72      * 回滚事务
    73      * @throws SQLException 
    74      */
    75     public static void rollbackTransaction() throws SQLException {
    76         Connection con = tl.get();//获取当前线程的事务连接
    77         if(con == null) throw new SQLException("没有事务不能回滚!");
    78         con.rollback();
    79         con.close();
    80         con = null;
    81         tl.remove();
    82     }
    83     
    84     /**
    85      * 释放Connection
    86      * @param con
    87      * @throws SQLException 
    88      */
    89     public static void releaseConnection(Connection connection) throws SQLException {
    90         Connection con = tl.get();//获取当前线程的事务连接
    91         if(connection != con) {//如果参数连接,与当前事务连接不同,说明这个连接不是当前事务,可以关闭!
    92             if(connection != null &&!connection.isClosed()) {//如果参数连接没有关闭,关闭之!
    93                 connection.close();
    94             }
    95         }
    96     }
    97 }

     

    3.TxQueryRunnerTest.java

      1 package cn.itcast.test;
      2 
      3 import java.sql.SQLException;
      4 import java.util.List;
      5 import java.util.Map;
      6 
      7 import org.apache.commons.dbutils.QueryRunner;
      8 import org.apache.commons.dbutils.handlers.BeanHandler;
      9 import org.apache.commons.dbutils.handlers.BeanListHandler;
     10 import org.apache.commons.dbutils.handlers.MapHandler;
     11 import org.apache.commons.dbutils.handlers.MapListHandler;
     12 import org.apache.commons.dbutils.handlers.ScalarHandler;
     13 import org.junit.Test;
     14 
     15 import cn.itcast.commons.CommonUtils;
     16 import cn.itcast.jdbc.JdbcUtils;
     17 import cn.itcast.jdbc.TxQueryRunner;
     18 
     19 /**
     20  * TxQueryRunner它是QueryRunner的子类!(commons-dbutils.jar)
     21  *   可用起来与QueryRunner相似的!
     22  *   我们的类支持事务!它底层使用了JdbcUtils来获取连接!
     23  *   
     24  * 简化jdbc的操作
     25  * QueryRunner的三个方法:
     26  * * update() --> insert、update、delete
     27  * * query() --> select
     28  * * batch() --> 批处理
     29  * @author qdmmy6
     30  *
     31  */
     32 public class TxQueryRunnerTest {
     33     /**
     34      * 测试update()方法,用来执行insert、update、delete语句
     35      * @throws SQLException
     36      */
     37     @Test
     38     public void testUpdate() throws SQLException {
     39         String sql = "insert into t_person(pid,pname,age,sex) values(?,?,?,?)";
     40         Object[] params = {"1", "p1", 1, "男"};//给sql中对应的参数
     41         
     42         QueryRunner qr = new TxQueryRunner();//我们没有给对象提供连接池
     43         qr.update(sql, params);//执行sql,也不提供连接,它内部会使用JdbcUtils来获取连接
     44     }
     45     
     46     /**
     47      * 使用事务
     48      * @throws SQLException
     49      */
     50     @Test
     51     public void testUpdate2() throws Exception {
     52         try {
     53             JdbcUtils.beginTransaction();//开启事务
     54             
     55             String sql = "insert into t_person(pid,pname,age,sex) values(?,?,?,?)";
     56             QueryRunner qr = new TxQueryRunner();
     57             Object[] params = {"2", "p2", 2, "女"};
     58             qr.update(sql, params);//执行
     59             
     60             if(false) {
     61                 throw new Exception();
     62             }
     63             
     64             params = new Object[]{"3", "p3", 3, "女"};
     65             qr.update(sql, params);//执行            
     66             
     67             JdbcUtils.commitTransaction();//提交事务
     68         } catch(Exception e) {
     69             try {
     70                 JdbcUtils.rollbackTransaction();//回滚事务
     71             } catch (SQLException e1) {
     72             }
     73             throw e;
     74         }        
     75     }
     76     
     77     /**
     78      * 测试查询方法
     79      *   我们知道JDBC查询的结果的是ResultSet
     80      *   而QueryRunner查询的结果是通过ResultSet映射后的数据。
     81      *     * QueryRunner第一步是执行select,得到ResultSet
     82      *     * 把ResultSet转换成其他类型的!
     83      *   通过转换结果:
     84      *      * javaBean:把结果集封装到javaBean中
     85      *      * Map:把结果集封装到Map中
     86      *      * 把结果集封装到Object中(结果集是单行单列)
     87      * @throws SQLException 
     88      *      
     89      *  
     90      */
     91     /*
     92      * 单行结果集映射到javaBean中
     93      */
     94     @Test
     95     public void testQuery1() throws SQLException {
     96         String sql = "select * from t_person where pid=?";
     97         QueryRunner qr = new TxQueryRunner();
     98         /*
     99          * 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
    100          * 
    101          * BeanHandler --> 它是ResultSetHandler的实现类,它的作用是把结果集封装到Person对象中
    102          */
    103         Person p = qr.query(sql, new BeanHandler<Person>(Person.class), "1");
    104         System.out.println(p);
    105     }
    106     
    107     /**
    108      * 使用BeanListHandler
    109      *   把多行结果集映射到List<Bean>,即多个JavaBean对象。
    110      *   一行结果集记录对应一个javaBean对象,多行就对应List<Bean>
    111      * @throws SQLException
    112      */
    113     @Test
    114     public void testQuery2() throws SQLException {
    115         String sql = "select * from t_person";
    116         QueryRunner qr = new TxQueryRunner();
    117         /*
    118          * 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
    119          * 
    120          * BeanListHandler --> 它是ResultSetHandler的实现类,
    121          *   它的作用是把结果集封装到List<Person>对象中
    122          */
    123         List<Person> list = qr.query(sql, new BeanListHandler<Person>(Person.class));
    124         System.out.println(list);
    125     }
    126     
    127     /**
    128      * 使用MapHandler,把单行结果集封装到Map对象中
    129      * @throws SQLException
    130      */
    131     @Test
    132     public void testQuery3() throws SQLException {
    133         String sql = "select * from t_person where pid=?";
    134         QueryRunner qr = new TxQueryRunner();
    135         /*
    136          * 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
    137          * 
    138          * BeanListHandler --> 它是ResultSetHandler的实现类,
    139          *   它的作用是把结果集封装到List<Person>对象中
    140          */
    141         Map<String, Object> map = qr.query(sql, new MapHandler(), "1");
    142         System.out.println(map);
    143     }
    144     
    145     /**
    146      * 使用MapListHandler,把多行结果集封装到List<Map>中,即多个Map
    147      *   一行对应一个Map,多行对应List<Map>
    148      * @throws SQLException
    149      */
    150     @Test
    151     public void testQuery4() throws SQLException {
    152         String sql = "select * from t_person";
    153         QueryRunner qr = new TxQueryRunner();
    154         /*
    155          * 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
    156          * 
    157          * BeanListHandler --> 它是ResultSetHandler的实现类,
    158          *   它的作用是把结果集封装到List<Person>对象中
    159          */
    160         List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
    161         System.out.println(mapList);
    162     }
    163     
    164     /**
    165      * 使用ScalarHandler,把单行单列的结果集封装到Object中
    166      * @throws SQLException
    167      */
    168     @Test
    169     public void testQuery5() throws SQLException {
    170         String sql = "select count(*) from t_person";//结果集是单行单列的
    171         QueryRunner qr = new TxQueryRunner();
    172 
    173         Object obj = qr.query(sql, new ScalarHandler());
    174         /*
    175          * 我们知道select count(1),结果一定是个整数!
    176          * > Integer
    177          * > Long
    178          * > BigInteger
    179          * 
    180          * 不同的驱动,结果不同!
    181          * 无论是哪种类型,它都是Number类型!强转成Number一定不出错
    182          */
    183         Number number = (Number)obj;
    184         long cnt = number.longValue();
    185         System.out.println(cnt);
    186     }
    187     
    188     /**
    189      * 一行结果集中包含了两张表的列
    190      * 使用MapHandler来处理
    191      * 1. 把结果集封装到map中
    192      * 2. 使用map生成Person对象
    193      * 3. 使用map生成address对象
    194      * 4. 把两个实体对象建立关系
    195      * @throws SQLException
    196      */
    197     @Test
    198     public void testQuery6() throws SQLException {
    199         String sql = "SELECT * FROM t_person p, t_address a WHERE p.aid=a.aid AND p.pid=?";
    200         QueryRunner qr = new TxQueryRunner();
    201         /*
    202          * 1. 得到Map
    203          */
    204         Map map = qr.query(sql, new MapHandler(), "aaa");
    205         /*
    206          * 2. 把Map中部分数据封装到Person中
    207          */
    208         Person p = CommonUtils.toBean(map, Person.class);
    209         /*
    210          * 3. 把Map中部分数据封装到Address中
    211          */
    212         Address addr = CommonUtils.toBean(map, Address.class);
    213         /*
    214          * 4. 建立两个实体的关系
    215          */
    216         p.setAddress(addr);
    217         
    218         System.out.println(p);
    219     }
    220 }

     源码:TxQueryRunner.java

     1 package cn.itcast.jdbc;
     2 
     3 import java.sql.Connection;
     4 import java.sql.SQLException;
     5 
     6 import org.apache.commons.dbutils.QueryRunner;
     7 import org.apache.commons.dbutils.ResultSetHandler;
     8 
     9 public class TxQueryRunner extends QueryRunner {
    10 
    11     @Override
    12     public int[] batch(String sql, Object[][] params) throws SQLException {
    13         Connection con = JdbcUtils.getConnection();
    14         int[] result = super.batch(con, sql, params);
    15         JdbcUtils.releaseConnection(con);
    16         return result;
    17     }
    18 
    19     @Override
    20     public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
    21             throws SQLException {
    22         Connection con = JdbcUtils.getConnection();
    23         T result = super.query(con, sql, rsh, params);
    24         JdbcUtils.releaseConnection(con);
    25         return result;
    26     }
    27     
    28     @Override
    29     public <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException {
    30         Connection con = JdbcUtils.getConnection();
    31         T result = super.query(con, sql, rsh);
    32         JdbcUtils.releaseConnection(con);
    33         return result;
    34     }
    35 
    36     @Override
    37     public int update(String sql) throws SQLException {
    38         Connection con = JdbcUtils.getConnection();
    39         int result = super.update(con, sql);
    40         JdbcUtils.releaseConnection(con);
    41         return result;
    42     }
    43 
    44     @Override
    45     public int update(String sql, Object param) throws SQLException {
    46         Connection con = JdbcUtils.getConnection();
    47         int result = super.update(con, sql, param);
    48         JdbcUtils.releaseConnection(con);
    49         return result;
    50     }
    51 
    52     @Override
    53     public int update(String sql, Object... params) throws SQLException {
    54         Connection con = JdbcUtils.getConnection();
    55         int result = super.update(con, sql, params);
    56         JdbcUtils.releaseConnection(con);
    57         return result;
    58     }
    59 }

    源码链接:

    http://pan.baidu.com/s/1pKnA7NH

    小工具

    工欲善其事,必先利其器。下面我们来介绍一下在项目中要使用的小工具(itcast-tools-1.4.jar)。这个小工具底层使用了:

    l  c3p0数据库连接池;

    l  common-beanutils;

    l  common-dbutils;

    l  javaMail;

    1 CommonUtils

    CommonUtils类就两个方法:

    l  String uuid():生成长度32的随机字符,通常用来做实体类的ID。底层使用了UUID类完成;

    l  T toBean(Map, Class<T>):把Map转换成指定类型的Bean对象。通常用来获取表单数据(request.getParameterMap())封装到JavaBean中,底层使用了common-beanutils。注意,本方法要求map中键的名称要与Bean的属性名称相同才能完成映射,否则不能完成映射。

        /**

         * 随机生成32位长的字符串,通常用来做实体类的ID

         */

        @Test

        public void testUuid() {

           String s = CommonUtils.uuid();//生成随机32位长的字符串

           System.out.println(s);

        }

       

        /**

         * 把Map类型映射成Bean类型。

         * 要求map中键的名称与Person类的属性名称相同。

         * 即map的key分别为:pid、name、age、birthday,person的属性名称也是pid、name、age、birthday

         */

        @Test

        public void testToBean() {

           Map<String,String> map = new HashMap<String,String>();

           /*

            * map的key:pid、age、birthday、myname

            * person的属性:pid、age、birthday、name

            * map中没有名为name的键值,而多出一个名为myname的键值,所以映射后的person对象的name属性值为null。

            * map中的age和birthday都是字符串类型,而person的age是int类型、birthday是Date类型,但toBean()方法会自动对Map中值进行类型转换。

            */

           map.put("pid", CommonUtils.uuid());

           map.put("age", "23");

           map.put("birthday", "2014-01-30");

           map.put("myname", "张三");

          

           Person p = CommonUtils.toBean(map, Person.class);

           System.out.println(p);

        }

    2 JdbcUtils

    JdbcUtils用来获取Connection对象,以及开启和关闭事务。

    l  Connection getConnection():从c3p0连接池获取Connection对象,所以需要提供c3p0-config.xml配置文件;

    l  beginTransaction():为当前线程开启事务;

    l  commitTransaction():提交当前线程的事务;

    l  rollbackTransaction():回滚当前线程的事务;

    l  releaseConnection(Connection):如果参数连接对象不是当前事务的连接对象,那么关闭它,否则什么都不做;

    c3p0-config.xml

    <?xml version="1.0" encoding="UTF-8" ?>

    <c3p0-config>

        <default-config>

           <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>

           <property name="driverClass">com.mysql.jdbc.Driver</property>

           <property name="user">root</property>

           <property name="password">123</property>

          

           <property name="acquireIncrement">3</property>

           <property name="initialPoolSize">10</property>

           <property name="minPoolSize">2</property>

           <property name="maxPoolSize">10</property>

        </default-config>

    </c3p0-config>

    JdbcUtilsTest.java

    /**

     * 测试JdbcUtils类

     * @author qdmmy6

     *

     */

    public class JdbcUtilsTest {

        /**

         * 通过C3P0连接池获取连接对象

         * @throws SQLException

         */

        @Test

        public void testGetConnection() throws SQLException {

           Connection con = JdbcUtils.getConnection();//获取连接

           System.out.println(con);

           JdbcUtils.releaseConnection(con);//如果参数con不是当前线程的连接对象,那么关闭之

        }

       

        /**

         * 当开始事务后,调用getConnection()会为当前线程创建Connection,而且多次调用getConnection()返回的是同一个对象

         * @throws SQLException

         */

        @Test

        public void testTansaction() throws SQLException {

           JdbcUtils.beginTransaction();//开启事务

           Connection c1 = JdbcUtils.getConnection();//第一次获取当前线程的事务连接对象

           Connection c2 = JdbcUtils.getConnection();//第二次获取当前线程的事务连接对象

           Assert.assertEquals(true, c1 == c2);//比较两次是否相同

           JdbcUtils.commitTransaction();//提交事务

        }

    }

    3 TxQueryRunner

    TxQueryRunner类是common-dbutils下QueryRunner类的子类,用来简化JDBC操作。TxQueryRunner类内部使用了JdbcUtils.getConnection()类来获取连接对象,以及使用JdbcUtils.releaseConnection()关闭连接。

    l  int[] batch(String sql, Object[][] params):执行批处理,参数sql是SQL语句模板,params为参数;

    l  T query(String sql, ResultSetHandler<T> rh):执行查询,执行查询,参数sql为要执行的查询语句模板,rh是结果集处理,用来把结果集映射成你想要的结果;

    l  T query(String sql, ResultSetHandler<T> rh, Object… params):执行查询,参数sql为要执行的查询语句模板,rh是结果集处理,用来把结果集映射成你想要的结果,params是sql语句的参数;

    l  int update(String sql):执行增、删、改语句,参数sql是要执行的SQL语句;

    l  int update(Stringsql, Object param):执行增、删、改语句,参数sql是要执行的SQL语句,参数param是参数(一个参数);

    l  int update(String sql, Object… params):执行增、删、改语句,参数sql是要执行的SQL语句,参数params是参数(多个参数);

    为了测试TxQueryRunner,我们在mydb1数据库下创建t_person表,然后再创建Person实体类,以及PersonDao类,最后测试PersonDao类中的方法。

    t_person

    字段

    说明

    pid

    主键

    name

    姓名

    age

    年龄

    birthday

    生日

    Person.java

    public class Person {

        private String pid;

        private String name;

        private int age;

        private Date birthday;

    }

    PersonDao.java

    /**

     * 测试TxQueryRunner

     * @author qdmmy6

     *

     */

    public class PersonDao {

        private QueryRunner qr = new TxQueryRunner();

       

        public void add(Person person) throws SQLException {

           String sql = "insert into t_person values(?,?,?,?)";

           Object[] params = {person.getPid(),

                  person.getName(),

                  person.getAge(),

                  new java.sql.Date(person.getBirthday().getTime())};

           qr.update(sql, params);

        }

       

        public void edit(Person person) throws SQLException {

           String sql = "update t_person set name=?,age=?,birthday=? where pid=?";

           Object[] params = {

                  person.getName(),

                  person.getAge(),

                  new java.sql.Date(person.getBirthday().getTime()),

                  person.getPid()};

           qr.update(sql, params);

        }

       

        public void delete(String pid) throws SQLException {

           String sql = "delete from t_person where pid=?";

           qr.update(sql, pid);

        }

       

        public Person load(String pid) throws SQLException {

           String sql = "select * from t_person where pid=?";

           return qr.query(sql, new BeanHandler<Person>(Person.class), pid);

        }

       

        public List<Person> findAll() throws SQLException {

           String sql = "select * from t_person";

           return qr.query(sql, new BeanListHandler<Person>(Person.class));

        }

    }

    PersonDaoTest.java

    public class PersonDaoTest {

        @Test

        public void testAdd() throws SQLException {

           Person p1 = new Person(CommonUtils.uuid(), "张三", 18, new Date());

           Person p2 = new Person(CommonUtils.uuid(), "李四", 81, new Date());

           Person p3 = new Person(CommonUtils.uuid(), "王五", 66, new Date());

          

           PersonDao dao = new PersonDao();

           dao.add(p1);

           dao.add(p2);

           dao.add(p3);

        }

       

        @Test

        public void testEdit() throws SQLException {

           PersonDao dao = new PersonDao();

           Person person = dao.load("2F371BE415984DE89781CCCA7B8734CB");

           person.setAge(88);

           dao.edit(person);

        }

       

        @Test

        public void testDelete() throws SQLException {

           PersonDao dao = new PersonDao();

           dao.delete("2F371BE415984DE89781CCCA7B8734CB");

        }

       

        @Test

        public void testFindAll() throws SQLException {

           PersonDao dao = new PersonDao();

           List<Person> list = dao.findAll();

           System.out.println(list);

        }

    }

    4 MailUtils

    MailUtils是用来发邮件的小工具,底层使用JavaMail完成,所以它这件事mail.jar和activaion.jar。

    MailUtilsTest.java

        /**

         * 测试发送普通邮件

         * @throws IOException

         * @throws MessagingException

         */

        @Test

        public void fun() throws MessagingException, IOException {

           Session session = MailUtils.createSession("smtp.163.com", "itcast_cxf", "itcastitcast");[q1] 

           Mail mail = new Mail("itcast_cxf@163.com", "itcast_cxf@126.com", "测试MailUtils", "这是正文!");[q2] 

           MailUtils.send(session, mail);[q3] 

        }

    5 BaseServlet

    BaseServlet是用来作为其它Servlet父类的,它有如下两个优点:

    一个Servlet多个处理方法

    BaseServlet的作用是用来简化Servlet。通过我们需要为每个功能编写一个Servlet,例如用户注册写一个RegistServlet,用户登录写一个LoginServlet。如果使用BaseServlet,那么我们可以只写一个UserServlet,然后让UserServlet去继承BaseServlet,然后在UserServlet给出两个请求处理方法,一个方法叫regist(),一个叫login()。

    BaseServlet来简化了Servlet中请求转发和重定向的代码。

     

    简化了请求转发和重定向的代码

    BaseServlet中的请求处理方法有一个String类型的返回值,返回值表示转发或重定向的目标页面。例如:

    l  f:/index.jsp:其中f:表示转发,即forward的意思,/index.jsp表示转发到/index.jsp页面;

    l  r:/index.jsp:其中r:表示重定向,即redirect的意思,/index.jsp表示重定向到/index.jsp页面。

    l  null:表示不转发也不重定向;

    因为BaseServlet中可以有多个请求处理方法,所以在访问BaseServlet时一定要给出名为method的参数来指定要请求的方法名称。

    AServlet.java

    public class AServlet extends BaseServlet {

        /**

         * 请求处理方法的参数都与doGet()和doPost()相同,即request和response

         * 但请求处理方法有String类型的返回值,而doGet()和doPost()没有返回值。

         * 在请求本方法时需要给出method=regist参数!

         */

        public String regist[q4] (HttpServletRequest req, HttpServletResponse resp)

               throws ServletException, IOException {

           System.out.println("AServlet regist()...");

           return "f:/index.jsp";[q5] 

        }

       

        /**

         * 在请求本方法时需要给出method=login参数!

         */

        public String login[q6] (HttpServletRequest req, HttpServletResponse resp)

               throws ServletException, IOException {

           System.out.println("AServlet login()...");

           return "r:/index.jsp"[q7] ;

        }

    }

    6 EncodingFilter

    EncodingFilter用来处理请求编码问题。

    我们知道,如果是POST请求,我们需要调用request.setCharacterEncoding(“utf-8”)方法来设计编码;如果是GET请求,我们需要自己手动来处理编码问题。如果我们使用了EncodingFilter,那么就处理了POST和GET请求的编码问题。

    web.xml

    <filter>

        <filter-name>EncdoingFilter</filter-name>

        <filter-class>cn.itcast.filter.EncodingFilter</filter-class>

    </filter>

    <filter-mapping>

        <filter-name>EncdoingFilter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

    index.jsp

    <a href="<c:url value='/EncodingServlet?method=test[q8] &name=张三'/>">点击这里发出GET请求</a><br/>

    <form action="<c:url value='/EncodingServlet'/>" method="post">

      <input type="hidden" name="method" value="test"/>[q9] 

      <input type="text" name="name" value="李四"/>

      <input type="submit" value="请求这里发出POST请求"/>

    </form>

    EncodingServlet

    /**

     * 测试EncodingFilter

     * @author qdmmy6

     *

     */

    public class EncodingServlet [q10] extends BaseServlet {

        /**

         * 可以使用POST和GET两种方式请求test()方法!查看输出是否为乱码!

         */

        public String test(HttpServletRequest request, HttpServletResponse response)

               throws ServletException, IOException {

           String name = request.getParameter("name");

           System.out.println(name);

           return null;

        }

    }

    7 VerifyCodeServlet(一次性验证码)

    通过在表单中总是需要使用一次性验证码,这一问题可以使用VerifyCodeServlet来处理。让<img>元素的src指向VerifyCodeServlet即可在页面中生成一次性验证码。而且VerifyCodeServlet还会把验证码保存到session中,名称为:vCode,也就是说,你可以通过session来获取验证码文本:session.getAttribute(“vCode”)。

    web.xml

    <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>cn.itcast.vcode.servlet.VerifyCodeServlet</servlet-class>

    </servlet>

    <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/VerifyCodeServlet</url-pattern>

    </servlet-mapping>

    MyJsp.jsp

    <form action="<c:url value='/UserServlet'/>" method="post">

        <input type="hidden" name="method" value="regist"/>

        验证码:<input type="text" name="verifyCode"/>

        <img src="<c:url value='/VerifyCodeServlet'/>"[q11]  border="1"/><br/>

        <input type="submit" value="注册"/>

    </form>

      因为用户可能看不清楚图片上的文本,所以我们需要给用户提供一个“换一张”超链接。其实实现这一步很简单,只需要使用javascript让<img>元素src指向VerifyCodeServlet即可。但因为浏览器可能会缓存上一次生成的图片,所以我们还需要使用时间为参数“强迫”浏览器访问服务器,而不是使用缓存。

    MyJsp.jsp

        <script type="text/javascript" src="<c:url value='/js/jquery-1.5.1.js'/>"></script>[q12] 

        <script type="text/javascript">

           function change[q13] () {

               $("#img").attr("src", "<c:url value='/VerifyCodeServlet?'/>" + new Date().getTime());[q14] 

           }

        </script>

    <form action="<c:url value='/UserServlet'/>" method="post">

        <input type="hidden" name="method" value="regist"/>

        验证码:<input type="text" name="verifyCode"/>

        <img id="img"[q15]  src="<c:url value='/VerifyCodeServlet'/>" border="1"/>

        <a href="javascript:change();">换一张</a>[q16] 

        <br/>

        <input type="submit" value="注册"/>

    </form>

    当用户在表单中填写了验证码,而且提交了表单,到达UserServlet的regist()方法,在regist() 方法中需要比较用户在表单中输入的验证码,与验证码图片上的文本是否相同。

    l  获取用户输入的验证码:request.getParameter(“verifyCode”);

    l  获取图片上的验证码:session.getAttribute(“vCode”);


     [q1]创建session

     [q2]创建邮箱对象,参数分别为:发件人、收件人、主题、正文

     [q3]发送邮件

     [q4]访问本方法的URL为http://localhost:8080/day01/AServlet?method=regist

     [q5]转发到/index.jsp页面

     [q6]访问本方法的URL为http://localhost:8080/day01/AServlet?method=login

     [q7]重定向到/index.jsp

     [q8]请求EncdoingServlet的test方法

     [q9]请求EncodingServlet的test方法

     [q10]因为添加了EncodingFilter过滤器,那么所有的Servlet都不用再去处理请求编码的问题了。

     [q11]让<img>的src指向VerifyCodeServlet即可生成一次性验证码

     [q12]导入jquery

     [q13]在点击“换一张”时会调用本方法

     [q14]指定<img>元素的src属性值为VerifyCodeServlet,并且追加参数为当前时间毫秒,它是不会重复的值,所以浏览器不会使用缓存,而是访问服务器。

     [q15]指定id为img,方法使用jquery来查找该元素。

     [q16]点击该超链接会调用change()方法

  • 相关阅读:
    Android UI开发 popupwindow介绍以及代码实例
    前端之Android入门(5) – MVC模式(下)
    前端之Android入门(4) – MVC模式(中)
    前端之Android入门(3) – MVC模式(上)
    前端之Android入门(2) – 程序目录及UI简介
    前端之Android入门(1) – 环境配置
    android之SQLite数据库应用(二)
    android之SQLite数据库应用(一)
    android 裁剪图片大小 控制图片尺寸
    Android应用盈利广告平台的嵌入方法详解
  • 原文地址:https://www.cnblogs.com/shamgod/p/5153264.html
Copyright © 2020-2023  润新知