第14天dbutils与案例
4. 4.dbutils API详解-QueryRunner类 2
5. 5.dbutils API详解-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类型的数据
进行运算之后,会自动类型提升为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
}
}
效果:
-
案例--注册功能实现
开展工作:
准备工作:
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点积分)