你的位置:首页 > Java教程

[Java教程]第14天dbutils与案例


第14天dbutils与案例

第14天dbutils与案例    1

1.    1.dbutils介绍    2

2.    2.dbutils快速入门    2

3.    3.dbutils API详解-DbUtils类    2

4.    4.dbutils API详解-QueryRunner类    2

5.    5.dbutils API详解-ResultSetHandler    3

6.    6.ResultSetHandler实现类介绍    3

7.    7.案例--添加商品分析    3

8.    8.案例--添加商品实现    4

9.    9.案例--查询全部分析    4

10.    10.案例--查询全部实现    4

11.    11.案例--修改分析    4

12.    12.案例--修改实现    4

 

知识点回顾:

  1. 昨天学习了哪些jstl标签(说出你印象最深刻的)?

     

    Choose when otherwise

    If

    Foreach

    Set

    Out

     

     

  2. JavaBean的特点是哪些?

     

    公开的无参数构造函数

    属性私有化

    提供getter setter方法

     

  3. MVC设计模式中M V C分别指什么?

     

    M 模型

     

    V 视图

     

    C 控制器

     

 

dbutils介绍

 

如何学习新技术:

  1. 百度(谷歌),技术的官方网站
  2. 官方文档和jar包
  3. 创建java工程,导入jar包,进行测试
  4. 制作笔记,将笔记做成技术博客或者存入有道云笔记

 

 

 

DBUtils是什么?

 

作用:帮助java程序员,开发Dao层代码的简单框架。

 

框架作用:它是帮助程序员,提高开发效率的工具。(木工师傅,锯子,锤子。。。)

 

JDBC几技术本身是可以开发dao层代码,那么为什么还需要学习,DBUtils?

 

JDBC技术的弊端分析:

 

回顾day13项目中JDBC代码:

 

需求:操作jdbc数据库,操作user表,获取user表中所有的数据

 

 

代码演示:

// 需求:获取当前user表中所有的数据

    public List<User> findAllUser() {

        // 定义一个链接对象

        Connection conn = null;

        // 定义一个操作sql语句的对象

        PreparedStatement stmt = null;

        // 定义一个封装结果集的对象

        ResultSet rs = null;

 

        try {

            conn = JDBCUtils.getConnection();

            String sql = "select * from user";

            stmt = conn.prepareStatement(sql);

            rs = stmt.executeQuery();

 

            // 准备一个list集合,保存User对象

            List<User> list = new ArrayList<User>();

            while (rs.next()) {

                User u = new User();

                u.setAddress(rs.getString("address"));

                u.setAge(rs.getInt("age"));

                u.setBirthday(rs.getDate("birthday"));

                u.setDescription(rs.getString("description"));

                u.setEmail(rs.getString("email"));

                u.setHobby(rs.getString("hobby"));

                u.setId(rs.getInt("id"));

                u.setName(rs.getString("name"));

                u.setPassword(rs.getString("password"));

                u.setSex(rs.getString("sex"));

 

                list.add(u);

            }

            return list;

        } catch (SQLException e) {

            e.printStackTrace();

            return null;

        } finally {

            // 释放资源

            JDBCUtils.release(rs, stmt, conn);

        }

    }

 

JDBC弊端:

 

  1. 数据库连接对象,sql语句操作对象,封装结果集对象,重复定义
  2. 封装数据的代码重复,而且操作复杂,代码量大
  3. 释放资源的代码重复

 

 

导致:程序员在开发的时候,大量的重复劳动。开发的周期长,效率低

 

  1. 什么是dbutils及其作用

DBUtils:它主要是封装了JDBC的代码,简化了dao层的操作。

 

它主要是封装了JDBC的代码——DBUtils的底层还是JDBC,做了一次简单的封装方便程序员使用。

 

 

DBUtils由Apache公司提供——一个需要Java程序员关注的公司。云计算,谷歌三篇论文,hadoop——大数据技术。

 

 

