用户登录注册【JDBC版】

前言

在讲解Web开发模式的时候,曾经写过XML版的用户登录注册案例!如今在原有的项目上,使用数据库版来完成用户的登录注册!若是不了解的朋友,能够看看我Web开发模式的博文!html

原本使用的是XML文件做为小型数据库,如今使用Mysql数据库,代码究竟要改多少呢?咱们拭目以待!java

使用C3P0数据库链接池

导入C3P0的开发包和导入配置文件

开发包导入的是这个:c3p0-0.9.2-pre1和mchange-commons-0.2.jar.mysql

C3P0不只性能好,并且配置文件可使用XML文档来配置!sql

相似的配置文件能够在官方文档上找获得数据库

咱们来改造一下:编程

<?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框架了oracle

  • 导入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?ide

为何须要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版的成功效果以下:

这里写图片描述


总结
  1. 因为咱们的Service层可能有多种实现【jdbc,xml】,若是咱们直接是使用new具体的Service,那么这耦合性就有点高了
  2. 因而咱们有了工厂,工厂的目的就是解耦,咱们经过配置文件来建立具体的对象。
相关文章
相关标签/搜索