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(); }
事务
属性:
原子:是不可分割的最小单位
一致:不能破坏逻辑性,就是转账前后的总额不能改变
持久:把数据存入磁盘
隔离:当多个线程的时候使用的时候,就是在并发编程中,每个事务都有完整的空间,相互独立
程序中的一组事情,要不都成功,要不都失败。
列子:转钱的时候,当发生错误的时候,我们转钱的人钱少了,但是收钱人没有增加钱,这样就出现了问题,所以需要使用事务
当多个进行都出现的时候我们需要回滚事务(让所有的数据都为最初时的样子),在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(); }
连接池
在里面创建好连接(一定的)对象,我们只需要获得其中的连接就可以了,因为每个数据库的连接能方式的不同,所以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(); } } } } }
获得主键
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(); } } }