一、JDBC介绍
JDBC(Java DataBase Contectivity),Java与数据库的连接—数据库编程
JDBC是Java语言(JDK)为完成数据库的访问操作提供的一套标准
二、JDBC步骤
加载驱动,添加数据库驱动jar包,加载
创建连接
编写SQL指令
编译SQL指令
执行SQL指令
处理结果
关闭连接
三、JDBC入门案例
JDBC是用Java代码完成数据库访问的规范
3.1 加载驱动 3.1.1 下载对应数据库匹配版本的驱动jar包
MySQL数据库版本为5.x的推荐驱动版本5.1.47
MySQL为8.x的推荐使用8.0.x
3.1.2 将驱动jar文件添加到java应用
在Java应用中创建lib文件夹
将下载好的jar文件复制到lib
将驱动文件设置为java库—驱动文件(add as library)
3.1.3注册驱动
通过反射机制将驱动jar文件中提供的驱动类载入到JVM中
1 Class.forName("com.mysql.cj.jdbc.Driver" );
3.2 创建连接 1 2 3 4 5 6 7 8 9 10 11 Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3308/test1?characterEncoding=utf8&useSSL=true&useTimezone=true" ; Connection connection = DriverManager.getConnection(url,"root" ,"JBJHHZSL@0" ); System.out.println(connection);
3.3编写SQL指令 1 2 3 String sql = "insert into books(book_isbn,book_name,book_author) values " + "(‘" +book_isbn+"’,‘" +book_name+"’,‘" +book_author+"’)" ;
3.4 加载SQL指令 1 2 3 4 Statement statement = connection.createStatement();
3.5 执行SQL指令 1 2 3 4 int i = statement.executeUpdate(sql);
3.6 处理结果 1 2 3 4 5 6 System.out.println(i>0 ?"添加成功" :"添加失败" );
3.7 关闭连接 1 2 3 4 5 6 System.out.println(i>0 ?"添加成功" :"添加失败" );
四、JDBC增删查改实例练习
使用JDBC完成数据库的CRUD访问
4.1 insert操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class TestInsertBook { public static void main (String[] args) throws ClassNotFoundException, SQLException { int book_id = 1004 ; String book_name = "name3" ; String book_author = "au3" ; Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3308/test1?characterEncoding=utf8&useSSL=true&useTimezone=true" ; Connection connection = DriverManager.getConnection(url,"root" ,"JBJHHZSTSL@0" ); System.out.println(connection); String sql = "insert into books(book_isbn,book_name,book_author) values ('" +book_id+"','" +book_name+"','" +book_author+"')" ; Statement statement = connection.createStatement(); int i = statement.executeUpdate(sql); System.out.println(i>0 ?"添加成功" :"添加失败" ); if (!statement.isClosed()) { statement.close(); } if (!connection.isClosed()) { connection.close(); }
4.2 delete 操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public class TestDeleteBook { public static void main (String args[]) throws ClassNotFoundException, SQLException { int bid = 1001 ; Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3308/test1" ; Connection connection = DriverManager.getConnection(url,"root" ,"JBJHHZSTSL@0" ); String sql = "delete from books where book_isbn=" +bid; Statement statement = connection.createStatement(); int i = statement.executeUpdate(sql); System.out.println(i>0 ?"删除成功" :"删除失败" ); if (statement != null && !statement.isClosed()) { statement.close(); } if (connection != null && !connection.isClosed()) { connection.close(); } } }
4.3.update 操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class TestUpdateBook { public static void main (String args[]) throws ClassNotFoundException, SQLException { int bid = 1002 ; Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3308/test1" ; Connection connection = DriverManager.getConnection(url,"root" ,"JBJHHZSTSL@0" ); String sql = "update books set book_name='java' where book_isbn=" + bid; Statement statement = connection.createStatement(); int i = statement.executeUpdate(sql); System.out.println(i>0 ?"更新成功" :"更新失败" ); if (statement != null && !statement.isClosed()){ statement.close(); } if (connection != null && !connection.isClosed()){ connection.close(); } } }
4.4.select 操作
重点在结果集rs 的处理
1 2 3 4 5 6 7 8 9 ResultSet rs = statement.executeQuery(sql); while (rs.next()){ int book_id = rs.getInt("book_isbn" ); String book_name = rs.getString("book_name" ); String book_author = rs.getString("book_author" ); System.out.println(book_id +"-" +book_name+"-" +book_author); }
五、JDBC的核心类与接口
java.sql.DriverManager类 驱动管理器
java.sql.Connection接口 数据库连接
java.sql.Statement接口 SQL指令的加载器
java.sql.ResultSet接口 结果集
5.1 DriverManager 类
注册驱动
1 2 3 4 Class.forName("com.mysql.cj.jdbc.Driver" );
获取数据库连接
1 Connection connection = DriverManager . getConnection(url ,username ,paswd ) ;
5.2 Connection 接口
Connection对象表示java应用于数据库之间的连接
通过Connection接口对象,获取执行SQL语句的Statement对象
完成数据库的事务管理
5.2.1 获取Statement对象
5.2.2 事务管理
1 2 3 4 5 6 7 8 connection.setAutoCommit(false ); connection.rollback(); connerction.commit();
5.3 Statement接口
用于编译、执行静态SQL指令
静态SQL指令:可以直接执行的完整SQL指令
动态SQL指令:带有占位符的SQL指令,不能直接执行
1 2 3 4 5 int i = statement.executeUpdate(sql);ResultSet rs = statement.executeQuery(sql);
5.4 ResultSet 接口
ResultSet 接口对象用于封装查询操作的结果集
1 2 3 4 5 6 while (rs.next()){...};rs.getInt("columnname" ); rs.getDate("" );
六、SQL注入问题 6.1SQL注入介绍
在JDBC的SQL指令编写过程中,如果SQL指令中需要数据,可以通过字符串拼接的形式将参数拼接到SQL指令中,参数变化可能导致SQL原意变化,导致对数据的非法操作
6.2 如何解决SQL注入问题
使用PreparedStatement 进行SQL指令的预编译
在编写SQL指令时,如果SQL指令中需要参数,一律使用 ? 占位符
如果SQL指令中有占位符?,则使用preraredstatement对象预编译SQL指令
预编译完成之后,通过PreparedStatement对象给预编译后的SQL语句赋值
在所有SQL指令中的?被赋值之后,通过PreparedStatement来执行SQL,执行SQL时不再加载SQL
int i = preparedStatement.executeUpdate(); 括号内不传参
tip:
七、工具类 7.1代码的复用性 在我们的程序中,如果需要完成相同的操作,相同的代码无需重复编写,我们只需要一次编写即可
7.2 工具类DBHelper封装
JDBC数据库编程有一个固定的步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 package utils;import java.sql.*;public class DBHelper { private static final String DRIVER = "com.mysql.cj.jdbc.Driver" ; private static final String URL = "jdbc:mysql://localhost:3308/test1" ; private static final String USER = "root" ; private static final String PASSWORD = "JBJHHZSTSL@0" ; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { System.out.println("---------注册驱动失败" ); } } public static Connection getConnection () { Connection connection = null ; try { connection = DriverManager.getConnection(URL,USER,PASSWORD); } catch (SQLException e) { System.out.println("---------创建连接失败" ); } return connection; } public static void closeConnection (Statement statement,Connection connection) { closeConnection(null ,statement,connection); } public static void closeConnection (ResultSet resultSet,Statement statement,Connection connection) { try { if (resultSet != null && !resultSet.isClosed()) { resultSet.close(); } if (statement != null && !statement.isClosed()) { statement.close(); } if (connection != null && !connection.isClosed()) { connection.close(); } } catch (SQLException e) { System.out.println("------关闭连接失败" ); } } }
八、DAO 与 DTO的封装
DAO(Data Access Object) 数据访问对象
DTO(Data Transfer Object) 数据传输对象
8.1 CRUD方法的封装
面向对象编程的特征之一——封装
即要将完成某个CRUD操作的代码单独定义成一个方法
添加insert :
1 2 3 4 5 6 7 8 9 10 11 public boolean insertBook (int book_id,String book_name,String book_author) throws SQLException { boolean flag = false ; Connection connection = DBHelper.getConnection(); String sql = "insert into books(book_isbn,book_name,book_author) values ('" +book_id+"','" +book_name+"','" +book_author+"')" ; Statement statement = connection.createStatement(); int i = statement.executeUpdate(sql); flag = i > 1 ; DBHelper.closeConnection(statement,connection); return flag; }
8.2 DTO实体类封装
处理:在Java程序中创建一个属性与数据库表匹配的类,通过此类的对象来封装查询到的数据,我们把用于传递JDBC增删查改操作的数据的对象称为数据传输对象(DTO)
实体类的创建规则
实体类实例 :
省略get和set方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class Book { private int bookId; private String bookName; private String bookAuthor; public Book (int bookId, String bookName, String bookAuthor) { this .bookId = bookId; this .bookName = bookName; this .bookAuthor = bookAuthor; } public Book () { } @Override public String toString () { return "Book{" + "bookId=" + bookId + ", bookName='" + bookName + '\'' + ", bookAuthor='" + bookAuthor + '\'' + '}' ; }
8.3 使用DTO封装多条记录
每条查询的结果分别存放到一个实体对象中,再将多个DTO对象存放到一个List集合中,返回list集合
8.4 实体类传递参数 8.5 DAO封装
我们将对数据库中同一张表的JDBC操作方法封装到同一个Java类中,这个类就是访问此数据表的数据访问对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 package dao;import dto.Book;import utils.DBHelper;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import java.sql.Statement;public class BookDao { public boolean insertBook (int book_id,String book_name,String book_author) throws SQLException { boolean flag = false ; Connection connection = DBHelper.getConnection(); String sql = "insert into books(book_isbn,book_name,book_author) values ('" +book_id+"','" +book_name+"','" +book_author+"')" ; Statement statement = connection.createStatement(); int i = statement.executeUpdate(sql); flag = i > 1 ; DBHelper.closeConnection(statement,connection); return flag; } public boolean deleteBook (Book book) throws SQLException { boolean flag = false ; Connection connection = DBHelper.getConnection(); String sql = "delete from books where book_isbn=?" ; PreparedStatement prepareStatement = connection.prepareStatement(sql); prepareStatement.setInt(1 ,book.getBookId()); int i = prepareStatement.executeUpdate(); flag = i>0 ; DBHelper.closeConnection(prepareStatement,connection); return flag; } }
8.6 DAO类的优化
1.在应用程序开发中,如果方法中抛出异常且自己可以处理,则直接通过try catch代码块进行捕获处理
2.JDBC操作方法的连接需要放在finally中进行关闭
3.将数据库连接connection 和 statement 、resultset等对象定义在try语句之前,在try语句中直接赋值
4.因为所有的JDBC操作都需要Connection,statement,resultset等对象,因此在DAO中可以将这些对象定义为成员变量
九、JDBC的综合案例
完成学生信息的CRUD操作
9.1 JDBC 数据库编程的流程
创建数据库,数据表
创建新的Java工程
创建JDBC的工具类DBHelper
创建DTO类(用于封装数据对象)
创建DAO类(用于完成对数据的操作)
9.2 创建JDBC工具类
在Java工程中创建package:com.jdbc.utils
在com.jdbc.utils里面创建工具类HBHelper
编写DBHelper工具类
9.3 创建DTO类
新建一个package dto
在dto包中创建数据表对应的实体类
编写实体类代码
9.4 创建DAO类
新建package dao
在dao包中创建类
编写dao类的代码
9.5 测试DAO类中的方法
使用Junit对DAO中定义的JDBC方法进行单元测试
9.5.1 下载导入junit依赖到项目中
下载 mvnrepository.com-
添加为Lib
9.5.2 创建单元测试类
可以对某个类中的方法进行单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package com.jdbc.test;import com.jdbc.dao.StudentDao;import com.jdbc.dto.Student;import org.junit.Test;import java.util.List;import static org.junit.jupiter.api.Assertions.*;public class StudentDaoTest { private StudentDao studentDao = new StudentDao(); @Test public void testInsertStudent () { Student stu = new Student("20211021" ,"钱倒一" ,"女" ,18 ,1 ); boolean b = studentDao.insertStudent(stu); assertTrue(b); } @Test public void testQueryStudent () { String snum = "20211021" ; Student student = studentDao.queryStudent(snum); assertEquals("钱一" ,student.getStuName()); } @Test public void testListStudent () { List<Student> students = studentDao.listStudents(); assertEquals(8 ,students.size()); } }
十、JDBC事务管理
10.1 JDBC实现借书操作
1.向records表添加借书记录
2.修改books表中的库存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package com.jdbc.dao;import com.jdbc.utils.DBHelper;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class BookDAO { public boolean borrowBook (String stuNum,String bookId,int num) { boolean flag = false ; try { Connection connection = DBHelper.getConnection(); String sql1 = "insert into records(snum,bid,borrow_num,is_return,borrow_data) values(?,?,?,0,sysdate())" ; PreparedStatement preparedStatement = connection.prepareStatement(sql1); preparedStatement.setString(1 ,stuNum); preparedStatement.setString(2 ,bookId); preparedStatement.setInt(3 ,num); int i = preparedStatement.executeUpdate(); Connection connection2 = DBHelper.getConnection(); String sql2 = "update books set book_stock=book_stock-? where book_id=?" ; PreparedStatement preparedStatement2 = connection2.prepareStatement(sql2); preparedStatement2.setInt(1 ,num); preparedStatement2.setString(2 ,bookId); int j = preparedStatement2.executeUpdate(); flag = i >0 && j>0 ; } catch (SQLException e){ e.printStackTrace(); } finally { } return flag; } }
分析 :
借书业务由两个数据库操作完成,这两个操作要么同时成功要么同时失败,构成一个数据库事务
JDBC的DML操作默认是自动提交的,因此当第一个DLM操作(添加借书记录)完成后,无论第二个操作是否成功,借书记录都会永久添加到数据库
JDBC如何做事务管理呢?
10.2 JDBC事务管理
1.一个事务中的多个DML操作需要基于同一个数据库连接
2.创建连接之后设置事务手动提交
3.在当前事务中的所有操作完成之后手动提交
4.当事务中的任何一个步骤失败后执行事务回滚
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 package com.jdbc.dao;import com.jdbc.utils.DBHelper;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class BookDAO { public boolean borrowBook (String stuNum,String bookId,int num) { boolean flag = false ; Connection connection = null ; PreparedStatement preparedStatement = null ; PreparedStatement preparedStatement2 = null ; try { connection = DBHelper.getConnection(); connection.setAutoCommit(false ); String sql1 = "insert into records(snum,bid,borrow_num,is_return,borrow_data) values(?,?,?,0,sysdate())" ; preparedStatement = connection.prepareStatement(sql1); preparedStatement.setString(1 ,stuNum); preparedStatement.setString(2 ,bookId); preparedStatement.setInt(3 ,num); int i = preparedStatement.executeUpdate(); int k = 10 /0 ; String sql2 = "update books set book_stock=book_stock-? where book_id=?" ; preparedStatement2 = connection.prepareStatement(sql2); preparedStatement2.setInt(1 ,num); preparedStatement2.setString(2 ,bookId); int j = preparedStatement2.executeUpdate(); connection.commit(); flag = i >0 && j>0 ; } catch (Exception e){ e.printStackTrace(); try { connection.rollback(); } catch (SQLException ex) { throw new RuntimeException(ex); } } finally { DBHelper.close(preparedStatement,null ); DBHelper.close(preparedStatement2,connection); } return flag; } }
10.3 service层的事务管理
DAO只负责数据库的操作,业务由service层进行管理
10.3.1 Service 分层介绍
DAO只负责特定的数据库操作
Service进行业务处理
10.3.2 Service 分层实现
RecordDAO
BookDAO
创建Bookservice
10.3.3 Service 事务管理
service层事务中多个数据的DML操作是相互独立的,如何保证所有DML操作要么同时成功要么同时失败呢?
多个DML操作需要基于同一个数据库连接
第一个DML操作之前设置事务手动提交
如何实现多个DAO基于同一个数据库连接?
Service 层通过传递Connection连接对象的方式实现多个DML操作使用同一个连接
分析:DAO类中的Connection对象需要通过Service传递给进来,但是当我们通过面向接口开发时,容易造成接口冗余(接口污染)
使用ThreadLocal容器,实现多个DML操作的同一连接
存储Connection对象可以使用List容器,但是在多线程并发编程中会出现资源竞争问题
为了解决并发编程的连接对象共享问题,我们可以使用ThreadLocl作为数据库连接对象的容器
**ThreadLocal:**内部维护一个Map集合,可以为每一个线程存储一个连接对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 package com.jdbc.utils;import java.sql.*;import java.util.ArrayList;import java.util.List;public class DBHelper { private static final String DRIVER = "com.mysql.cj.jdbc.Driver" ; private static final String URL = "jdbc:mysql://localhost:3308/db_test1?characterEncoding=utf8" ; private static final String USER = "root" ; private static final String PASSWORD = "JBJHHZSS0" ; private static final ThreadLocal<Connection> container = new ThreadLocal<>(); static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection () { Connection connection = container.get(); try { if (connection == null ) { connection = DriverManager.getConnection(URL, USER, PASSWORD); container.set(connection); } } catch (SQLException e) { e.printStackTrace(); } return connection; } public static void closeConnection () { Connection connection = container.get(); try { if (connection != null && !connection.isClosed()){ connection.close(); } container.remove(); } catch (SQLException e) { e.printStackTrace(); } } public static void closeStatement (ResultSet resultSet, Statement statement) { try { if (resultSet != null && !resultSet.isClosed()) { resultSet.close(); } if (statement != null && !statement.isClosed()) { statement.close(); } } catch (SQLException e) { e.printStackTrace(); } } public static void closeStatement (Statement statement) { closeStatement(null ,statement); } }
十一、数据库连接池 11.1概念
如果每个JDBC操作都创建一个连接,使用完成之后销毁,JVM会因为频繁地创建、销毁连接而占用额外的系统资源
数据库连接本质上是可以被重用的资源
因此创建一个存放连接的容器,用于存放数据库连接,当我们进行JDBC操作室,直接从这个容器中获取连接,如果容器中没有数据库连接或者没有空闲的连接,才重新建立连接使用(新建立的连接也被放入连接池)
数据库连接池是有容量的,如果连接池中没有闲置连接对象或者容量已满,则新的DML操作就会进行等待
连接池: 存放数据库连接对象的容器
作用 :对数据库连接进行管理
11.2 常用的连接池
我们可以编程实现创建一个数组或者集合来存放数据库连接
目前市面上已有多种实现的数据库连接池,我们无需再手动实现
基于连接池的性能,使用的便捷性以及连接池的性能监控多方面综合,druid是目前企业中应用最广泛的连接池
HikariCp诸多竞品中最好的
11.3 使用数据库连接池Druid 11.3.1 创建应用
11.3.2 创建连接池属性配置文件
创建druid.properties文件
配置druid连接池的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 driverClassName =com.mysql.cj.jdbc.Driver url =jdbc:mysql://localhost:3308/db_test1 username =root password =JBJHHZSTSL@0 maxActive =50 initialSize =10 minIdle =5 maxWait =30000
11.3.3 创建连接池工具类
下载并导入Druid的jar文件
创建DruidUtils工具类(与属性文件在同一个包下)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package com.jdbc.utils;import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.druid.pool.DruidDataSourceFactory;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;public class DruidUtils { private static DruidDataSource druidDataSource; static { try { InputStream is = DruidUtils.class.getResourceAsStream("druid.properties" ); Properties properties = new Properties(); properties.load(is); druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection () { Connection connection = null ; try { connection = druidDataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return connection; } public static DruidDataSource getDruidDataSource () { return druidDataSource; } }
十二、通用JDBC操作封装
在DAO层的JDBC操作中,对数据表的增删改查操作存在代码的冗余
12.1 DML操作封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.jdbc.dao;import com.jdbc.utils.DruidUtils;import java.sql.Connection;import java.sql.PreparedStatement;public class CommonDAO { public boolean update (String asql,Object... args) { boolean flag = false ; try { Connection connection = DruidUtils.getConnection(); String sql = asql; PreparedStatement preparedStatement = connection.prepareStatement(sql); for (int i = 0 ; i < args.length; i++) { preparedStatement.setObject(i+1 ,args[i]); } int i = preparedStatement.executeUpdate(); flag = i>0 ; } catch (Exception e){ e.printStackTrace(); } return flag; } }
12.2 DQL操作封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public List<Student> listStudents () { String sql = "select stu_num,stu_name,stu_gender,stu_age,cid from students" ; CommonDAO<Student> commonDAO = new CommonDAO<Student>(); RowMapper<Student> rowMapper = new RowMapper<Student>() { @Override public Student getRow (ResultSet resultSet) { Student student = null ; try { String stuNum = resultSet.getString("stu_num" ); String stuName = resultSet.getString("stu_name" ); String stuGender = resultSet.getString("stu_gender" ); int stuAge = resultSet.getInt("stu_age" ); int stuCid = resultSet.getInt("cid" ); student = new Student(stuNum,stuName,stuGender,stuAge,stuCid); } catch (SQLException e) { e.printStackTrace(); } return student; } }; return commonDAO.select(sql,rowMapper); }
十三、Apache DBUtils 13.1 DBUtils介绍
Commons DBUtils 是Apache 组织提供的一个针对JDBC进行简单封装的开源工具类, 使用DBUtils可以极大简化JDBC应用开发程序开发,同时不会影响数据库访问的性能
提供对数据表通用的DML操作
提供通用的DQL操作
核心类:
QueryRunner,用于执行SQL指令:update操作和query操作
ResultSetHandler接口,结果集处理器
13.2 DBUtils使用准备
新建Java工程
添加依赖:
jdbc mysql的驱动jar
Druid的jar包
DBUtils 的jar包
配置druid的属性文件
新建一个utils文件夹
文件夹中新建文件druid.properties
创建连接池工具类
在工具包中创建DruidUtils工具类
编写工具类
13.3 DBUtils使用
完成图书信息的数据库操作
13.3.1 添加操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public int insertBook (Book book) { int i = 0 ; try { String sql = "insert into books(book_id,book_name,book_stock) values(?,?,?)" ; Object[] params = {book.getBookId(),book.getBookName(),book.getBookStock()}; QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource()); i = queryRunner.update(sql, params); } catch (SQLException e) { e.printStackTrace(); } return i; }
13.3.2 删除操作 1 2 3 4 5 6 7 8 9 10 11 12 public int deleteBook (String bid) { int i = 0 ; String sql = "delete from books where book_id=?" ; QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource()); try { i = queryRunner.update(sql,bid); } catch (SQLException e) { e.printStackTrace(); } return i; }
13.3.3 修改操作 1 2 3 4 5 6 7 8 9 10 11 12 13 public int updateBook (Book book) { int i = 0 ; try { String sql = "update books set book_name=?,book_stock=? where book_id=?" ; Object[] params = {book.getBookName(),book.getBookStock(),book.getBookId()}; QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource()); i = queryRunner.update(sql,params); } catch (SQLException e) { e.printStackTrace(); } return i; }
13.3.4 查询操作
查询一条记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public Book queryBook (String bookId) { Book book = null ; String sql = "select book_id bookId,book_name bookName,book_stock bookStock from books where book_id=?" ; QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource()); BeanHandler<Book> beanHandler = new BeanHandler<Book>(Book.class); try { book = queryRunner.query(sql, beanHandler, bookId); } catch (SQLException e) { e.printStackTrace(); } return book; }
查询多条记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public List<Book> listBooks () { List<Book> bookList = null ; String sql = "select book_id bookId,book_name bookName,book_stock bookStock from books" ; QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource()); BeanListHandler<Book> beanListHandler = new BeanListHandler<Book>(Book.class); try { bookList = queryRunner.query(sql, beanListHandler); } catch (SQLException e) { e.printStackTrace(); } return bookList; }
13.3.5 查询一个值 1 2 3 4 5 6 7 8 9 10 11 12 13 public int getCount () { int count = 0 ; String sql = "select count(1) from books" ; ScalarHandler<Integer> scalarHandler = new ScalarHandler<Integer>(); QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource()); try { count = queryRunner.query(sql, scalarHandler); } catch (SQLException e) { e.printStackTrace(); } return count; }
2022-10-19完结