第14天dbutils与案例

时间:2022-04-19 15:13:54

第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/

去下载页面:

第14天dbutils与案例

第14天dbutils与案例

解压:

第14天dbutils与案例

解压后:

第14天dbutils与案例

第14天dbutils与案例

  1. dbutils三个核心类介绍

学习一个类方式:

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

定义:

第14天dbutils与案例

构造函数:

DbUtils()

第14天dbutils与案例

成员函数:

第14天dbutils与案例

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

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

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

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

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

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

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

定义:

第14天dbutils与案例

构造函数:

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、保存到数组、保存到集合)

定义:

第14天dbutils与案例

方法介绍:

第14天dbutils与案例

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

  1. dbutils快速入门

    1. 导入jar包

      Mysql驱动

      C3P0包

      DBUtils包

      第14天dbutils与案例

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

      第14天dbutils与案例

      第14天dbutils与案例

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

      第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    总结:

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    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();

    }

    }

    效果:

    第14天dbutils与案例

    DBUtils总结:

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

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

    需求:

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

    功能列表:

    注册

    登陆

    查询所有联系人

    按条件查询联系人

    添加联系人

    删除联系人

    修改联系人

    分页展示数据

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

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

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

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

    第14天dbutils与案例

    JDK API:

    第14天dbutils与案例

    获取对象的API:

    第14天dbutils与案例

    加密的API:

    第14天dbutils与案例

    代码演示:

    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类型的数据

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

    //b 1001 1100 原来

    //b 0000 0000 0000 0000 0000 0000 1001 1100

    int temp = b & 255;

    进制的形式 1F 2B 3c

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

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

    进制格式

    //那么,我们可以,手动补上一个"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

    }

    }

    效果:

    第14天dbutils与案例

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

    开展工作:

    准备工作:

    1)创建数据库

    第14天dbutils与案例

    2)创建web工程

    第14天dbutils与案例

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

    第14天dbutils与案例

    为什么要记住jar包?

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

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

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

    4)c3p0-config.xml配置文件

    第14天dbutils与案例

    第14天dbutils与案例

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

    第14天dbutils与案例

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

    User类:用户实体

    第14天dbutils与案例

    Contact类:联系人实体类

    第14天dbutils与案例

    注册的功能需求明确:

    1)用户的操作是什么?

    在页面上输入注册的信息

    提交注册信息

    2)页面需要哪些东西?

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

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

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

    Servlet要做什么?

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

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

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

    Service要做什么?

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

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

    不存在:

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

    调用dao注册用户

    Dao要做什么?

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

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

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

    所有的情况:

    验证码错误

    用户名已经存在

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

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

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

    第14天dbutils与案例

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

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

    页面展示:

    第14天dbutils与案例

    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. 画图分析

    第14天dbutils与案例

    画图分析:

    第14天dbutils与案例

    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点积分)