package JDBC.utils; /** * JDBC工具类.简化JDBC编程 * @author Max_Hu * */ import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DBUtil { //工具类的构造方法都是私有的, //因为其中的方法都是静态的,不需要new对象,直接用类名调用 private DBUtil() {} static { //静态代码块在类加载时执行,并只执行一次 //注册驱动只需要走一次 try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 获取数据库连接对象 * @return * @throws SQLException */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","333"); } /** * 释放资源 * @param conn * @param st * @param rs */ public static void close(Connection conn,Statement st, ResultSet rs) { try { if(rs!=null) { rs.close(); } } catch (Exception e) { e.printStackTrace(); } try { if(st!=null) { st.close(); } } catch (Exception e) { e.printStackTrace(); }try { if(conn!=null) { conn.close(); } } catch (Exception e) { e.printStackTrace(); } } }
做模糊查询并验证工具类是否好用
模糊查询时,传值传模糊字符,而不是在预编译语句中模糊处理
package JDBC; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import JDBC.utils.DBUtil; public class fuzzy_query { public static void main(String[] args) { Connection conn=null; PreparedStatement ps=null; ResultSet rs=null; try { //获取连接 conn=DBUtil.getConnection(); //获取预编译的数据库操作对象 String sql="select ename from emp where ename like ?"; ps=conn.prepareStatement(sql); ps.setString(1, "_A%"); rs=ps.executeQuery(); while(rs.next()) { System.out.println(rs.getString("ename")); } } catch (Exception e) { e.printStackTrace(); }finally { //释放资源 DBUtil.close(conn, ps, rs); } } }
行级锁(悲观锁)在select语句后面添加for update
悲观锁:事务必须排队,数据锁住了,不允许并发
乐观锁:支持并发,事务不需要排队,但需要一个版本号
创建两个类
该类用来锁定记录
package JDBC; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import JDBC.utils.DBUtil; /** * 开启一个事务,专门进行查询,使用悲观锁锁住相关记录 * * @author Max_Hu * */ public class row_locking { public static void main(String[] args) { Connection connection = null; PreparedStatement ps = null; ResultSet rs = null; try { connection = DBUtil.getConnection(); // 开启事务 connection.setAutoCommit(false); String sql = "select ename,job,sal from emp where job=? for update"; ps = connection.prepareStatement(sql); ps.setString(1, "MANAGER"); rs = ps.executeQuery(); while (rs.next()) { System.out.println(rs.getString("ename") + "," + rs.getString("job") + "," + rs.getDouble("sal")); } // 提交事务(事务结束) //在提交语句打断点进行Debug,然后执行第二个程序 connection.commit(); } catch (SQLException e) { if (connection != null) { try { // 回滚事务(事务结束) connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } e.printStackTrace(); } finally { DBUtil.close(connection, ps, rs); } } }
第二个类,用来修改被锁住的记录
在第一个类debug没有结束的时候,该类不能修改被锁住的数据,
当第一个类debug结束的时候,该程序才正常执行
package JDBC; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import javax.swing.border.EmptyBorder; import JDBC.utils.DBUtil; /** * 负责修改被锁定的记录 * * @author Max_Hu * */ public class row_locking02 { public static void main(String[] args) { Connection conn = null; PreparedStatement ps = null; try { conn = DBUtil.getConnection(); conn.setAutoCommit(false); String sql = "update emp set sal=sal*1.1 where job=?"; ps = conn.prepareStatement(sql); ps.setString(1, "MANAGER"); int count = ps.executeUpdate(); System.out.println(count); conn.commit(); } catch (SQLException e) { if (conn != null) { try { conn.rollback(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } e.printStackTrace(); } finally { DBUtil.close(conn, ps, null); } } }