用户登陆注册【JDBC版】
前言
在讲解Web开发模式的时候,曾经写过XML版的用户登陆注册案例!现在在原有的项目上,使用数据库版来完成用户的登陆注册!如果不了解的朋友,可以看看我Web开发模式的博文!
本来使用的是XML文件作为小型数据库,现在使用Mysql数据库,代码究竟要改多少呢?我们拭目以待!
使用C3P0数据库连接池
导入C3P0的开发包和导入配置文件
开发包导入的是这个:c3p0-0.9.2-pre1和mchange-commons-0.2.jar
C3P0不仅性能好,而且配置文件可以使用XML文档来配置!
类似的配置文件可以在官方文档上找得到!

我们来改造一下:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<named-config name="mysql">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</named-config>
<named-config name="oracle">
<property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
<property name="jdbcUrl">jdbc:oracle:thin:@//localhost:1521/事例名...</property>
<property name="user">用户名</property>
<property name="password">密码</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</named-config>
</c3p0-config>
写获取连接的工具类
public class DBUtils {
private static ComboPooledDataSource comboPooledDataSource = null;
static {
//它会自动寻找配置文件,节点为mysql的数据库【如果没有指定,就使用默认的!】
comboPooledDataSource = new ComboPooledDataSource("mysql");
}
public static DataSource getDataSource() {
return comboPooledDataSource ;
}
public static Connection getConnection() {
try {
return comboPooledDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("数据库初始化失败了!");
}
}
}
设计数据库表
非常简单,根据实体表来设计就好了!
CREATE TABLE user (
id VARCHAR(20) PRIMARY KEY,
username VARCHAR(20) UNIQUE NOT NULL,
password VARCHAR(20) NOT NULL,
email VARCHAR(20),
birthday DATE
);
写一个操作数据库的Dao实现
public class UserImplDataBase implements UserDao {
@Override
public User find(String username, String password) {
return null;
}
@Override
public void register(User user) {
}
}
下面我们就直接使用DBUtils框架了
- 导入DBUtils的开发包