阿里巴巴技术——大型分布式电商网站,技术特点,能解决高并发,高可用问题

B2B 企业与企业 做生意(电商平台)

B2C 天猫 企业与个人用户(电商平台)

C2C 个人与个人 淘宝(电商平台)

 

阿里云开发者平台,共享了阿里的电商开发的很多技术(云计算,云存储,海量数据分析,智能推荐。。。。。)

 

 

学习新技术的思路:

 

  1. 百度(技术博客,技术论坛,培训机构资料,最重要的是官网)
  2. 下载资料(jar包,API文档)
  3. 创建工程进行测试(先从核心对象开始,一般核心对象都在API文档中)quickstart 快速入门 exemple 示例

     

  4. 笔记,保存好(博客,有道云笔记)

 

 

 

 

下载:DBUtils——http://commons.apache.org/proper/commons-dbutils/

去下载页面:

 

解压:

解压后:

 

 

  1. dbutils三个核心类介绍

学习一个类方式:

  1. 构造方法(先创建对象)
  2. 字段(属性)
  3. 方法(关注返回值,方法名称,参数列表)

 

  1. 连接数据库对象——DbUtils

定义:

 

构造函数:

DbUtils()

 

成员函数:

 

 

 

 

总结:DbUtils,它是一个控制连接,控制事物,控制驱动加载的一个类。

 

注意:今天使用C3P0连接数据库,所以不使用DbUtils类,但是,在关闭资源的时候,会使用到DbUtils,而且这个DbUtils关闭资源的方法,是框架自动调用,不需要程序员,书写java代码,手动调用。

 

 

老师既然不用,为何要学?

作为一个JDBC框架(操作数据库),肯定需要有加载驱动,获取连接,关闭资源的方法,所以DBUtils技术,设计了一个类(DbUtils).

 

那以后我要不要使用DbUtils类?

 

一般来说,不用,以后开发,使用框架,框架内部一般都使用C3P0连接数据库

 

  1. SQL语句的操作对象——QueryRunner(重点:必须掌握)

定义:

 

 

 

 

构造函数:

QueryRunner():创建一个与数据库无关的queryRunner对象,后期在操作数据库的时候,需要手动给一个Connection对象,它可以手动控制事物。

Connection.setAutoCommit(false);设置手动管理事务

Connection.commit();提交事务

 

QueryRunner(DataSource ds):创建一个与数据库关联的queryRunner对象,后期在操作数据库的时候,不需要Connection对象,自动管理事物。

 

 

DataSource参数:就是c3p0数据库连接池对象

 

c3p0数据库连接池对象,它实现类java.sql.DateSource这个接口

 

ComboPooledDataSource extends AbstractPoolBackedDataSource implements PooledDataSource

 

PooledDataSource:PooledDataSource extends DataSource

 

成员方法:

 

增删改方法:

 


update(Connection conn, String sql, Object... params):这是执行添加,修改和删除sql语句的方法,三个参数(数据库连接,sql语句,sql语句的参数)

 

    update(String sql, Object... params):这是执行添加,修改和删除sql语句的方法,两个参数(sql语句,sql语句的参数)

 

 

查询的方法

 

    query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params):这是执行查询sql语句的方法,四个参数(数据库连接,sql语句,封装数据的策略对象,sql语句的参数)

 

query(String sql, ResultSetHandler<T> rsh, Object... params):这是执行查询sql语句的方法,三个参数(sql语句,封装数据的策略对象,sql语句的参数)

 

 

 

构造函数与增删改查方法的组合:

QueryRunner()

    update(Connection conn, String sql, Object... params)

query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)

 

QueryRunner(DataSource ds)

    update(String sql, Object... params)

    query(String sql, ResultSetHandler<T> rsh, Object... params)

 

 

  1. 封装数据的策略对象ResultSetHandler(重点:必须掌握)

策略:封装数据到对象的方式(示例:将数据保存在User、保存到数组、保存到集合)

定义:

 

方法介绍:

 

