zoukankan      html  css  js  c++  java
  • 数据库操作

    1、DAO模式 ---- 数据访问对象
    将持久层实现完全封装起来(不需要让调用者知道我是使用什么技术实现持久层的)
    所有的数据持久化操作都通过对象来完成
    save(User)
    delete(User)
    update(User)
    User find(id)
    List<User> findAll
    验证:我是否完全按照DAO模式编程---- serlvet中不允许有任何和数据库相关的东西!
    2、PrepareStatement 用来替代Statement 来防止SQL注入
    先编译sql(预编译),后传入参数
    select * from users where name=? and pwd=?; ---- 传入数据库进行遍历  ?只能用来替代变量
    select ? from ? where ? = ? and ?= ?; ---- 无法编译,表名、列名这些都不可以用?代替
    为什么能防止SQL注入?
    select * from users where name='zhangsan' or'1' = '1' and pwd='xxx'; // 在编译时 or会作为关键字进行编译----注入
    select * from users where name=? and pwd=?; 编译
    username --- > zhangsan' or '1'='1 ------ username中or会作为值的一部分进行处理,不会作为关键字 ----- 防止注入!

    编写CustomerCURD程序
    1、数据库、数据表
    * 在企业内,会选择新建一个数据库,新建一个用户(密码)----来管理这个系统
    新建数据库
    create database customer
    新建数据表
    CREATE TABLE `customers` (
      `id` int(11) NOT NULL auto_increment,
      `name` varchar(20) NOT NULL,
      `gender` varchar(10) NOT NULL,
      `birthday` date default NULL,
      `cellphone` varchar(11) default NULL,
      `email` varchar(50) default NULL,
      `preference` varchar(100) default NULL,
      `type` varchar(10) NOT NULL,
      `description` varchar(255) default NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    2、准备开发环境
    新建web工程 -- day9_customer
    导入数据库驱动 --- WEB-INF/lib
    新建目录结构
    cn.itcast.customer.dao ---- 存放所有数据库操作DAO类
    cn.itcast.customer.vo ---- 存放所有数据库表对应值对象
    cn.itcast.customer.util ---- 系统所有的工具类
    cn.itcast.customer.servlet ---- 存放所有Servlet程序
    3、开发
    a、客户信息增加功能
    编写一个客户信息增加 add.jsp
    编写一个客户信息增加 AddServlet
    编写一个客户信息存储类 Customer
    编写一个客户信息DAO操作类 CustomerDAO

    b、编写客户信息查询功能
    **个人开发习惯 1.写页面 2.写DAO 3.测试 4.写Servlet
    当查询到所有客户信息 通过Servlet输出表格时,麻烦!!!! ----- JSP:html文件中可以通过<%%>写java语法
    1)通过request.setAttribute 和 RequestDispatcher.forward 跳转传递数据
    JSP内部
    <%
     List<Customer> customers = (List<Customer>)request.getAttribute("customers");
    %>
    2)JSP 引包???
    <%@page import="java.util.List" %>
    <%@page import="cn.itcast.customer.vo.Customer" %>
    3)嵌套了java和html jsp页面中的循环
    <%
     for(Customer customer:customers){
    %>
     <tr>
      <td>xxx</td>
     </tr>
    <% 
     }
    %>  
    4) 使用java语法向页面输出 :html: <%= XXX %>  ============== java: <% out.print(xxx); %>
    out.print("男"); ====  <%="男"%>
    5) 对于enum类型,可以通过修改toString() 完成输出!
    vip {
      @Override
      public String toString() {
       return "钻石用户";
      }
    }
    插入的时候,不能使用enum的toString 这里会插入中文到数据库
    这个时候 enum name方法
    customer.getType().name()

    c.删除功能
    1、页面链接怎么写
    <td><a href="del?id=<%=customer.getId() %>">删除</a></td>
    2、删除时提供确认 js
    <a href="del?id=<%=customer.getId() %>" onclick="delConfirm();">删除</a>
    当点击删除时,会触发href和onclick 两个事件,onclick会先被触发
    在onclick询问用户是否确认,如果确认,删除,如果用户取消,在onclick中阻止href事件
    function checkJump(event){
      if(event&&event.preventDefault){ // 阻止其它浏览器跳转
       event.preventDefault();
      }else{ // 阻止IE跳转
       window.event.returnValue = false;
      }
     }

    d.修改功能
    1) ViewServlet查询出你要修改那条数据 id --- select * from customers where id = ?
    2) 查询出的数据显示在form表单里 view.jsp
    input text/password/hidden value="<%=xxx %>"
    textarea <textarea><%=xxx%></textarea>
    input radio/checkbox <% if...  checked='checked' %>
    select <option <% if... selected='selected' %>>
    提供一个表单隐藏域:用来存放记录的id
    3) UpdateServlet 接收更新的数据,调用DAO保存
    接收时:定义了Converter、BeanUtils.populate、如果不满足populate列,可以自己手动封装例如:Preference
    4) CustomerDAO.update 方法中,要更新所有的数据!!

    思考:在删除和修改后,不跳转到主页,而直接显示结果??
    在删除DelServlet执行后,直接调用SearchServlet
    resp.sendRedirect("search");
    BeanUtils ---- 封装时候,只能支持基本数据类型和String,如果不是自定义Converter
    封装的时候,表单的字段name属性,必须和JavaBean属性 同样名字,才能自动封装
    BeanUtils.populate(Object,Map);

    敏捷:极限编程XP、测试驱动、快速部署、scrum  ---- 快速迭代模型 3个月内快速迭代下面过程多次
    按照功能开发集成! 可持续集成,任意一个时间点 系统都是可用的
    传统:RUP 瀑布模型 需求---分析---设计---编码---测试---实施---运维 3个月

    JDBC 处理大规模数据
    Text 、Blob 存储大规模数据
    Text(Clob) 大规模文本数据 ---- 大的文档
    Blob 大二进制文件 ----- 电影、图片

    编写Clob练习
    mysql> create table notes(id int not null primary key auto_increment,content longtext);

    编写Blob
    mysql> create table images(id int not null primary key auto_increment,content longblob);

    测试batch使用
    mysql> create table users(id int not null primary key auto_increment,name varchar(20));
      String sql = "insert into users values(null,'lisi')";
      String sql2 = "insert into users values(null,'wangwu')";
      stmt.addBatch(sql);
      stmt.addBatch(sql2);
      stmt.executeBatch();


    在数据库操作中,测试过性能,什么最浪费性能?
    创建和关闭连接!
    **使用Statement批处理,不可以使用预编译SQL语句

      Insert into user(name,password) values(‘aa’,’111’);
      Insert into user(name,password) values(‘bb’,’222’);
      Insert into user(name,password) values(‘cc’,’333’);
      Insert into user(name,password) values(‘dd’,’444’);

    如果使用预编译 insert into user values(?.?); 只需要编译一次
    采用Statement.addBatch(sql)方式实现批处理:
    优点:可以向数据库发送多条不同的SQL语句。
    缺点:SQL语句没有预编译。当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句
    **想使用预编译执行批处理

    采用PreparedStatement.addBatch()实现批处理
    优点:发送的是预编译后的SQL语句,执行效率高。
    缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。

    获得数据库自动生成的主键
    通过PrepareStatement 不可以直接用Statement
    conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS );
    ResultSet rs = pstmt.getGeneratedKeys();
    System.out.println(rs.getObject(1));

  • 相关阅读:
    vue.extend 拓展
    leetcode-166-分数到小数(用余数判断有没有出现小数的循环体)
    leetcode-165-比较版本号
    leetcode-162-寻找峰值
    vector.clear()不能用来清零
    leetcode-209-长度最小的子数组
    leetcode-201-数字范围按位与
    完全多部图的判断(个人思考)
    leetcode-200-岛屿的个数(dfs找所有的连通分量)
    leetcode-151-翻转字符串里的单词
  • 原文地址:https://www.cnblogs.com/qq809306794/p/DAO.html
Copyright © 2011-2022 走看看