5:JDBC

  1 # 今日内容
  2 
  3     1. JDBC基本概念
  4     2. 快速入门
  5     3. 对JDBC中各个接口和类详解
  6 
  7 
  8 ## JDBC:
  9     1. 概念:Java DataBase Connectivity  Java 数据库连接, Java语言操作数据库
 10         * JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)
         编程,真正执行的代码是驱动jar包中的实现类。
11 12 2. 快速入门: 13 * 步骤: 14 1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar 15 1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下 16 2.右键-->Add As Library 17 2. 注册驱动 18 3. 获取数据库连接对象 Connection 19 4. 定义sql 20 5. 获取执行sql语句的对象 Statement 21 6. 执行sql,接受返回结果 22 7. 处理结果 23 8. 释放资源 24 25 * 代码实现: 26 //1. 导入驱动jar包 27 //2.注册驱动 28 Class.forName("com.mysql.jdbc.Driver"); 29 //3.获取数据库连接对象 30 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root"); 31 //4.定义sql语句 32 String sql = "update account set balance = 500 where id = 1"; 33 //5.获取执行sql的对象 Statement 34 Statement stmt = conn.createStatement(); 35 //6.执行sql 36 int count = stmt.executeUpdate(sql); 37 //7.处理结果 38 System.out.println(count); 39 //8.释放资源 40 stmt.close(); 41 conn.close(); 42 43 3. 详解各个对象: 44 1. DriverManager:驱动管理对象 45 * 功能: 46 1. 注册驱动:告诉程序该使用哪一个数据库驱动jar 47 static void registerDriver(Driver driver) :注册与给定的驱动程序 DriverManager 。 48 写代码使用: Class.forName("com.mysql.jdbc.Driver"); 49 通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块 50 static { 51 try { 52 java.sql.DriverManager.registerDriver(new Driver()); 53 } catch (SQLException E) { 54 throw new RuntimeException("Can't register driver!"); 55 } 56 } 57 58 注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。 59 2. 获取数据库连接: 60 * 方法:static Connection getConnection(String url, String user, String password) 61 * 参数: 62 * url:指定连接的路径 63 * 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称 64 * 例子:jdbc:mysql://localhost:3306/db3 65 * 细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称 66 * user:用户名 67 * password:密码 68 2. Connection:数据库连接对象 69 1. 功能: 70 1. 获取执行sql 的对象 71 * Statement createStatement() 72 * PreparedStatement prepareStatement(String sql) 73 2. 管理事务: 74 * 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务 75 * 提交事务:commit() 76 * 回滚事务:rollback() 77 3. Statement:执行sql的对象 78 1. 执行sql 79 1. boolean execute(String sql) :可以执行任意的sql 了解 80 2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句 81 * 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。 82 3. ResultSet executeQuery(String sql) :执行DQL(select)语句 83 2. 练习: 84 1. account表 添加一条记录 85 2. account表 修改记录 86 3. account表 删除一条记录 87 88 代码: 89 Statement stmt = null; 90 Connection conn = null; 91 try { 92 //1. 注册驱动 93 Class.forName("com.mysql.jdbc.Driver"); 94 //2. 定义sql 95 String sql = "insert into account values(null,'王五',3000)"; 96 //3.获取Connection对象 97 conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root"); 98 //4.获取执行sql的对象 Statement 99 stmt = conn.createStatement(); 100 //5.执行sql 101 int count = stmt.executeUpdate(sql);//影响的行数 102 //6.处理结果 103 System.out.println(count); 104 if(count > 0){ 105 System.out.println("添加成功!"); 106 }else{ 107 System.out.println("添加失败!"); 108 } 109 110 } catch (ClassNotFoundException e) { 111 e.printStackTrace(); 112 } catch (SQLException e) { 113 e.printStackTrace(); 114 }finally { 115 //stmt.close(); 116 //7. 释放资源 117 //避免空指针异常 118 if(stmt != null){ 119 try { 120 stmt.close(); 121 } catch (SQLException e) { 122 e.printStackTrace(); 123 } 124 } 125 126 if(conn != null){ 127 try { 128 conn.close(); 129 } catch (SQLException e) { 130 e.printStackTrace(); 131 } 132 } 133 } 134 135 4. ResultSet:结果集对象,封装查询结果 136 * boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true 137 * getXxx(参数):获取数据 138 * Xxx:代表数据类型 如: int getInt() , String getString() 139 * 参数: 140 1. int:代表列的编号,从1开始 如: getString(1) 141 2. String:代表列名称。 如: getDouble("balance") 142 143 * 注意: 144 * 使用步骤: 145 1. 游标向下移动一行 146 2. 判断是否有数据 147 3. 获取数据 148 149 //循环判断游标是否是最后一行末尾。 150 while(rs.next()){ 151 //获取数据 152 //6.2 获取数据 153 int id = rs.getInt(1); 154 String name = rs.getString("name"); 155 double balance = rs.getDouble(3); 156 157 System.out.println(id + "---" + name + "---" + balance); 158 } 159 160 * 练习: 161 * 定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回。 162 1. 定义Emp类 163 2. 定义方法 public List<Emp> findAll(){} 164 3. 实现方法 select * from emp; 165 166 5. PreparedStatement:执行sql的对象 167 1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题 168 1. 输入用户随便,输入密码:a' or 'a' = 'a 169 2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' 170 171 2. 解决sql注入问题:使用PreparedStatement对象来解决 172 3. 预编译的SQL:参数使用?作为占位符 173 4. 步骤: 174 1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar 175 2. 注册驱动 176 3. 获取数据库连接对象 Connection 177 4. 定义sql 178 * 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?; 179 5. 获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql) 180 6. 给?赋值: 181 * 方法: setXxx(参数1,参数2) 182 * 参数1:?的位置编号 从1 开始 183 * 参数2:?的值 184 7. 执行sql,接受返回结果,不需要传递sql语句 185 8. 处理结果 186 9. 释放资源 187 188 5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作 189 1. 可以防止SQL注入 190 2. 效率更高 191 192 ## 抽取JDBC工具类 : JDBCUtils 193 * 目的:简化书写 194 * 分析: 195 1. 注册驱动也抽取 196 2. 抽取一个方法获取连接对象 197 * 需求:不想传递参数(麻烦),还得保证工具类的通用性。 198 * 解决:配置文件 199 jdbc.properties 200 url= 201 user= 202 password= 203 204 205 3. 抽取一个方法释放资源 206 207 * 代码实现: 208 public class JDBCUtils { 209 private static String url; 210 private static String user; 211 private static String password; 212 private static String driver; 213 /** 214 * 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块 215 */ 216 static{ 217 //读取资源文件,获取值。 218 219 try { 220 //1. 创建Properties集合类。 221 Properties pro = new Properties(); 222 223 //获取src路径下的文件的方式--->ClassLoader 类加载器 224 ClassLoader classLoader = JDBCUtils.class.getClassLoader(); 225 URL res = classLoader.getResource("jdbc.properties"); 226 String path = res.getPath(); 227 System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties 228 //2. 加载文件 229 // pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties")); 230 pro.load(new FileReader(path)); 231 232 //3. 获取数据,赋值 233 url = pro.getProperty("url"); 234 user = pro.getProperty("user"); 235 password = pro.getProperty("password"); 236 driver = pro.getProperty("driver"); 237 //4. 注册驱动 238 Class.forName(driver); 239 } catch (IOException e) { 240 e.printStackTrace(); 241 } catch (ClassNotFoundException e) { 242 e.printStackTrace(); 243 } 244 } 245 246 247 /** 248 * 获取连接 249 * @return 连接对象 250 */ 251 public static Connection getConnection() throws SQLException { 252 253 return DriverManager.getConnection(url, user, password); 254 } 255 256 /** 257 * 释放资源 258 * @param stmt 259 * @param conn 260 */ 261 public static void close(Statement stmt,Connection conn){ 262 if( stmt != null){ 263 try { 264 stmt.close(); 265 } catch (SQLException e) { 266 e.printStackTrace(); 267 } 268 } 269 270 if( conn != null){ 271 try { 272 conn.close(); 273 } catch (SQLException e) { 274 e.printStackTrace(); 275 } 276 } 277 } 278 279 280 /** 281 * 释放资源 282 * @param stmt 283 * @param conn 284 */ 285 public static void close(ResultSet rs,Statement stmt, Connection conn){ 286 if( rs != null){ 287 try { 288 rs.close(); 289 } catch (SQLException e) { 290 e.printStackTrace(); 291 } 292 } 293 294 if( stmt != null){ 295 try { 296 stmt.close(); 297 } catch (SQLException e) { 298 e.printStackTrace(); 299 } 300 } 301 302 if( conn != null){ 303 try { 304 conn.close(); 305 } catch (SQLException e) { 306 e.printStackTrace(); 307 } 308 } 309 } 310 311 } 312 313 * 练习: 314 * 需求: 315 1. 通过键盘录入用户名和密码 316 2. 判断用户是否登录成功 317 * select * from user where username = "" and password = ""; 318 * 如果这个sql有查询结果,则成功,反之,则失败 319 320 * 步骤: 321 1. 创建数据库表 user 322 CREATE TABLE USER( 323 id INT PRIMARY KEY AUTO_INCREMENT, 324 username VARCHAR(32), 325 PASSWORD VARCHAR(32) 326 327 ); 328 329 INSERT INTO USER VALUES(NULL,'zhangsan','123'); 330 INSERT INTO USER VALUES(NULL,'lisi','234'); 331 332 2. 代码实现: 333 public class JDBCDemo9 { 334 335 public static void main(String[] args) { 336 //1.键盘录入,接受用户名和密码 337 Scanner sc = new Scanner(System.in); 338 System.out.println("请输入用户名:"); 339 String username = sc.nextLine(); 340 System.out.println("请输入密码:"); 341 String password = sc.nextLine(); 342 //2.调用方法 343 boolean flag = new JDBCDemo9().login(username, password); 344 //3.判断结果,输出不同语句 345 if(flag){ 346 //登录成功 347 System.out.println("登录成功!"); 348 }else{ 349 System.out.println("用户名或密码错误!"); 350 } 351 352 353 } 354 355 356 357 /** 358 * 登录方法 359 */ 360 public boolean login(String username ,String password){ 361 if(username == null || password == null){ 362 return false; 363 } 364 //连接数据库判断是否登录成功 365 Connection conn = null; 366 Statement stmt = null; 367 ResultSet rs = null; 368 //1.获取连接 369 try { 370 conn = JDBCUtils.getConnection(); 371 //2.定义sql 372 String sql = "select * from user where username = '"+username+"' and password = '"+password+"' "; 373 //3.获取执行sql的对象 374 stmt = conn.createStatement(); 375 //4.执行查询 376 rs = stmt.executeQuery(sql); 377 //5.判断 378 /* if(rs.next()){//如果有下一行,则返回true 379 return true; 380 }else{ 381 return false; 382 }*/ 383 return rs.next();//如果有下一行,则返回true 384 385 } catch (SQLException e) { 386 e.printStackTrace(); 387 }finally { 388 JDBCUtils.close(rs,stmt,conn); 389 } 390 391 392 return false; 393 } 394 } 395 396 397 ## JDBC控制事务: 398 1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。 399 2. 操作: 400 1. 开启事务 401 2. 提交事务 402 3. 回滚事务 403 3. 使用Connection对象来管理事务 404 * 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务 405 * 在执行sql之前开启事务 406 * 提交事务:commit() 407 * 当所有sql都执行完提交事务 408 * 回滚事务:rollback() 409 * 在catch中回滚事务 410 411 4. 代码: 412 public class JDBCDemo10 { 413 414 public static void main(String[] args) { 415 Connection conn = null; 416 PreparedStatement pstmt1 = null; 417 PreparedStatement pstmt2 = null; 418 419 try { 420 //1.获取连接 421 conn = JDBCUtils.getConnection(); 422 //开启事务 423 conn.setAutoCommit(false); 424 425 //2.定义sql 426 //2.1 张三 - 500 427 String sql1 = "update account set balance = balance - ? where id = ?"; 428 //2.2 李四 + 500 429 String sql2 = "update account set balance = balance + ? where id = ?"; 430 //3.获取执行sql对象 431 pstmt1 = conn.prepareStatement(sql1); 432 pstmt2 = conn.prepareStatement(sql2); 433 //4. 设置参数 434 pstmt1.setDouble(1,500); 435 pstmt1.setInt(2,1); 436 437 pstmt2.setDouble(1,500); 438 pstmt2.setInt(2,2); 439 //5.执行sql 440 pstmt1.executeUpdate(); 441 // 手动制造异常 442 int i = 3/0; 443 444 pstmt2.executeUpdate(); 445 //提交事务 446 conn.commit(); 447 } catch (Exception e) { 448 //事务回滚 449 try { 450 if(conn != null) { 451 conn.rollback(); 452 } 453 } catch (SQLException e1) { 454 e1.printStackTrace(); 455 } 456 e.printStackTrace(); 457 }finally { 458 JDBCUtils.close(pstmt1,conn); 459 JDBCUtils.close(pstmt2,null); 460 } 461 462 463 } 464 465 } 466 467

 

posted @ 2020-08-24 14:29  佛祖让我来巡山  阅读(111)  评论(0编辑  收藏  举报

佛祖让我来巡山博客站 - 创建于 2018-08-15

开发工程师个人站,内容主要是网站开发方面的技术文章,大部分来自学习或工作,部分来源于网络,希望对大家有所帮助。

Bootstrap中文网