zoukankan      html  css  js  c++  java
  • JDBC加强

    PrepareStatement的用法

    预处理语句,预先处理sql语句,让sql先加载到内存,提高速率,还可以处理statement中的拼接问题和,sql注入(因为是sql拼接所以当密码验证的时候如果输入的为(“123134’or’1=1”)这样是一直成立的),

    public void insert(Account account) {
            Connection conn = JDBCUtilDataSources.getinstance().getConnetion();
            String sql="insert into account (username,money) values(?,?)";
            try {
                PreparedStatement ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
                conn.setAutoCommit(false);
                //PreparedStatement ps = conn.prepareStatement(sql);
                ps.setString(1, account.getUsername());
                ps.setDouble(2, account.getMoney());
                ps.executeUpdate(sql);
                ResultSet rs = ps.getGeneratedKeys();
                while (rs.next()) {
                    System.out.println(rs.getLong(1));
                }
                conn.commit();
                //System.out.println(update);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
    View Code

    事务

    属性:

    原子:是不可分割的最小单位

    一致:不能破坏逻辑性,就是转账前后的总额不能改变

    持久:把数据存入磁盘

    隔离:当多个线程的时候使用的时候,就是在并发编程中,每个事务都有完整的空间,相互独立

    程序中的一组事情,要不都成功,要不都失败。

    列子:转钱的时候,当发生错误的时候,我们转钱的人钱少了,但是收钱人没有增加钱,这样就出现了问题,所以需要使用事务

    当多个进行都出现的时候我们需要回滚事务(让所有的数据都为最初时的样子),在Java代码中怎么提交事务我们需要取消自动提交事物,connection.setautocommit(false),然后自己提交connetion.commit();connection.rollback();

    public void insert(Account account) {
            Connection conn = JDBCUtilDataSources.getinstance().getConnetion();
            String sql="insert into account (username,money) values(?,?)";
            try {
                PreparedStatement ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
                conn.setAutoCommit(false);
                //PreparedStatement ps = conn.prepareStatement(sql);
                ps.setString(1, account.getUsername());
                ps.setDouble(2, account.getMoney());
                ps.executeUpdate(sql);
                ResultSet rs = ps.getGeneratedKeys();
                while (rs.next()) {
                    System.out.println(rs.getLong(1));
                }
                conn.commit();
                //System.out.println(update);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
    View Code

    连接池

    在里面创建好连接(一定的)对象,我们只需要获得其中的连接就可以了,因为每个数据库的连接能方式的不同,所以ecilpse不会写这样的方法,我们需要使用数据库厂商的包才能使用其中的方式,当不够的时候可以获得最大连接数,然后就只有等待了

    每次我们获得连接的时候都需要通过class.forname()得到drivermanger()来获得连接,而数据库的连接也有限制,这样不仅浪费内存,而且每次获得连接也需要时间,这样既浪费了空间,也浪费了时间,所以我们需要连接池,这样不仅能够

     

    package cn.jiedada.jdbcutil;
    
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    import javax.sql.DataSource;
    
    import org.apache.commons.dbcp.BasicDataSourceFactory;
    
    public class JDBCUtilDataSources {
        //单列模式
        private JDBCUtilDataSources(){}
        static private JDBCUtilDataSources instance;
        static Properties prop;
        private static DataSource dSource;
        public static JDBCUtilDataSources getinstance() {
            //获得对象
            return instance;
        }
        static{
            //提高加载效率
            prop = new Properties();
            instance=new JDBCUtilDataSources();
            try {
                //使用load获得文件中的键值对
                prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
                //获得加载器
                //Class.forName(prop.getProperty("classname"));
                dSource=BasicDataSourceFactory.createDataSource(prop);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public  Connection getConnetion() {    
            Connection conn=null;
            try {
                //获得连接
                 //conn = DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("username"), prop.getProperty("password"));
                conn = dSource.getConnection();
                return conn;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return conn;
        }
        public  void del(ResultSet rs,Statement st,Connection conn) {
                try {
                    //判断关闭资源
                    if(rs!=null)rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally {
                    try {
                        if(st!=null)
                        st.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }finally {
                        try {
                            if(conn!=null)
                            conn.close();
                        } catch (SQLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
        }
    }
    View Code

     

     

    获得主键

    Connection.preparestatement()中的方法,当提交了执行方法的时候,就可以通过preparestatement中的get。。keys方法获得

    package cn.jiedada.dao.impl;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import com.mysql.jdbc.Statement;
    
    import cn.jiedada.dao.IAccountDao;
    import cn.jiedada.diman.Account;
    import cn.jiedada.jdbcutil.JDBCUtilDataSources;
    
    public class AccountDaoLmpl implements IAccountDao {
    
        @Override
        public void convert(Account from, Account to, Double num) {
            // TODO Auto-generated method stub
            Connection conn = JDBCUtilDataSources.getinstance().getConnetion();
            String sql="update account set money=? where username=?";
            try {
                conn.setAutoCommit(false);
                PreparedStatement ps = conn.prepareStatement(sql);
                ps.setDouble(1, select(from)-num);
                ps.setString(2, from.getUsername());
                ps.executeUpdate();
                //System.out.println(1/0);
                PreparedStatement ps1 = conn.prepareStatement(sql);
                ps1.setDouble(1, select(to)+num);
                ps1.setString(2, to.getUsername());
                ps1.executeUpdate();
                conn.commit();
                JDBCUtilDataSources.getinstance().del(null, ps1, conn);
                JDBCUtilDataSources.getinstance().del(null, ps, conn);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
        }
    
        @Override
        public Double select(Account account) {
            Connection conn = JDBCUtilDataSources.getinstance().getConnetion();
            String sql="select money from account where username=?";
            try {
                PreparedStatement ps = conn.prepareStatement(sql);
                ps.setString(1, account.getUsername());
                ResultSet rs = ps.executeQuery();
                while (rs.next()) {
                    return rs.getDouble("money");
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        public void insert(Account account) {
            Connection conn = JDBCUtilDataSources.getinstance().getConnetion();
            String sql="insert into account (username,money) values(?,?)";
            try {
                PreparedStatement ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
                conn.setAutoCommit(false);
                //PreparedStatement ps = conn.prepareStatement(sql);
                ps.setString(1, account.getUsername());
                ps.setDouble(2, account.getMoney());
                ps.executeUpdate(sql);
                ResultSet rs = ps.getGeneratedKeys();
                while (rs.next()) {
                    System.out.println(rs.getLong(1));
                }
                conn.commit();
                //System.out.println(update);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            
        }
    
    }
    View Code

    保护模式

  • 相关阅读:
    Android蓝牙通信 .[转]
    通过VS2010性能分析来查找代码中那些地方最损耗资源 [转]
    【百度地图API】如何区分地址解析和智能搜索?
    Windows 程序员必备的知识和工具
    NUnit详细使用方法
    Android 蓝牙开发浅析 [转]
    软件工程的国家标准下载链接
    android布局属性详解
    Android之Service相关
    Android 实现布局动态加载
  • 原文地址:https://www.cnblogs.com/xiaoruirui/p/11361732.html
Copyright © 2011-2022 走看看