注意:详解参考ResultSetHandler实现类介绍

 

  1. dbutils快速入门

    1. 导入jar包

      Mysql驱动

      C3P0包

      DBUtils包

    2. 添加C3P0配置文件和JDBCUtils工具类

       

      1. 需要创建一个user对象,与数据库(jdbc)user表对应

    3. 使用QueryRunner对象完成增删改的操作

     

    代码演示:

    //需求:向user表插入一条数据

        @Test

        public void test1(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

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

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                int update = qr.update(sql, "狗蛋","123456");

                System.out.println(update);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

        

        //需求:修改id==7的数据

        @Test

        public void test2(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "update user set name = ? where id = ?";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                int update = qr.update(sql, "柳岩",7);

                System.out.println(update);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

        

        //需求:删除id==7的数据

        @Test

        public void test3(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "delete from user where id = ?";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                int update = qr.update(sql, 7);

                System.out.println(update);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

     

  2. QueryRunner的query方法与ResultSetHandler接口介绍

    1. 自定义实现ResultSetHandler封装查询结果集

    自定义策略:

     

    package cn.itcast.handler;

     

    import java.sql.ResultSet;

    import java.sql.SQLException;

    import java.util.ArrayList;

    import java.util.List;

     

    import org.apache.commons.dbutils.ResultSetHandler;

     

    import cn.itcast.domain.User;

    // ResultSetHandler<T>,<T>表示封装结果的类型

    //MyHandler 是自定义的ResultSetHandler封装结果集策略对象

    public class MyHandler implements ResultSetHandler<List<User>>{

     

        @Override

        public List<User> handle(ResultSet rs) throws SQLException {

            //封装数据,数据从Resultset中获取

     

            List<User> list = new ArrayList<User>();

            while(rs.next()){

                User u = new User();

                u.setId(rs.getInt("id"));

                u.setName(rs.getString("name"));

                u.setPwd(rs.getString("pwd"));

                

                list.add(u);

            }

            return list;

        }

     

    }

     

     

     

    测试代码:

     

        //需求:获取user表中所有的数据

        @Test

        public void test4(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                List<User> list = qr.query(sql, new MyHandler());

                System.out.println(list);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

     

     

    效果:

    总结:

             1)创建queryRunner对象,用来操作数据库

    2)设置一个sql语句,用来操作数据库

    3)根据sql语句,执行相应的方法(insert 、 delete 、update===== update方法 || select=====query方法)

     

     

     

  3. ResultSetHandler实现类介绍(由DBUtils框架给我们提供使用)

     

    实现类的学习方式:先测试,根据测试结果,总结当前实现类的按照什么样的方式封装数据(策略)

     

     

    1. ArrayHandler

    //需求:测试ArrayHandler策略

        //ArrayHandler:将查询结果的第一行数据,保存到Object数组中

        @Test

        public void test5(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                Object[] objects = qr.query(sql, new ArrayHandler());

                for (Object object : objects) {

                    System.out.println(object);

                }

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果:

    1. ArrayListHandler

    //需求:测试ArrayListHandler策略

        //ArrayListHandler:将查询的结果,每一行先封装到Object数组中,然后,将数据存入list集合

        @Test

        public void test6(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                List<Object[]> list = qr.query(sql, new ArrayListHandler());

                for (Object[] objects : list) {

                    for (Object object : objects) {

                        System.out.println(object);

                    }

                    System.out.println("=====");

                }

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果:

    1. BeanHandler(重点:必须掌握)

     

    //需求:测试BeanHandler策略

        //BeanHandler:将查询结果的第一行数据,封装到user对象

        @Test

        public void test7(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                User user = qr.query(sql, new BeanHandler<User>(User.class));

                System.out.println(user);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

     

    效果:

    1. BeanListHandler(重点:必须掌握)

     

    //需求:测试BeanListHandler策略

        //BeanListHandler:将查询结果的每一行封装到user对象,然后,再存入list集合

        @Test

        public void test8(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                List<User> list = qr.query(sql, new BeanListHandler<User>(User.class));

                System.out.println(list);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果:

    1. ColumnListHandler(可指定列封装数据)

    //需求:测试ColumnListHandler策略

        //ColumnListHandler:将查询结果的指定列的数据封装到list集合中

        @Test

        public void test9(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                Object object = qr.query(sql, new ColumnListHandler(2));

                System.out.println(object);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果:

    1. MapHandler

    //需求:测试MapHandler策略

        //MapHandler:将查询结果的第一行数据封装到map集合(key==列名,value==列值)

        @Test

        public void test10(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                Map<String, Object> map = qr.query(sql, new MapHandler());

                System.out.println(map);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果:

    1. MapListHandler

     

    //需求:测试MapListHandler策略

        //MapListHandler:将查询结果的每一行封装到map集合(key==列名,value==列值),再将map集合存入list集合

        @Test

        public void test11(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                List<Map<String, Object>> list = qr.query(sql, new MapListHandler());

                System.out.println(list);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果:

     

    1. BeanMapHandler(可指定列为key值)

        //需求:测试BeanMapHandler策略

        //BeanMapHandler:将查询结果的每一行数据,封装到User对象,再存入map集合中(key==指定的列值,value==User)

        @Test

        public void test12(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                Object object = qr.query(sql, new BeanMapHandler(User.class,2));

                System.out.println(object);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果:

     

    1. KeyedHandler(可指定列为key值)

    //需求:测试KeyedHandler策略

        //KeyedHandler:将查询结果的每一行数据,封装到map1集合(key==列名,value==列值),然后,将map1集合(有多个)存入map2集合(只有一个)

        //map2集合(key==指定的列,value==map1集合)

        @Test

        public void test13(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select * from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                Object object = qr.query(sql, new KeyedHandler());

                System.out.println(object);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

     

    效果:

     

     

    1. ScalarHandler(重点;必须掌握)

     

    //需求:测试ScalarHandler策略

        //ScalarHandler:封装类似count、avg、max、min、sum。。。。函数的执行结果

        @Test

        public void test14(){

            

            //第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第二步:创建sql语句

            String sql = "select count(*) from user";

            //第三步:执行sql语句,params:是sql语句的参数

            //注意,给sql语句设置参数的时候,按照user表中字段的顺序

            try {

                Object object = qr.query(sql, new ScalarHandler());

                System.out.println(object);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果:

     

     

    DBUtils总结:

    1. 它的jar包和API文档在哪里
    2. 核心对象(queryRunner和ResultSetHandler)
    3. 学会使用ResultSetHandler的实现类(beanHandler beanListHandler ScalarHandler)

     

     

     

     

     

    练习案例——用户联系人管理系统

    需求:

    1. 使用本系统的用户必须注册
    2. 用户登录系统后,获取管理联系人权限
    3. 用户管理权限包括(添加、删除、修改、查询联系人)
    4. 展示联系人数据时,数据必须分批次显示(分页技术)

     

    功能列表:

    注册

    登陆

    查询所有联系人

    按条件查询联系人

    添加联系人

    删除联系人

    修改联系人

    分页展示数据

     

    权限:1)在servelt 中做if判断

                    2)将权限的数据保存在配置文件中,用户请求的时候,根据配置文件查看用户是否具有权限。

                    3)使用数据库实现权限管理,涉及5张表

     

     

    补充内容(MD5加密分析):

     

    JDK API:

     

    获取对象的API:

    加密的API:

     

    代码演示:

    package cn.itcast.utils;

     

    import java.security.MessageDigest;

    import java.security.NoSuchAlgorithmException;

     

    /**

    * @author wjn

    * MD5加密工具类

    */

    public class MD5Utils {

     

        public static String getPwd(String pwd){

            //创建加密对象

            try {

                MessageDigest digest = MessageDigest.getInstance("md5");

                

                //调用加密对象的方法,加密的动作已经完成

                byte[] bs = digest.digest(pwd.getBytes());

                //接下来,我们要对加密后的结果,进行优化,按照mysql的优化思路走

                //mysql的优化思路:

                //第一步:将数据全部转换成正数

                String hexString = "";

                for (byte b : bs) {

                    //b,它本来是一个byte类型的数据

                    //255,是一个int类型的数据

                    //b与255进行运算之后,会自动类型提升为int类型

                    //b 1001 1100 原来

                    //b 0000 0000 0000 0000 0000 0000 1001 1100

                    int temp = b & 255;

                    //第二步:将所有的数据,转换成16进制的形式 1F 2B 3c

                    

                    //第三步:解决任意数据,都要输出一个固定长度的字符串

                    if(temp < 16 && temp >= 0){

                        //如果进入判断,表示当前数据,不能转换成两位的16进制格式

                        //那么,我们可以,手动补上一个"0"

                        hexString = hexString +"0"+ Integer.toHexString(temp);

                    }else{

                        hexString = hexString + Integer.toHexString(temp);

                    }

                }

                return hexString;

                

            } catch (NoSuchAlgorithmException e) {

                //NoSuchAlgorithmException没有这个加密的算法

                e.printStackTrace();

                return "";

            }

            

        }

        public static void main(String[] args) {

            String pwd = MD5Utils.getPwd("abc");

            System.out.println(pwd);

            //工具类加密结果: 900150983cd24fb0d6963f7d28e17f72

            //mysql加密结果:900150983cd24fb0d6963f7d28e17f72

        }

    }

     

     

    效果:

     

  4. 案例--注册功能实现

    开展工作:

     

    准备工作:

    1)创建数据库

     

    2)创建web工程

     

     

    3)导入jar包(mysql驱动包、c3p0jar包、DBUtils包、BeanUtils包)

     

    为什么要记住jar包?

    Jar包对应的都是技术,使用什么jar包,使用什么技术。

    后期,使用maven技术管理项目的jar包,使用pom.

    他在管理的时候,都是通过jar包的名称去管理。

     

     

    4)c3p0-config.

     

    1. 导入工具类(JDBCUtils、MD5Utils)

     

     

     

    6)创建与数据库表对应的javabean

    User类:用户实体

     

    Contact类:联系人实体类

     

     

    注册的功能需求明确:

     

    1)用户的操作是什么?

        在页面上输入注册的信息

        提交注册信息

     

    2)页面需要哪些东西?

        需要一个表单,让用户可以输入注册信息

    需要一个提交按钮,将数据发送到服务器

     

    3)服务器如何处理请求?

     

    Servlet要做什么?

        获取用户请求数据(注册信息)

    对验证码做校验,不通过,返回注册页面,

    通过,将数据封装到User对象中

     

     

     

    Service要做什么?

        判断当前用户名是否已经存在

        存在,返回一个标记,告诉servlet,用户名重复    

     

        不存在:

        将用户输入的明文密码进行加密,

    调用dao注册用户

     

     

    Dao要做什么?

     

        对service方法进行支持,注册用户到数据库

     

    4)给用户什么样的响应?

    根据不同的情况,给出不同的响应。

    所有的情况:

    验证码错误

    用户名已经存在

    数据库异常,服务器忙,请稍后再试

     

     

    思考功能的实现基本思路:

     

    1. 用户的操作是什么?
    2. 页面要给用户提供什么东西?
    3. 服务器要做什么事情(servlet service Dao 给用户一个什么样的响应)?

     

     

    1. 画图分析

     

    老师:页面可不可以写表单的验证,使用javascript技术?

    答:可以,注意页面的表单验证,必须前端js验证和后台java代码验证都需要执行。

     

     

     

    页面展示:

     

    1. 代码实现

    Servlet代码:

     

    package cn.itcast.web;

     

    import java.io.IOException;

    import java.lang.reflect.InvocationTargetException;

     

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    import org.apache.commons.beanutils.BeanUtils;

     

    import cn.itcast.domain.User;

    import cn.itcast.service.UserService;

    import cn.itcast.service.impl.UserServiceImpl;

     

    public class RegisterServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            //第一步:接收请求

            request.setCharacterEncoding("utf-8");

            

            //第二步:验证码校验

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

            String servletImg = (String)request.getSession().getAttribute("servletImg");

            //提问:servletImg调用equeals方法好,还是checkImg调用equeals好?

            //答:checkImg因为是用户提交的数据,可能为null,容易发生空指针异常

            if(servletImg.equalsIgnoreCase(checkImg)){

                //验证通过

                //第三步:封装数据

                //bean:数据要被封装到的对象(User)

                //properties :封装了请求参数的map集合

                User u = new User();

                try {

                    BeanUtils.populate(u, request.getParameterMap());

                } catch (Exception e) {

                    e.printStackTrace();

                }

                //单独封装hobby

                String[] values = request.getParameterValues("hobby");

                String hobby = "";

                for (String string : values) {

                    hobby = hobby + ","+string;

                }

                hobby = hobby.substring(1);

                u.setHobby(hobby);

                //封装数据完成

                //第四步:调用service方法

                //提问:老师,我自己写的项目没有使用接口,直接都是类之间调用,这样可以吗?

                //答:不可以,如果是类之间调用,那么你后期,要使用新的类替换原来的内容,那么你需要修改servlet service dao

                //如果使用接口开发,只需要替换实现类即可,操作简单。

                

                UserService userService = new UserServiceImpl();

                int info = userService.register(u);

                //第五步:根据不同返回值,不同处理

                if(info == 1){

                    response.sendRedirect(request.getContextPath()+"/login.jsp");

                    return;

                }else if(info == -1){

                    request.setAttribute("msg", "用户名重复");

                    request.getRequestDispatcher("/register.jsp").forward(request, response);

                    return;

                }else{

                    request.setAttribute("msg", "服务器已经很努力了,请在等我一下下");

                    request.getRequestDispatcher("/register.jsp").forward(request, response);

                    return;

                }

                

            }else{

                //验证不通过

                request.setAttribute("msg", "验证码错误");

                request.getRequestDispatcher("/register.jsp").forward(request, response);

                return;

            }

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

     

    Service代码:

     

    接口:

    package cn.itcast.service;

     

    import cn.itcast.domain.User;

     

    public interface UserService {

     

        /**

         * 注册的方法

         * @param u

         * @return

         */

        int register(User u);

     

    }

     

    实现类:

     

    package cn.itcast.service.impl;

     

    import cn.itcast.dao.UserDao;

    import cn.itcast.dao.impl.UserDaoImpl;

    import cn.itcast.domain.User;

    import cn.itcast.service.UserService;

    import cn.itcast.utils.MD5Utils;

     

    public class UserServiceImpl implements UserService {

     

        private UserDao userDao = new UserDaoImpl();

        @Override

        public int register(User u) {

            // TODO :标记当前的代码写到这里,还没有完成,请继续完成

            // 查询用户是否存在

            User user = userDao.findUserByName(u.getName());

            if(user != null){

                return -1;

            }else{

                // 不存在,先将用户的密码进行加密,然后,注册用户

                String pwd = MD5Utils.getPwd(u.getPassword());

                u.setPassword(pwd);

                

                return userDao.register(u);

            }

        

        }

     

    }

     

     

    Dao代码:

     

    接口:

    package cn.itcast.dao;

     

    import cn.itcast.domain.User;

     

    public interface UserDao {

     

        /**

         * 根据用户名查询数据的方法

         * @param name

         * @return

         */

        User findUserByName(String name);

     

        /**

         * 注册的方法

         * @param u

         * @return

         */

        int register(User u);

     

    }

     

     

    实现类:

    package cn.itcast.dao.impl;

     

    import java.sql.SQLException;

    import java.util.ArrayList;

    import java.util.List;

     

    import org.apache.commons.dbutils.QueryRunner;

    import org.apache.commons.dbutils.handlers.BeanHandler;

     

    import cn.itcast.dao.UserDao;

    import cn.itcast.domain.User;

    import cn.itcast.utils.JDBCUtils;

     

    public class UserDaoImpl implements UserDao {

     

        @Override

        public User findUserByName(String name) {

     

            // 第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            // ctrl+shift+f 格式化代码

            // 第二步:创建sql语句

            String sql = "select * from user where name = ?";

            try {

                User user = qr.query(sql, new BeanHandler<User>(User.class), name);

                return user;

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("获取用户数据失败");

            }

            //throw throws:方法声明 try catch finally 处理异常关键字

        }

     

        @Override

        public int register(User u) {

            // 第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            // 第二步:创建sql语句

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

            //创建一个集合List,用来存放sql语句参数

            List<Object> list = new ArrayList<Object>();

            list.add(u.getName());

            list.add(u.getPassword());

            list.add(u.getAge());

            list.add(u.getSex());

            list.add(u.getEmail());

            list.add(u.getHobby());

            list.add(u.getAddress());

            list.add(u.getDescription());

            list.add(u.getBirthday());

            

            try {

                return qr.update(sql, list.toArray());

            } catch (SQLException e) {

                e.printStackTrace();

                return -2;

            }

        }

     

    }

     

     

     

  5. 案例--登录功能实现(页面显示用户信息)

    1. 画图分析

    画图分析:

     

    1. 代码实现

    Servlet代码:

     

    package cn.itcast.web;

     

    import java.io.IOException;

     

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    import cn.itcast.domain.User;

    import cn.itcast.service.UserService;

    import cn.itcast.service.impl.UserServiceImpl;

     

    public class LoginServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            request.setCharacterEncoding("utf-8");

            //接收请求的参数

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

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

            

            //调用service方法

            UserService userService = new UserServiceImpl();

            User loginUser = userService.login(username,pwd);

            if(loginUser == null){

                request.setAttribute("msg", "用户名或者密码错误");

                request.getRequestDispatcher("/login.jsp").forward(request, response);

                return;

            }else{

                //获取方法的返回值,将数据保存到session,跳转欢迎页面

                request.getSession().setAttribute("loginUser", loginUser);

                response.sendRedirect(request.getContextPath()+"/welcome.jsp");

                return;

            }

            

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

     

     

    Service代码:

    接口:

     

        /**

         * 用户登录的方法

         * @param username

         * @param pwd

         * @return

         */

        User login(String username, String pwd);

     

     

     

    实现类:

    public User login(String username, String pwd) {

            //加密密码

            String password = MD5Utils.getPwd(pwd);

            //登陆用户

            return userDao.login(username,password);

        }

     

     

    DAO代码

     

     

    接口:

    /**

         * 用户登录的方法

         * @param username

         * @param password

         * @return

         */

        User login(String username, String password);

    实现类:

    public User login(String username, String password) {

            // 第一步:创建queryRunner对象,用来操作sql语句

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            // ctrl+shift+f 格式化代码

            // 第二步:创建sql语句

            String sql = "select * from user where name = ? and password = ?";

            try {

                return qr.query(sql, new BeanHandler<User>(User.class), username,password);

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("登陆用户失败");

            }

        }

     

    补充(记住用户名)——希望大家可以课余时间完成:

    1. 使用cookie记住用户名(中文要进行特殊处理——URLEncode.encode())
    2. 使用response发送cookie给浏览器
    3. 在登陆页面显示用户名(使用EL表达式获取),获取的是乱码
    4. 将数据解码(使用javascript技术,使用javascript的全局函数decodeURI())

     

    1. 作业:

     

    1. 总结DBUtils用法(导入那个包、使用那个类操作sql语句、什么sql语句调用什么方法、如何添加参数)(25点积分)
    2. 完成注册功能(50点积分)
    3. 完成登录功能(25点积分)