用户注册和登录:
本节内容两个知识点:
1.掌握javaEE项目的三层架构
下面对每层进行详细介绍:
每层结构 | 说明 |
---|---|
web层 | com.lihao.web/servlet/controller |
service层 | com.lihao.service service接口包 |
service层 | com.lihao.service.impl service接口实现类 |
dao层 | com.lihao.dao Dao接口包 |
dao层 | com,lihao.dao.impl Dao接口实现类 |
实体bean对象 | com.lihao.pojo/entity/domain/bean javabean 类 |
测试包 | com.lihao.test/junit |
工具类 | com.lihao.utils |
2.完成用户注册和登录
2.1 先创建书城需要的数据库和表
#1.如果存在,删除库
DROP DATABASE IF EXISTS bookshop;
#2.创建数据库
CREATE DATABASE bookshop;
#3.使用数据库
USE bookshop;
#4.创建表
CREATE TABLE t_user(
`id` INT PRIMARY KEY AUTO_INCREMENT,##注意只有int 类型才能够自增
`username` VARCHAR(20) NOT NULL UNIQUE,
`password` VARCHAR(32) NOT NULL,
`email` VARCHAR (200)
);
#5.测试往数据库中插入一条数据
INSERT INTO t_user(`username`,`password`,`email`)VALUES('admin','admin','admin@qq.com');
2.2 编写数据库对应的javaBean对象
2.3 编写DAO层
2.3.1编写之前先导入需要的包:
druid-1.1.1.jar
mysql-connector-java-5.1.7-bin.jar
以下是测试需要的包:
harmcrest-core-1.3.jar
junit-4.12.jar
2.3.2 在src源码目录下编写jdbc.properties属性配置文件:
username=root
password=041811
url=jdbc:mysql://localhost:3306/bookshop
driverClassName=com.mysql.jdbc.Driver
initialSize=5
maxActive=10
2.3.3 编写JDBCUtils工具类
public class JdbcUtils {
//1.创建datasource数据库连接池
public static DruidDataSource dataSource;
//这里使用静态代码块的目的是保证数据库连接池只加载一次:
static {
try {
//1.读取jdbc.properties属性配置文件
Properties pros = new Properties();
//1.1获取工具类的类加载器,并通过getResourceAsStream方法将配置文件中的数据转换为输入流
InputStream resourceAsStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
//2.加载配置文件
pros.load(resourceAsStream);
//3.加载完成之后创建数据库连接池
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(pros);
} catch (Exception e) {
e.printStackTrace();
}
}
//实现获取连接的操作
public static Connection getConnection() {
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
//实现数据库关闭连接的操作
public static void closeConnection(Connection connection){
try {
if(connection!=null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
2.3.4 对JDBCUtils工具类进行测试
测试结果:成功!
2.3.5 根据JDBCUtils编写BaseDao类实现增删改查
编写之前先导入需要的包:commons-dbutils-1.3.jar
public abstract class BaseDao {
//baseDao中提供方法
QueryRunner queryRunner = new QueryRunner();
//1.使用dbutils实现增删改操作
public int update(String sql,Object...args){
//1.获取连接
Connection connection = JdbcUtils.getConnection();
try {
//2.增删改
return queryRunner.update(connection,sql,args);
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.closeConnection(connection);
}
//-1代表失败
return -1;
}
//2.使用dbutils实现查询单个操作,为了抽象化,使用泛型方法实现。
public <T> T queryforOne(String sql, Class<T> clazz, Object... args){
//1.获取连接
Connection connection = JdbcUtils.getConnection();
try {
return queryRunner.query(connection,sql,new BeanHandler<T>(clazz),args);
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils.closeConnection(connection);
}
return null;
}
//3.使用dbutils实现查询多个操作,为了抽象化,使用泛型方法实现。
public <T> List<T> queryforList(String sql, Class<T> clazz, Object... args){
//1.获取连接
Connection connection = JdbcUtils.getConnection();
try {
return queryRunner.query(connection,sql,new BeanListHandler<>(clazz),args);
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils.closeConnection(connection);
}
return null;
}
//3.使用dbutils实现查询单个值.
public Object queryForValue(String sql,Object... args){
//1.获取连接
Connection connection = JdbcUtils.getConnection();
try {
queryRunner.query(connection,sql,new ScalarHandler(),args);
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils.closeConnection(connection);
}
return null;
}
}
2.3.6 编写UserDao和测试
首先编写接口
public interface UserDao {
/**
* 根据用户名查询用户信息
* @param username 用户名
* @return 如果返回null, 这说明没有这个用户。
*/
User queryUserByUsername(String username);
/**
* 根据用户名和密码查询用户信息
* @param username 用户名
* @return 如果返回null, 这说明用户名或者密码错误。反之亦然
*/
User queryUserByUsernameAndPassword(String username,String password);
/**
* 保存用户信息
* @param user
* @return 返回-1表示操作失败,其他是sql语句影响的行数
*/
int saveUser(User user);
}
然后编写实现类
public class UserDaoImpl extends BaseDao implements UserDao {
@Override
public User queryUserByUsername(String username) {
String sql = "select `id`,`username`,`password`,`email` from t_user where `username`=?";
User user = queryforOne(sql, User.class, username);
return user;
}
@Override
public User queryUserByUsernameAndPassword(String username, String password) {
String sql = "select `id`,`username`,`password`,`email` from t_user where `username`=? and `password`=?";
User user = queryforOne(sql, User.class, username,password);
return user;
}
@Override
public int saveUser(User user) {
String sql = "insert into t_user (`username`,`password`,`email`) values (?,?,?)";
int number = update(sql, user.getUsername(),user.getPassword(),user.getEmail());
return number;
}
}
进行测试:
public class UserDaoTest {
UserDao userDao = new UserDaoImpl();
@Test
public void queryUserByUsername() {
User admin = userDao.queryUserByUsername("liming");
System.out.println(admin);
}
@Test
public void queryUserByUsernameAndPassword() {
User user = userDao.queryUserByUsernameAndPassword("admin", "admin");
System.out.println(user);
}
@Test
public void saveUser() {
int liming = userDao.saveUser(new User(null, "liming", "041811", "liming@qq.com"));
System.out.println(liming);
}
}
2.3.7 编写UserService和测试
Userservice接口:
public interface UseService {
/**
* 实现注册用户的功能
* @param user
*/
void registUser(User user);
/**
* 登录
* @param user 如果返回null,则说明登录失败,返回有值,说明登录成功
* @return
*/
User login(User user);
/**
* 检查用户名名是否可用
* @param Username
* @return 返回true表示用户名已经存在,返回false表示用户名可用。
*/
boolean existsUsername(String Username);
}
编写实现类
public class UseServiceImpl implements UseService {
UserDao userDao = new UserDaoImpl();
@Override
public void registUser(User user) {
userDao.saveUser(user);
}
@Override
public User login(User user) {
return userDao.queryUserByUsernameAndPassword(user.getUsername(), user.getPassword());
}
@Override
public boolean existsUsername(String Username) {
//如果用户名已经存在,返回true.
if(userDao.queryUserByUsername(Username)!=null){
return true;
}else {
//如果用户名不存在,返回false.
return false;
}
}
}
进行测试:
public class UseServiceTest {
UseService useService = new UseServiceImpl();
@Test
public void registUser() {
useService.registUser(new User(null,"wzg168","wzg168","wzg168@qq.com"));
}
@Test
public void login() {
System.out.println(useService.login(new User(null, "admin", "admin", null)));
}
@Test
public void existsUsername() {
if(useService.existsUsername("admin1")){
System.out.println("用户名已存在!");
}else{
System.out.println("用户名可用!");
}
}
}
2.3.8 编写servlet程序,实现用户的登录功能和注册功能
public class RegistServlet extends HttpServlet {
UseService useService = new UseServiceImpl();
//2.实现用户的注册功能:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取用户信息
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
String code = req.getParameter("code");
//2.先检查验证码是否正确
if("abcde".equalsIgnoreCase(code)) {
//验证码正确:
if(useService.existsUsername(username)){
//用户名存在
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}else{
//用户名不存在
useService.registUser(new User(null,username,password,email));
req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp);
}
}else {
//验证码不正确:
// "/"表示: http://localhost:8080/book/ 映射到web目录下
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}
}
}
public class LoginServlet extends HttpServlet {
UseService useService = new UseServiceImpl();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//通过用户名和密码验证是否存在此用户
User login = useService.login(new User(null, username, password, null));
if(login!=null){
//则证明存在此用户
request.getRequestDispatcher("/pages/user/login_success.jsp").forward(request,response);
}else{
request.getRequestDispatcher("/pages/user/login.jsp").forward(request,response);
}
}
}