A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© csbl 初级黑马   /  2018-5-21 16:26  /  647 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  学习体会
没有JDBC的时候,如果现在要开发一套系统,使用Java连接MySQL数据库,那么这时候Java程序员需要了解MySQL驱动API,如果使用Java连接Oracle数据库,那么这个时候Java程序员需要了解Oracle数据库驱动API。
SUN公司提供一套统一的规范(接口)。然后各个数据库生产商提供这套接口的实现。这套接口规范就是JDBC的规范。
file:///C:/Users/lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
这个方法可以完成驱动的注册,但是实际开发中一般不会使用这个方法完成驱动的注册!!!
原因:
如果需要注册驱动,就会使用DriverManager.registerDriver(newDriver());,但是查看源代码发现,在代码中有一段静态代码块,静态代码块已经调用了注册驱动的方法。
file:///C:/Users/lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg
这个方法就是用来获得与数据库连接的方法:这个方法中有三个参数
file:///C:/Users/lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg
file:///C:/Users/lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image008.jpg
file:///C:/Users/lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image010.jpg
Statement                         :执行SQL
CallableStatement           :执行数据库中存储过程
PreparedStatement         :执行SQL.对SQL进行预处理。解决SQL注入漏洞。
DBC程序执行结束后,将与数据库进行交互的对象释放掉,通常是ResultSet,Statement,Connection。
这几个对象中尤其是Connection对象是非常稀有的。这个对象一定要做到尽量晚创建,尽早释放掉。
if(rs !=null){
                try {
                   rs.close();
                }catch (SQLException e) {
                   e.printStackTrace();
                }
               
                rs = null;
            }
            
            if(statement!=null){
                try {
                   statement.close();
                }catch (SQLException e) {
                   e.printStackTrace();
                }
               
                statement = null;
            }
            
            
            if(conn !=null){
                try {
                   conn.close();
                }catch (SQLException e) {
                   e.printStackTrace();
                }
               
                conn = null;
            }
因为传统JDBC的开发,注册驱动,获得连接,释放资源这些代码都是重复编写的。所以可以将重复的代码提取到一个类中来完成。
/**
* JDBC的工具类
* @author jt
*
*/
public class JDBCUtils {
    private static final String driverClassName;
    private static final String url;
    private static final String username;
    private static final String password;
   
    static{
        driverClassName="com.mysql.jdbc.Driver";
        url="jdbc:mysql:///web_test3";
        username="root";
        password="abc";
    }
    /**
     * 注册驱动的方法
     */
    public static void loadDriver(){
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }
   
    /**
     * 获得连接的方法
     */
    public static Connection getConnection(){
        Connection conn = null;
        try{
            // 将驱动一并注册:
            loadDriver();
            // 获得连接
            conn = DriverManager.getConnection(url,username, password);
        }catch(Exception e){
            e.printStackTrace();
        }
        return conn;
    }
   