- 具体的代码如下
@Override
public User find(String username, String password) {
QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
String sql = "SELECT * FROM user WHERE username=? AND password=?";
try {
User user = (User) queryRunner.query(sql, new BeanHandler(User.class), new Object[]{username, password});
return user == null ? null : user;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("登陆失败了!");
}
}
@Override
public void register(User user) {
QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
String sql = "INSERT INTO user (id, username, password, email,birthday) VALUES (?,?,?,?,?);";
String id = user.getId();
String username = user.getUsername();
String password = user.getPassword();
String email = user.getEmail();
Date date = user.getBirthday();
try {
queryRunner.update(sql, new Object[]{id, username, password, email,date});
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("注册失败了");
}
}
}
开发DaoFactory
我们的Dao实现已经有了XML版和JDBC版的,BusinessService调用Dao层方法的时候还是要new出具体的Dao实现,也就是以下的代码:
UserDao userDao = new UserImplXML();
//或者
UserDao userDao= new UserImplDataBase();
这样做有点不够灵活,也就有点不够专业!下面我们来说一下为什么需要DaoFactory?
为什么需要DaoFactory?
参考博文:http://blog.sina.com.cn/s/blog_4ca34d0501008tpc.html
摘抄重点:
优点:
- 透明化:商业对象可以在完全不知道数据源如何具体实现的情况下来使用数据源. 访问数据源是透明的,因为实现细节已经被隐藏进了DAO.
- 迁移简单化:DAO 层的出现,使得应用程序向不同的数据库实现进行迁移变的容易.商业对象可以对底层数据实现一无所知.这样,迁移只涉及到了对DAO层的修改. 另外,如果使用工厂策略,则使为每一种底层数据实现提供一个具体的工厂实现成为可能.在这种情况下,迁移到一种不同的数据实现,其实就相当于为这个应用程序再提供一个新的工厂实现.
- 减少在商业对象中的编程难度:由于DAO管理着所有的数据访问细节,因而大大简化了在商业对象和其他使用DAO的数据客户端里的代码.所有的实现细节相关的代码比如(SQL 语句)都包含在DAO而不在商业对象中. 这样使得代码变的更加健壮而且大大提高了开发效率.
- 将所有的数据访问都单独集中到一层中去: 因为所有的数据访问操作现在都已经被DAO所代理,所以这个单独的数据访问层可以被看作可以是将数据访问实现和其余应用程序相互隔离的一层. 这样的集中,使得应用程序可以更加容易的来维护和管理.
缺点:
- 增加了多余的层:由于DAO在数据客户端和数据源之外多创建了一层对象,因而,需要对他进行设计和实现,来均衡这个设计模式的利弊. 但是,一般来说,采用此设计模式还是利大于弊的.
- 需要对类的相互继承关系进行设计:当使用工厂策略的时候,具体工厂类的继承关系和由这些工厂类生成的产品需要进行设计和实现. 我们需要仔细考虑这些多付出的工作是否真的可以产生出来更高的灵活性. 使用这个策略会使设计变的更加复杂,然而,你可以先从工厂方法模式开始来实现这个策略,然后在需要的情况下再转向抽象工厂
设计DaoFactory
首先,我们把DaoFactory设计成单例的【工厂有一个就够了!】
public class DaoFactory {
private DaoFactory() {
}
private static final DaoFactory DAO_FACTORY = new DaoFactory();
//暴露公开方法获取工厂对象
public static DaoFactory newInstance() {
return DAO_FACTORY;
}
}
目前我们操作的是User,所以工厂造UserDao对象,而UserDao对象是JDBC版呢,还是XML版呢,我们通过配置文件来定(这样就更灵活了)!
- 在src目录下加入配置文件
- 注意:不要加”“字符串的符号!!!!!我就是这里搞了很久!!!!
#class需要的是完整的对象名称(包括包)
#userClass=zhongfucheng.dao.impl.UserImplDataBase
userClass=zhongfucheng.dao.impl.UserImplXML
- 读取配置文件的信息,创建相对应的UserDao对象,直接在构造函数做就行了(其实就是个初始化的操作罢了)
private static UserDao userDao = null;
private DaoFactory() {
try {
//读取配置文件的信息
InputStream inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("UserDao.properties");
Properties properties = new Properties();
properties.load(inputStream);
String userClass = properties.getProperty("userClass");
//利用反射机制创建相对应的对象
userDao = (UserDao) Class.forName(userClass).newInstance();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("读取文件失败了!");
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new RuntimeException("反射失败了!");
} catch (InstantiationException e) {
e.printStackTrace();
throw new RuntimeException("反射失败了!");
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("反射失败了!");
}
}
public static UserDao createUserDao() {
return userDao;
}
在BusinessService层中用DaoFactory获取UserDao对象
UserDao userDao = DaoFactory.newInstance().createUserDao();
测试
如果我们的mysql驱动版本太低,就出现以下的异常!我们只需要下载新的mysql的jar包,导入项目即可!
java.sql.SQLException: Feature not implemented Query:insert into guestbook (id,name,email,url,title,content,time) value(?,?,?,?,?,?,?) Parameters: [1, qwq,wqwq,qwqw,qw,qw, 2010-09-13]
JDBC版的成功的效果如下:

XML版的成功效果如下:
总结
- 由于我们的Service层可能有多种实现【jdbc,xml】,如果我们直接是使用new具体的Service,那么这耦合性就有点高了
- 于是我们有了工厂,工厂的目的就是解耦,我们通过配置文件来创建具体的对象。
用户登陆注册【JDBC版】的更多相关文章
- 《java入门第一季》模拟用户登陆注册案例集合版
需求:校验用户名和密码,登陆成功后玩猜数字小游戏. 在这里先写集合版.后面还有IO版.数据库版. 一.猜数字小游戏类: 猜数字小游戏的代码见博客:http://blog.csdn.net/qq_320 ...
- 函数式编程做用户登陆注册练习-pycharm上
def login(username,password): """ 用户登陆 :param username: 用户名 :param password:密码 :retur ...
- jsp+servlet+mysql简单实现用户登陆注册
原码,项目中遇到的错误,解决方法,文章最后有链接可以获取 项目简介 *有的网友说在修改和删除时会触发error,建议各位不要去把用户名命名为中文! 功能描述 登陆,注册,用户一览表,修改,删除,添加, ...
- django 用户登陆注册
注册登陆 views.py #!/usr/bin/env python # -*- coding:utf- -*- from django.shortcuts import render,render ...
- Python学习笔记_05:使用Flask+MySQL实现用户登陆注册以及增删查改操作
前言:本文代码参考自两篇英文博客,具体来源点击文末代码链接中文档说明. (PS:代码运行Python版本为2.7.14) 运行效果: 首页: 注册页面: 登陆界面: 管理员登陆后界面: 添加.删除.修 ...
- 15_常用API_第15天(Object、String、StringBuffer、用户登陆注册)_讲义
今日内容介绍 1.Object 2.String 3.StringBuilder 01API概念 A:API(Application Programming Interface) 应用程序编程接口 B ...
- 常用API(Object、String、StringBuffer、用户登陆注册)
常用API 今日内容介绍 u Object u String u StringBuilder 第1章 Java的API及Object类 在以前的学习过程中,我们都在学习对象基本特征.对象的使用以及对象 ...
- Android通过Http连接MySQL 实现登陆/注册(数据库+服务器+客户端)
写在最前: 在实际开发中,相信每个项目都会有用户登陆注册功能,这个实现的方法很多,下面是我实现的方法,供大家交流. 新人发帖,万分紧张,怎么样才能装作一副经常发帖的样子不被别人看出来呢-,- ? 好了 ...
- 微信小程序常见两种登陆注册方式(一)
普通登录注册以及用户授权登陆 普通登陆注册 概述 此功能的实现简单的借助了微信小程序的云开发,具体在哪里使用,我会标出来.对于用户名.账号.密码都做了简单的校验.主要练手功能的实现,样式只做了简单的编 ...
随机推荐
- Ubuntu Docker 安装和配置 GitLab CI 持续集成
相关文章: Ubuntu Docker 简单安装 GitLab 劈荆斩棘:Gitlab 部署 CI 持续集成 目的:在 Ubuntu 服务器上,使用 Docker 安装和配置 GitLab Runne ...
- zetcode :: First programs in PyQt5
练习代码,详见网站 http://zetcode.com/gui/pyqt5/firstprograms/ import sys from PyQt5 import QtWidgets from Py ...
- 【渗透笔记】友情检测朋友公司并拿下shell过程
一朋友在一个百货公司上班,由于无聊危险漫步就友情检测了他们公司的网站,开始我们的检测之旅吧. 打开网站,发现网站挺不错,不愧是大卖场,页面做的挺花,但是安全性怎么样呢?来试试吧.先用工具扫了下后台,结 ...
- Stream-快速入门Stream编程
1.什么是流 Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator.原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执 ...
- Eclipse无法打开项目中的任何文件
今天,Eclipse居然打不开项目的任何一个文件,网上也没搜到,我决定重置下视图试试: Windows-Reset Persective-然后能正常打开项目的文件了,解决问题!
- Tomcat闪退的问题
问题:双击tomcat bin下的startup.bat,tomcat的窗口一闪而过,未成功启动: 原因是:在启动tomcat是,需要读取环境变量和配置信息,缺少了这些信息就会导致了tomcat的闪退 ...
- Amazon Aurora解读(SIGMOD 2017)
Amazon在SIGMOD 2017发表了论文<Amazon Aurora: DesignConsiderations for High Throughput Cloud-Native Rela ...
- 常用Git操作
--------------------git-------------------- 1.简介 1.Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.[1] ...
- 堆排序Java实现
package practice; import edu.princeton.cs.algs4.StdRandom; public class TestMain { public static voi ...
- 一、Solr的相关概念了解
1.1. 什么是Solr Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器.Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置.可扩展 ...