第14天dbutils与案例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第14天dbutils与案例相关的知识,希望对你有一定的参考价值。
第14天dbutils与案例
3.????3.dbutils API详解-DbUtils类????2
4.????4.dbutils API详解-QueryRunner类????2
5.????5.dbutils API详解-ResultSetHandler????3
6.????6.ResultSetHandler实现类介绍????3
?
知识点回顾:
- 昨天学习了哪些jstl标签(说出你印象最深刻的)?
?
Choose when otherwise
If
Foreach
Set
Out
?
?
- JavaBean的特点是哪些?
?
公开的无参数构造函数
属性私有化
提供getter setter方法
?
- MVC设计模式中M V C分别指什么?
?
M 模型
?
V 视图
?
C 控制器
?
?
dbutils介绍
?
如何学习新技术:
- 百度(谷歌),技术的官方网站
- 官方文档和jar包
- 创建java工程,导入jar包,进行测试
- 制作笔记,将笔记做成技术博客或者存入有道云笔记
?
?
?
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弊端:
?
- 数据库连接对象,sql语句操作对象,封装结果集对象,重复定义
- 封装数据的代码重复,而且操作复杂,代码量大
- 释放资源的代码重复
?
?
导致:程序员在开发的时候,大量的重复劳动。开发的周期长,效率低
?
什么是dbutils及其作用
DBUtils:它主要是封装了JDBC的代码,简化了dao层的操作。
?
它主要是封装了JDBC的代码——DBUtils的底层还是JDBC,做了一次简单的封装方便程序员使用。
?
?
DBUtils由Apache公司提供——一个需要Java程序员关注的公司。云计算,谷歌三篇论文,hadoop——大数据技术。
?
?
阿里巴巴技术——大型分布式电商网站,技术特点,能解决高并发,高可用问题
B2B 企业与企业 做生意(电商平台)
B2C 天猫 企业与个人用户(电商平台)
C2C 个人与个人 淘宝(电商平台)
?
阿里云开发者平台,共享了阿里的电商开发的很多技术(云计算,云存储,海量数据分析,智能推荐。。。。。)
?
?
学习新技术的思路:
?
- 百度(技术博客,技术论坛,培训机构资料,最重要的是官网)
- 下载资料(jar包,API文档)
- 创建工程进行测试(先从核心对象开始,一般核心对象都在API文档中)quickstart 快速入门 exemple 示例
?
- 笔记,保存好(博客,有道云笔记)
?
?
?
?
下载:DBUtils——http://commons.apache.org/proper/commons-dbutils/
去下载页面:
?
解压:
解压后:
?
?
dbutils三个核心类介绍
学习一个类方式:
- 构造方法(先创建对象)
- 字段(属性)
- 方法(关注返回值,方法名称,参数列表)
?
连接数据库对象——DbUtils
定义:
?
构造函数:
DbUtils()
?
成员函数:
?
?
?
?
总结:DbUtils,它是一个控制连接,控制事物,控制驱动加载的一个类。
?
注意:今天使用C3P0连接数据库,所以不使用DbUtils类,但是,在关闭资源的时候,会使用到DbUtils,而且这个DbUtils关闭资源的方法,是框架自动调用,不需要程序员,书写java代码,手动调用。
?
?
老师既然不用,为何要学?
作为一个JDBC框架(操作数据库),肯定需要有加载驱动,获取连接,关闭资源的方法,所以DBUtils技术,设计了一个类(DbUtils).
?
那以后我要不要使用DbUtils类?
?
一般来说,不用,以后开发,使用框架,框架内部一般都使用C3P0连接数据库
?
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)
?
?
封装数据的策略对象ResultSetHandler(重点:必须掌握)
策略:封装数据到对象的方式(示例:将数据保存在User、保存到数组、保存到集合)
定义:
?
方法介绍:
?
注意:详解参考ResultSetHandler实现类介绍
?
dbutils快速入门
导入jar包
mysql驱动
C3P0包
DBUtils包
添加C3P0配置文件和JDBCUtils工具类
?
需要创建一个user对象,与数据库(jdbc)user表对应
使用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();
????????}
????}
?
QueryRunner的query方法与ResultSetHandler接口介绍
自定义实现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方法)
?
?
?
ResultSetHandler实现类介绍(由DBUtils框架给我们提供使用)
?
实现类的学习方式:先测试,根据测试结果,总结当前实现类的按照什么样的方式封装数据(策略)
?
?
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();
????????}
????}
效果:
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();
????????}
????}
效果:
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();
????????}
????}
?
效果:
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();
????????}
????}
效果:
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();
????????}
????}
效果:
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();
????????}
????}
效果:
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();
????????}
????}
效果:
?
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();
????????}
????}
效果:
?
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();
????????}
????}
?
效果:
?
?
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总结:
- 它的jar包和API文档在哪里
- 核心对象(queryRunner和ResultSetHandler)
- 学会使用ResultSetHandler的实现类(beanHandler beanListHandler ScalarHandler)
?
?
?
?
?
练习案例——用户联系人管理系统
需求:
- 使用本系统的用户必须注册
- 用户登录系统后,获取管理联系人权限
- 用户管理权限包括(添加、删除、修改、查询联系人)
- 展示联系人数据时,数据必须分批次显示(分页技术)
?
功能列表:
注册
登陆
查询所有联系人
按条件查询联系人
添加联系人
删除联系人
修改联系人
分页展示数据
?
权限: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
????}
}
?
?
效果:
?
案例--注册功能实现
开展工作:
?
准备工作:
1)创建数据库
?
2)创建web工程
?
?
3)导入jar包(mysql驱动包、c3p0jar包、DBUtils包、BeanUtils包)
?
为什么要记住jar包?
Jar包对应的都是技术,使用什么jar包,使用什么技术。
后期,使用maven技术管理项目的jar包,使用pom.xml文件管理jar包
他在管理的时候,都是通过jar包的名称去管理。
?
?
4)c3p0-config.xml配置文件
?
- 导入工具类(JDBCUtils、MD5Utils)
?
?
?
6)创建与数据库表对应的javabean
User类:用户实体
?
Contact类:联系人实体类
?
?
注册的功能需求明确:
?
1)用户的操作是什么?
????在页面上输入注册的信息
????提交注册信息
?
2)页面需要哪些东西?
????需要一个表单,让用户可以输入注册信息
需要一个提交按钮,将数据发送到服务器
?
3)服务器如何处理请求?
?
Servlet要做什么?
????获取用户请求数据(注册信息)
对验证码做校验,不通过,返回注册页面,
通过,将数据封装到User对象中
?
?
?
Service要做什么?
????判断当前用户名是否已经存在
????存在,返回一个标记,告诉servlet,用户名重复????
?
????不存在:
????将用户输入的明文密码进行加密,
调用dao注册用户
?
?
Dao要做什么?
?
????对service方法进行支持,注册用户到数据库
?
4)给用户什么样的响应?
根据不同的情况,给出不同的响应。
所有的情况:
验证码错误
用户名已经存在
数据库异常,服务器忙,请稍后再试
?
?
思考功能的实现基本思路:
?
- 用户的操作是什么?
- 页面要给用户提供什么东西?
- 服务器要做什么事情(servlet service Dao 给用户一个什么样的响应)?
?
?
画图分析
?
老师:页面可不可以写表单的验证,使用javascript技术?
答:可以,注意页面的表单验证,必须前端js验证和后台java代码验证都需要执行。
?
?
?
页面展示:
?
代码实现
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;
????????}
????}
?
}
?
?
?
案例--登录功能实现(页面显示用户信息)
画图分析
画图分析:
?
代码实现
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("登陆用户失败");
????????}
????}
?
补充(记住用户名)——希望大家可以课余时间完成:
- 使用cookie记住用户名(中文要进行特殊处理——URLEncode.encode())
- 使用response发送cookie给浏览器
- 在登陆页面显示用户名(使用EL表达式获取),获取的是乱码
- 将数据解码(使用javascript技术,使用javascript的全局函数decodeURI())
?
作业:
?
- 总结DBUtils用法(导入那个包、使用那个类操作sql语句、什么sql语句调用什么方法、如何添加参数)(25点积分)
- 完成注册功能(50点积分)
- 完成登录功能(25点积分)
以上是关于第14天dbutils与案例的主要内容,如果未能解决你的问题,请参考以下文章
第三十天-加强2-多表查询&JDBC&连接池&DBUtils&综合案例悟空教程