• 面向接口编程


    1. DAO 模式

    • DAO 模式就是写一个类,把访问数据库的代码封装起来. DAO 在数据库与业务逻辑(Service)之间.
      换句话说, java.sql 包下的内容不能出现在 DAO 层以外.
    • 实体域, 即操作的对象, 例如我们操作的表是 user 表, 那么就需要写一个 User 类;
    • DAO 模式需要先提供 DAO 接口;
    • 然后再提供一个 DAO 接口的实现类;
    • 再编写一个 DAO 工厂, Service 通过工厂来获取 DAO 实现.
    // DAO 层
    public class UserDao{
        public User findByUsername(String username){
    
            private String path="/Users/姓名/Desktop/users.xml;"
    
            // 查找方法
            public User findByUsername(String username){
    
                // 创建解析器
                SAXReader reader = new SAXReader();
    
                try{
                    Document doc = reader.read(path);
                    // 使用 XPath 查找属性为 username 的元素
            Element ele = (Element)doc.selectSingleNode("//user[@username='"+username+"']");
    
                    // 如果没有找到, 返回 null
                    if(ele==null) return null;
    
    
                    // 如果找到了, 返回 User 对象
                    User user = new User();
                    String attrUsername = ele.attributeValue("username");
                    String attrPassword = ele.attributeValue("password");
                    User.setUsername(attrUsername);
                    User.setPassword(attrPassword);
    
                    return user;
                } catch (DocumentException e){
                    throw new RuntimeException(e);
                }
            }
    
            // 添加元素方法
            public void addUser(User user){
    
                // 创建解析器
                SAXReader reader = new SAXReader();
    
                try{
                    Document doc = reader.read(path);
                    Element root = doc.getRootElement();
    
                    // 添加 user 元素
                    Element ele = root.addElement("user");
    
                    // 添加属性
                    ele.addAttribute("username",user.getUsername());
                    ele.addAttribute("password",user.getPassword());
    
                    // 回写
                    OutputFormat format = new OutputFormat("	",true);
                    // 清除原有换行和缩进
                    format.setTrimText(true);
    
                    XMLWriter writer = new XMLWriter(
                                new OutputStreamWriter(
                                    new FileOutputStream(path),"utf-8"),format);
    
                    writer.write(doc);
                    writer.close();
                } catch(Exception e){
                    throw new RuntimeException(e);
                }
            }
        }
    }
    
    // service 层
        public class UserService{
    
            // 因为依赖 Dao 层, 创建 userDao 对象
            private UserDao userDao = new UserDao();
            ....
        }
    
    
    // 升级版
        // 创建 UserDao 接口
        pulic interface UserDao{
            public void addUser(User form);
            public User findByUsername(String username);
        }
    
        // 创建 UserDao 接口的实现类
        public class UserDaoImpl implements UserDao{
            private String path = "/Users/姓名/Desktop/users.xml";
    
            // 查找方法
            public User findByUsername(String username){
    
                // 创建解析器对象
                SAXReader reader = new SAXReader();
    
                try{
                    Document doc = reader.read(path);
              Element ele = (Element)doc.SelectSingleNode("//user@[username='"+username+"']");
    
                    if(ele==null) return null;
    
                    String attrUsername = ele.attributeValue("username");
                    String attrPassword = ele.attributeValue("password");
    
                    User user = new User();
                    user.setUsername(attrUsername);
                    user.setPassword(attrPassword);
                    return user;
                } catch(DocumentException e){
                    throw new RuntimeException(e);
                }
            }
    
            // 添加方法
            public void addUser(User user){
    
                SAXReader reader = new SAXReader();
                try{
                    Document doc = reader.read(path);
                    Element root = doc.getRootElement();
                    Element ele = root.addElement("user");
    
                    ele.addAttribute("username",user.getUsername());
                    ele.addAttribute("password",user.getPassword());
    
                    // 回写 xml
                    OutputFormat format = new OutputFormat("	",true);
                    format.setTrimText(true);
    
                    XMLWriter writer = new XMLWriter(
                                        new OutputStreamWriter(
                                            new FileOutpuStream(path),"utf-8"
                                        ),format);
    
                    writer.write(doc);
                    writer.close();
                } catch(Exception e){
                    throw new RuntimeException(e);
                }
            }
        }
    
    // src 目录下的 dao.properties
    // 其中键为接口名, 值为接口的实现类
        cn.itcast.user.dao.UserDao=cn.itcast.user.dao.UserDaoImpl
    
    
    // 创建 DaoFactory, 提供 getUserDao() 方法
        public class DaoFactory{
    
            private static Properties props = null;
            static{
                // 加载配置文件内容到 props 对象中
                try{
                    InputStream in =
                      DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties");
                    props = new Properties();
                    props.load(in);
    
                }catch(IOException e){
                    throw new RuntimeException(e);
                }
            }
    
    
            public static UserDao getUserDao(){
                // 给出一个配置文件, 文件中给出 UserDao 接口的实现类名称!
                // 我们这个方法, 获取实现类的类名, 通过反射完成创建对象!!
                // 配置文件 dao.properties 在 src 目录下
    
                /*  
                 * 将配置文件中的内容加载到 props 对象中
                 * (因为并不需要每回都加载, 所以放到静态代码块中)
                 * InputStream in =
                 *     DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties");
                 *
                 * Properties props = new Properties();
                 * props.load(in);
                 */
    
                // 得到 dao 实现类的名称
                String daoClassName = props.getProperty("cn.itcast.user.dao.UserDao");
    
                // 通过反射来创建实现类的对象
                try{
                    Class clazz = Class.forName(daoClassName);
                    return (UserDao)clazz.newInstance();
                } catch (Exception e){
                    throw new RuntimeException(e);
                }
            }
        }
    
    
    // service 层
        public class UserService{
    
            // 把具体的实现类的创建, 隐藏到工厂中
            private UserDao userDao = DaoFactory.getUserDao();
    
            .....
        }
    
    
    // 创建一个新类, 实现 UserDao 接口, 操作 MySql 数据库
    // 使用 MySql 数据库, 需要导包 mysql-connector-java
    // 使用 JdbcUtils 小工具类和 dbconfig.properties 来获取 Connection 对象 
        public class JdbcUserDaoImpl implements UserDao{
    
            public User findByUsername(String username){
                Connection con = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                try{
                    // 得到 Connection 对象
                    con = JdbcUtils.getConnection();
    
                    // 准备 sql 模板, 创建 PreparedStatement 对象
                    String sql = "SELECT * FROM user WHERE username=?";
                    pstmt = con.prepareStatement(sql);
    
                    // 为 sql 模板赋值
                    pstmt.setString(1,username);
    
                    // 发送 sql 语句, 返回 ResultSet 对象
                    rs = pstmt.executeQuery();
    
                    if(rs==null) return null;
    
                    // 获取 ResultSet 对象中的内容
                    if(rs.next()){
    
                        // 将 ResultSet 对象中的内容封装到 User 对象中
                        User user = new User();
                        user.setUsername(rs.getString("username"));
                        user.setPassword(rs.getString("password"));
    
                        return user;
                    }else{
                        // 如果第一行内容为空,也返回 null.
                        return null;
                    }
    
                }catch(Exception e){
                    throw new RuntimeException(e);
                }finally{
                    try{
                        if(rs != null) rs.close();
                        if(pstmt != null) pstmt.close();
                        if(con != null) con.close();
                    }catch(Exception e){
                        throw new RuntimeException(e);
                    }
                }
            }
    
            public void addUser(User user){
                Connection con = null;
                PreparedStatement pstmt = null;
    
                try{
                    con = JdbcUtils.getConnection();
    
                    // 创建 sql 模板, 获取 PreparedStatement 对象
                    String sql = "INSERT INTO user VALUES(?,?)";
                    pstmt = con.prepareStatement(sql);
    
                    // 为 sql 模板中的参数赋值
                    pstmt.setString(1,user.getUsername());
                    pstmt.setString(2,user.getPassword());
    
                    // 发送 sql 语句
                    pstmt.executeUpdate();
    
                } catch(Exception e){
                    throw new RuntimeException(e);
                } finally{
                    // 关闭资源
                    try{
                        if(pstmt != null) pstmt.close();
                        if(con != null) con.close();
                    }catch(Exception e){
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    
    // 然后只需要修改 dao.properties 配置文件,
    // 就可以将数据库 从 xml 文件改为 MySql 数据库
    cn.itcast.user.dao.UserDao=cn.itcast.user.dao.JdbcUserDaoImpl
    

    参考资料:

  • 相关阅读:
    true和false
    计算几何算法概览
    pixi.js 总结
    typescript 不用import?
    nodejs 新特性
    p2 碰撞
    Java学习笔记(十四)——Java静态工厂
    Java学习笔记(十三一)——Xml 常用知识总结
    读书笔记(二) ——《恶意》你善良吗?
    Spring学习(二)——Spring中的AOP的初步理解
  • 原文地址:https://www.cnblogs.com/linkworld/p/7619783.html
Copyright © 2020-2023  润新知