    /**
     * 释放资源的方法
     */
    public static void release(Statement stmt,Connectionconn){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
            stmt = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
   
    public static void release(ResultSet rs,Statement stmt,Connectionconn){
        // 资源释放:
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
            rs = null;
        }
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
            stmt = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}
@Test
    /**
     * 查询操作:使用工具类
     */
    public void demo1(){
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try{
            // 获得连接:
            conn = JDBCUtils.getConnection();
            // 创建执行SQL语句的对象:
            stmt = conn.createStatement();
            // 编写SQL:
            String sql = "select* from user";
            // 执行查询:
            rs = stmt.executeQuery(sql);
            // 遍历结果集:
            while(rs.next()){
                System.out.println(rs.getInt("id")+""+rs.getString("username")+""+rs.getString("password"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            // 释放资源:
            JDBCUtils.release(rs, stmt,conn);
        }
    }
在早期互联网上SQL注入漏洞普遍存在。有一个网站,用户需要进行注册,用户注册以后根据用户名和密码完成登录。假设现在用户名已经被其他人知道了,但是其他人不知道你的密码,也可以登录到网站上进行相应的操作。
需要采用PreparedStatement对象解决SQL注入漏洞。这个对象将SQL预先进行编译,使用?作为占位符。?所代表内容是SQL所固定。再次传入变量(包含SQL的关键字)。这个时候也不会识别这些关键字。
public class UserDao {
   
    public boolean login(String username,Stringpassword){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        // 定义一个变量:
        boolean flag = false;
        try{
            // 获得连接:
            conn = JDBCUtils.getConnection();
            // 编写SQL语句:
            String sql = "select* from user where username = ? and password = ?";
            // 预编译SQL
            pstmt = conn.prepareStatement(sql);
            // 设置参数:
            pstmt.setString(1, username);
            pstmt.setString(2, password);
            // 执行SQL语句:
            rs = pstmt.executeQuery();
            if(rs.next()){
                // 说明根据用户名和密码可以查询到这条记录
                flag = true;
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(rs, pstmt, conn);
        }
        return flag;
    }
之前进行JDBC的操作的时候,都是一条SQL语句执行。现在如果使用批处理,可以将一批SQL一起执行。
@Test
    /**
     * 批处理基本操作
     */
    public void demo1(){
        Connection conn = null;
        Statement stmt = null;
        try{
            // 获得连接:
            conn = JDBCUtils.getConnection();
            // 创建执行批处理对象:
            stmt = conn.createStatement();
            // 编写一批SQL语句:
            String sql1 = "createdatabase test1";
            String sql2 = "usetest1";
            String sql3 = "createtable user(id int primary key auto_increment,name varchar(20))";
            String sql4 = "insertinto user values (null,'aaa')";
            String sql5 = "insertinto user values (null,'bbb')";
            String sql6 = "insertinto user values (null,'ccc')";
            String sql7 = "updateuser set name = 'mmm' where id = 2";
            String sql8 = "deletefrom user where id = 1";
            // 添加到批处理
            stmt.addBatch(sql1);
            stmt.addBatch(sql2);
            stmt.addBatch(sql3);
            stmt.addBatch(sql4);
            stmt.addBatch(sql5);
            stmt.addBatch(sql6);
            stmt.addBatch(sql7);
            stmt.addBatch(sql8);
            // 执行批处理:
            stmt.executeBatch();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(stmt, conn);
        }
    }
@Test
    /**
     * 批量插入记录:
     * * 默认情况下MySQL批处理没有开启的,需要在url后面拼接一个参数即可。
     */
    public void demo2(){
        // 记录开始时间:
        long begin = System.currentTimeMillis();
        Connection conn = null;
        PreparedStatement pstmt = null;
        try{
            // 获得连接:
            conn = JDBCUtils.getConnection();
            // 编写SQL语句:
            String sql = "insertinto user values (null,?)";
            // 预编译SQL:
            pstmt = conn.prepareStatement(sql);
            for(int i=1;i<=10000;i++){
                pstmt.setString(1, "name"+i);
                // 添加到批处理
                pstmt.addBatch();
                // 注意问题:
                // 执行批处理
                if(i % 1000 == 0){
                   // 执行批处理:
                   pstmt.executeBatch();
                   // 清空批处理:
                   pstmt.clearBatch();
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(pstmt, conn);
        }
        long end = System.currentTimeMillis();
        System.out.println((end-begin));
    }
file:///C:/Users/lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image012.jpg
file:///C:/Users/lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image014.jpg
/**
     * 获得元素的内容:查询的操作.
     */
    publicvoid demo1() throws Exception{
        // 创建解析器
        SAXReaderreader = new SAXReader();
        // 解析XML的文档
        Documentdocument = reader.read("xml/demo1.xml");
        // 获得跟节点
        Elementroot = document.getRootElement();
        System.out.println(root.getName());
        // 查找跟节点下的子节点. element() elements();
        ElementpElement = root.element("person"); // 查找的是第一个person元素
        //root.elements("person").get(1); // 查找的是第二个person元素
        ElementnElement = pElement.element("name");
        ElementaElement = pElement.element("age");
        ElementsElement = pElement.element("sex");
        System.out.println(nElement.getText());
        System.out.println(aElement.getText());
        System.out.println(sElement.getText());
    }
Ø  XPath:
* dom4j支持XPath的jar包.
    * jaxen-1.1-beta-6.jar
* dom4j的XPath支持的API:
    * Listdocument.selectNodes(String xPath);
    * Nodedocument.selectSingleNode(String xPath);
* 代码:
    @Test
    /**
     * DOM4J的XPath的写法:
     */
    publicvoid demo2() throws Exception{
        // 创建解析器:
        SAXReaderreader = new SAXReader();
        // 解析XML返回Document对象.
        Documentdocument = reader.read("xml/demo1.xml");
        /*List<Node>list = document.selectNodes("//name");
        for(Node node : list) {
            Elementelement = (Element) node;
            System.out.println(element.getText());
        }*/
        
        List<Node>list = document.selectNodes("//person['@id']");
        for(Node node : list) {
            Elementelement = (Element) node;
            System.out.println(element.attributeValue("id"));
        }
    }
名称空间:一个XML只能引入一个DTD约束文档.使用了Schema约束XML文档,一个XML可以引入多个Schame的约束!!!
                      如果再多个Schema文档中定义了相同的属性名称 该怎么办?
      * 名称空间类似于java中的package.通过名称空间区分 标签或属性来自于哪个文档的!!!通常名称空间唯一的不重复的即可.一般情况下使用一个URL地址表示一个名称空间.
      
    xmlns              :xml name sapace .代表当前的文档应用的名称空间.
    targetNameSpace    :目标名称空间.
    elementFormDefault :
-->
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itheima.com/ee25"
elementFormDefault="qualified">
    <!-- 复杂标签 -->
    <elementname="persons">
        <!--复杂类型 -->
        <complexType>
            <sequencemaxOccurs="unbounded" minOccurs="1">
                <elementname="person">
                   <complexType>
                       <sequence>
                           <!--简单标签 -->
                           <elementname="name" type="string"></element>
                           <elementname="age" type="int"></element>
                           <elementname="sex" type="string"></element>
                       </sequence>
                       <attributename="id" type="string" use="required"/>
                   </complexType>
                </element>
            </sequence>
        </complexType>
    </element>
</schema>

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马