JDBC的使用
Posted CptMac
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC的使用相关的知识,希望对你有一定的参考价值。
基本使用
1、下载安装JDBC驱动包
2、然后建立连接
1 Connection conn =null; 2 PreparedStatement ps = null; 3 ResultSet rs = null; 4 //加载驱动类 5 Class.forName("com.mysql.cj.jdbc.Driver"); 6 long start = System.currentTimeMillis(); 7 System.out.println("驱动成功加载"); 8 //建立连接(内部包含socket对象,是一个远程连接。比较耗时!这是connection对象管理的一个要点!)、 9 //真正开发中,为了提高效率都会使用连接池来管理连接对象! 10 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC","root","123456"); 11 System.out.println("建立连接中"); 12 System.out.println(conn); 13 long end = System.currentTimeMillis(); 14 System.out.println("建立连接耗时"+(end-start)+"ms"
3、使用statement来执行SQL语句,使用完一定要close
1 //SQL注入 2 Statement stmt = conn.createStatement(); 3 String sql = "insert into t_user (username,pwd,regTime) values (\'赵\',666666,now())"; 4 stmt.execute(sql); 5 //****statement容易发生SQL注入的风险*****/
关闭管道要注意异常处理,关闭遵循resultset--》statement--》connection这样的关闭顺序
1 try { 2 巴拉巴拉 3 } catch (ClassNotFoundException e) { 4 e.printStackTrace(); 5 } catch (SQLException e) { 6 e.printStackTrace(); 7 } finally { 8 if(rs!=null){ 9 try { 10 rs.close(); 11 } catch (SQLException e) { 12 e.printStackTrace(); 13 } 14 } 15 if(ps!=null){ 16 try { 17 ps.close(); 18 } catch (SQLException e) { 19 e.printStackTrace(); 20 } 21 } 22 if(conn != null){ 23 try { 24 conn.close(); 25 } catch (SQLException e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 }
PreparedStatement的基本用法
1 /* 测试PreparedStatement的基本用法 2 * 一般非select语句用executeUpdate()返回更新的行数 3 * select语句采用executeQuery()返回ResultSet结果集 4 */ 5 String sql = "insert into t_user (username,pwd,regTime) values (\'老为\',6123466,now())"; 6 PreparedStatement ps = conn.prepareStatement(sql); 7 ps.execute(); 8 sql = "insert into t_user (username,pwd,regTime) values (?,?,now())";//?为占位符,固定输入内容,防止注入 9 ps = conn.prepareStatement(sql); 10 ps.setString(1,"老小为");//参数从1开始计算 11 ps.setString(2,"1241523"); 12 ps.execute(); 13 /** 14 * 测试ResultSet结果集的基本用法 15 */ 16 17 String sql = "select * from t_user where id >?";//?为占位符,固定输入内容,防止注入 18 ps = conn.prepareStatement(sql); 19 ps.setObject(1,2); 20 21 rs = ps.executeQuery(); 22 23 while (rs.next()){//next() 游标 返回Boolean,如果下一个位置没有了就返回false 24 System.out.println(rs.getInt(1)+"*********"+rs.getString(2)+"*********"+rs.getString(3)); 25 }
查询操作
boolean next():判断是否有下一行数据,若有,则向下移动一行指针;getXxx(int columnIndex):获取当前行中,第几列.(从1开始):不推荐;getXxx(String columnName):获取当前行中的,指定列名的列的值.columnName是列名/列的别名;若列的类型是VARCHAR/CHAR/TEXT,都使用getString来获取列的值;若列的类型是int/integer/-->getInt来获取列的值。executeQuery(Sql)会得到一个结果集,使用while可获取多行。
DAO设计
Data Access Object(数据存取对象)避免多个地方都要都同时做CRUD操作时,重复的代码就会很多。通过DAO层与数据库打交道可以减少重复操作。
ORM对象关系映射将关系数据库中表中的记录映射成为对象,以对象的形式展现,因此ORM的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作。
domain用来运输数据的一个类,使用set get方法进行保存数据和获取数据。
命名规范
DAO包
类名
各包的主要内容
DAO接口实现
1 public class StudentDaoImpl implements IStudentDao { 2 3 4 @Override 5 public void save(Student stu) { 6 7 Connection conn = null; 8 PreparedStatement ps = null; 9 try { 10 // 1.加载驱动 11 // 2.连接数据库 12 conn = JdbcUtil.getConn(); 13 // 3.创建语句 14 15 String sql = "insert into student(name,age) values(?,?)"; 16 ps = conn.prepareStatement(sql); 17 ps.setString(1, stu.getName()); 18 ps.setInt(2, stu.getAge()); 19 20 // 4.执行语句 21 ps.executeUpdate(); 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } finally { 25 // 5.释放资源 26 JdbcUtil.close(conn, ps, null); 27 } 28 } 29 30 @Override 31 public void delete(int id) { 32 33 Connection conn = null; 34 PreparedStatement ps = null; 35 try { 36 // 1.加载驱动 37 // 2.连接数据库 38 conn = JdbcUtil.getConn(); 39 // 3.创建语句 40 String sql = "delete from student where id = ?"; 41 ps = conn.prepareStatement(sql); 42 ps.setInt(1, id); 43 // 4.执行语句 44 ps.executeUpdate(); 45 46 47 } catch (Exception e) { 48 e.printStackTrace(); 49 } finally { 50 // 5.释放资源 51 JdbcUtil.close(conn, ps, null); 52 } 53 54 } 55 56 @Override 57 public void update(int id, Student stu) { 58 Connection conn = null; 59 PreparedStatement ps = null; 60 try { 61 // 1.加载驱动 62 // 2.连接数据库 63 conn = JdbcUtil.getConn(); 64 // 3.创建语句 65 String sql = "update student set name=?, age=? where id =? "; 66 ps = conn.prepareStatement(sql); 67 ps.setString(1, stu.getName()); 68 ps.setInt(2, stu.getAge()); 69 ps.setInt(3, id); 70 // 4.执行语句 71 ps.executeUpdate(); 72 } catch (Exception e) { 73 e.printStackTrace(); 74 } finally { 75 JdbcUtil.close(conn, ps, null); 76 } 77 } 78 79 @Override 80 public Student get(int id) { 81 82 Connection conn = null; 83 PreparedStatement ps = null; 84 ResultSet rs = null; 85 try { 86 // 1.加载驱动 87 // 2.连接数据库 88 conn = JdbcUtil.getConn(); 89 // 3.创建语句 90 String sql = "select * from student where id = ?"; 91 ps = conn.prepareStatement(sql); 92 ps.setInt(1, id); 93 // 4.执行语句 94 rs = ps.executeQuery(); 95 if (rs.next()) { 96 Student stu = new Student(); 97 stu.setName(rs.getString("name")); 98 stu.setAge(rs.getInt("age")); 99 stu.setId(rs.getInt("id")); 100 return stu; 101 } 102 103 } catch (Exception e) { 104 e.printStackTrace(); 105 } finally { 106 // 5.释放资源 107 JdbcUtil.close(conn, ps, rs); 108 109 } 110 return null; 111 } 112 113 @Override 114 public List<Student> getAll() { 115 116 Connection conn = null; 117 Statement st = null; 118 ResultSet rs = null; 119 try { 120 // 1.加载驱动 121 // 2.连接数据库 122 conn = JdbcUtil.getConn(); 123 // 3.创建语句 124 st = conn.createStatement(); 125 String sql = "select * from student "; 126 System.out.println(sql); 127 // 4.执行语句 128 rs = st.executeQuery(sql); 129 // 创建一个集合 130 List<Student> list = new ArrayList<Student>(); 131 while (rs.next()) { 132 Student stu = new Student(); 133 stu.setName(rs.getString("name")); 134 stu.setAge(rs.getInt("age")); 135 stu.setId(rs.getInt("id")); 136 list.add(stu); 137 } 138 return list; 139 140 } catch (Exception e) { 141 e.printStackTrace(); 142 } finally { 143 JdbcUtil.close(conn, st, rs); 144 } 145 return null; 146 } 147 148 }
批处理
建议使用Statement,因为PreparedStatement的预编译空间有限,当数据量特别大的时候会发生异常
1 Connection conn =null; 2 Statement stmt = null; 3 ResultSet rs = null; 4 5 6 conn.setAutoCommit(false);//设为纯手动提交 7 stmt = conn.createStatement(); 8 for(int i = 0; i<20000;i++){ 9 stmt.addBatch("insert into t_user(username,pwd,regTime) values (\'gao"+i+"\',666666,now())"); 10 } 11 stmt.executeBatch(); 12 conn.commit(); 13 long end = System.currentTimeMillis(); 14 System.out.println("插入两万条数据耗时:"+(end-start)+"ms");
事务
防止任务进行到一半出现问题导致数据错误,可将所有操作统一为一个事务,所有任务完成后事务才会完成
1 JDBCUtil.connect(); 2 3 conn.setAutoCommit(false);//设为手动提交,默认为自动提交,需要手动提交一定要更改 4 5 String sql= "insert into t_user (username,pwd) values(?,?)"; 6 ps1 = conn.prepareStatement(sql); 7 ps1.setObject(1,"raoxiaowei"); 8 ps1.setObject(2,"1279846789"); 9 ps1.execute(); 10 System.out.println("第一个数据插入成功"); 11 try { 12 Thread.sleep(6000); 13 } catch (InterruptedException e) { 14 e.printStackTrace(); 15 } 16 17 ps2 = conn.prepareStatement(sql); 18 ps2.setObject(1,"raoxiaowei"); 19 ps2.setObject(2,"1279846789"); 20 ps2.execute(); 21 System.out.println("第二个数据插入成功"); 22 23 long end = System.currentTimeMillis(); 24 System.out.println("插入两条数据耗时:"+(end-start)+"ms"); 25 26 } catch (ClassNotFoundException e) { 27 e.printStackTrace(); 28 try { 29 conn.rollback();//回滚操作 30 } catch (SQLException ex) { 31 ex.printStackTrace(); 32 } 33 } catch (SQLException e) { 34 e.printStackTrace(); 35 }finally { 36 JDBCUtil.close(); 37 }
连接池
用于解决每次需要单独进行连接,浪费资源的问题
常见连接池有DBCP:Spring推荐,Tomcat的数据源使用的就是DBCP;Druid:阿里巴巴提供的连接池-德鲁伊-号称最好的连接池,它里面除了这些, 还有更多的功能。
连接池采用的方式是先建立一批对象,然后由用户进行连接的时候从中抽取对象进行连接,使用完毕后并不关闭而是继续放入连接池,这样就有一个缓冲区,在面对大规模调取的时候可以减少创建对象等造成的资源浪费,提高性能。所以在使用是区别于传统方式的Connection创建对象,使用完毕后close;连接池创建DataSource对象,然后从DataSource对象中获取Connection对象,使用完后再把连接对象还给连接池。
DBCP
使用就是创建BasicDataSource对象
jar包:commons-dbcp-1.4.jar和commons-pool-1.5.6.jar
1 String url = "jdbc:mysql://localhost:3306/jdbc_db?rewriteBatchedStatements=true"; 2 String user = "root"; 3 String pwd = "1234"; 4 String driverName = "com.mysql.jdbc.Driver"; 5 6 BasicDataSource ds = new BasicDataSource(); 7 ds.setDriverClassName(driverName); 8 ds.setUsername(user); 9 ds.setPassword(pwd); 10 ds.setUrl(url); 11 12 Connection conn = ds.getConnection(); 13 String sql = "select * from account"; 14 Statement st = conn.createStatement(); 15 ResultSet rs = st.executeQuery(sql);
Druid
和DPCB一样,只需要修改对应的方法类就行。BasicDataSource-->DruidDataSource
Druid对比其他连接池性能目前最强,且开源
以上是关于JDBC的使用的主要内容,如果未能解决你的问题,请参考以下文章