JavaWeb笔记-16-面向接口编程与DAO模式、登陆注册(面向接口)、实现对数据库的注册

面向接口编程与DAO模式


1、面向接口编程:

目标:在实现类改变时可以不修改源代码,只修改配置文件即可

        当客户需求变化时,只需编写该业务逻辑的新的实现类,
        通过更改配置文件(例如Spring框架)中该接口的实现类就可以完成需求。

使功能依赖接口,而不是实现类。方便实现类的改变。

将接口实现的产出,定义在工厂里。  
        需要什么功能,就从工厂取什么功能。

原则:开闭原则。可添加,不可改动

2、DAO模式(Data Access Object):

    1)是面向接口编程思想的体现。
    2)是一个把访问数据库的代码封装起来的类。
    3)DAO存在于数据库与业务逻辑(Service)之间。

实现DAO模式:
    1)提供一个DAO接口;
    2)提供一个DAO接口的实现类;
    3)编写一个DAO工厂,Service通过工厂来获取DAO实现。

3、修改登陆注册案例:


修改目标:1)使功能依赖接口。方便实现类的改变。
                 在实现类改变时可以不修改源代码,只修改配置文件即可
         2)实现对数据库的注册操作      
修改项目:
    1.  把UserDao修改为接口,
    2.  把原来的UserDao修改类名为UserDaoImpl
    3.修改UserService中对UserDao的实例化:private UserDao userDao = DaoFactory.getUserDao()
    4.  创建DaoFactory,提供getUserDao()


propertiess文件 存储键值对的文件
接口名,实现类名。

1. 把UserDao修改为接口 ,

public interface UserDao {
    public User findByUsername(String username);
    public void add(User user);
}

2、把原来的UserDao类名修改为UserDaoImpl 实现对数据库的注册操作

/**
 * 针对数据库的实现。
 * 
 * @author 一万年行不行
 * 
 */
public class JdbcUserDaoImpl implements UserDao {
    @Override
    public User findByUsername(String username) {
        PreparedStatement pstmt = null;
        Connection con = null;
        ResultSet rs = null;
        try {
            // 得到连接
            con = JdbcUtils.getConnection();
            // 准备sql模板,得到pstmt
            String sql = "SELECT * FROM t_user WHERE username=?";
            pstmt = con.prepareStatement(sql);
            // 为参数赋值
            pstmt.setString(1, username);

            //执行
            rs = pstmt.executeQuery();          

            //把rs转为user类型
            if(rs == null){  //不存在,返回null
                return null;
            }
            if(rs.next()){  //存在 ,转为user对象返回
                //ORM -->  对象关系映射
                User user = new User();
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));

                return user;
            }else{
                return null;
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally{
            try{
                if(pstmt != null) pstmt.close();
                if(con != null) con.close();
            }catch(SQLException e){}
        }

    }

    @Override
    public void add(User form) {
        PreparedStatement pstmt = null;
        Connection con = null;
        try {
            // 得到连接
            con = JdbcUtils.getConnection();
            // 准备sql模板,得到pstmt
            String sql = "INSERT INTO t_user VALUES(?,?)";
            pstmt = con.prepareStatement(sql);
            // 为参数赋值
            pstmt.setString(1, form.getUsername());
            pstmt.setString(2, form.getPassword());

            // 执行
            pstmt.executeUpdate();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally{
            try{
                if(pstmt != null) pstmt.close();
                if(con != null) con.close();
            }catch(SQLException e){}
        }

    }
}

2.修改UserService中对UserDao的实例化:

    private UserDao userDao = DaoFactory.getUserDao()

3. 创建DaoFactory,提供getUserDao()

/**
 * 目标:返回一个具体的UserDao实现类对象
 * 
 * 1、静态代码块首先加载配置文件到对象中
 * 2、通过配置文件得到dao实现类的名称
 * 3、通过类名称,完成创建类对象
 * 
 * @return
 */
public class DaoFactory {
    private static Properties props = null;
    static{
        try {
            //加载配置文件到props对象中 
            // .class 得到(调用者)当前类class文件字节码对象。 
            //Classloader() 类加载器负责将 .class文件 加载到内存中,并生成对应的Class对象
            //.getResourceAsStream();查找具有给定名称的资源。

            //通过类对象得到用类加载器,得到资源 返回为流
            InputStream in = DaoFactory.class.getClassLoader()
                    .getResourceAsStream("dao.properties");

            //加载键值对数据
            props = new Properties();
            //加载流(库文件)到props对象中。
            props.load(in);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    // 设为静态,使工厂可以直接调用,不用new出实例对象
    public static UserDao getUserDao() {
        // return new UserDaoImpl;
        // 这种方式返回,在将来修改实现类时仍旧需要修改实现类,极不便利
        /**
         * 将功能存放在配置文件中,增强功能适用性 给出一个配置文件,配置文件中给出接口的实现类名称
         * 
         * 此方法作用: 获取文件中实现类类名,通过反射完成创建对象
         */
        //获取dao实现类的类名
        String daoClassName = props.getProperty("dao.UserDao");

        //通过类名反射创建实现类对象。    
        Class clazz = null;
        try {
            clazz = Class.forName(daoClassName);
            return (UserDao) clazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41307491/article/details/81449167