创建一个以JDBC链接数据库的程序,包含七个步骤
1.加载JDBC驱动
-
- 加载要连接的数据库的驱动到JVM
- 如何加载?forName(数据库驱动)
- MySQL:Class.forName("com.mysql.jdbc.Driver");
- Oracle10g:Class.forName("oracle.jdbc.driver.OracleDriver");
- SQLServer2005:Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
-
1 //1.加载驱动程序 mysql为例子2 try {3 Class.forName("com.mysql.jdbc.Driver");4 } catch (ClassNotFoundException e) {5 // TODO Auto-generated catch block6 e.printStackTrace();7 System.out.println("加载驱动失败");8 }
2.提供JDBC连接的URL
-
- 连接URL定义了连接数据库时的协议,子协议,数据源标识
- 根据不同的数据库产品不同连接的URL不同
- Oracle10g:jdbc:oracle:thin:@主机名:端口:数据库SID
- MySQL5:jdbc:mysql://主机名:端口/数据库名
- SQLServer2005:jdbc:sqlserver://主机名:端口:DatabaseName=库名
-
-
1 /**2 * 访问数据库的地址3 */4 private final String URL = "jdbc:mysql://localhost:3306/test";
-
3.创建数据库的链接
-
- 连接数据库就要向java.sqlDriverManager请求过的Connection对象,一个Connection就代表一个数据库连接
- 在连接的时候需要传入数据库的账户和密码
-
1 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
4.创建一个Statement
-
- 获得数据库连接后,要想执行sql语句,必须获得java.sql.Statement实例,Statement实例分为三种
- 执行静态的sql语句.通过Statement实例实现
- 执行动态的sql语句.通过PreparedStatement实例实现
- 执行数据库存储过程.通常通过CallableStatement实例实现
- 获得数据库连接后,要想执行sql语句,必须获得java.sql.Statement实例,Statement实例分为三种
-
-
1 //执行静态的sql2 Statement statement = connection.createStatement();3 ResultSet resultSet = statement.executeQuery("select * from sys_user");4 System.out.println(resultSet.toString());5 6 //执行动态的sql 采用预加载的方式 可防止sql注入7 PreparedStatement prepareStatement = connection.prepareStatement("select * from sys_user");
-
5.执行sql语句
- Statement提供了三种执行查询
- ResultSet executeQuery(String sql); 执行查询数据库的sql语句,返回一个结果集(ResultSet)对象
- int executeUpdate(String sql); 执行INSERT,UPDATE或者DELETE语句以及SQL DDL语句,返回受影响行数
- execute(String sql); 用于返回多个结果集,多个更新计数或者二者组合的语句
-
1 //执行查询2 ResultSet resultSet = statement.executeQuery("select * from sys_user");3 //执行insert update delete 4 statement.executeUpdate("INSERT INTO sys_user VALUES(5,'lisi','123','李四');");
6.处理结果
- 处理结果有两种情况
- 返回本次操作的记录数 在执行executeUpdate();方法的时候会返回受影响的行数
- 返回ResultSet对象 在执行executeQuery();方法的时候会返回对象
- ResultSet对象中包含SQL查询中出的所有行,通过get方法可以获取每行的数据
-
1 //执行查询2 ResultSet resultSet = statement.executeQuery("select * from sys_user");3 while(resultSet.next()) {4 System.out.println(resultSet.getInt("uid"));5 System.out.println(resultSet.getString("username"));6 System.out.println(resultSet.getString("password"));7 System.out.println(resultSet.getString("nickname"));8 }
7.关闭JDBC对象
- 在使用完毕后需要关闭三个对象,关闭结果集(resultSet),关闭声明(Statement),关闭数据库连接(Connection)
-
1 if (resultSet != null) { // 关闭记录集2 resultSet.close();3 }4 if (statement != null) { // 关闭声明5 statement.close();6 }7 if (connection != null) { // 关闭连接对象8 connection.close();9 }
我们可以把经常使用的方法封装成一个工具类,我们一般成为jdbcUtils,下面代码时从CSDN获取,大家可以自己借鉴修改,我就不再重复打出来了
1 package com.jdbc.dbutils; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.ResultSetMetaData; 8 import java.sql.SQLException; 9 import java.util.ArrayList; 10 import java.util.HashMap; 11 import java.util.List; 12 import java.util.Map; 13 14 public class JdbcUtils { 15 /** 16 * 数据库的用户名 17 */ 18 private final String USER = "root"; 19 /** 20 * 数据库的密码 21 */ 22 private final String PASSWORD = "123456"; 23 /** 24 * 数据库的驱动信息 25 */ 26 private final String DRIVER = "com.mysql.jdbc.Driver"; 27 /** 28 * 访问数据库的地址 29 */ 30 private final String URL = "jdbc:mysql://localhost:3306/test"; 31 /** 32 * 数据库的连接 33 */ 34 Connection connection; 35 /** 36 * sql语句的执行对象 37 */ 38 PreparedStatement preparedStatement; 39 /** 40 * 查询返回的结果集合 41 */ 42 ResultSet resultSet; 43 44 public JdbcUtils() { 45 try { 46 Class.forName(DRIVER); 47 System.out.println("注册驱动成功"); 48 } catch (ClassNotFoundException e) { 49 e.printStackTrace(); 50 } 51 } 52 53 /** 54 * 连接数据库 55 * 56 * @return 数据库的连接对象 57 */ 58 public Connection getConnection() { 59 try { 60 connection = DriverManager.getConnection(URL, USER, PASSWORD); 61 } catch (SQLException e) { 62 e.printStackTrace(); 63 } 64 return connection; 65 } 66 67 /** 68 * 完成对数据库的表的添加删除和修改的操作 69 * 70 * @param sql 71 * @param params 72 * @return 73 * @throws SQLException 74 */ 75 public boolean updateByPrepareStatement(String sql, List
数据库连接池技术
- 由于我们要对数据库频繁地进行操作,每进行一次连接操作就要获取一个conntection连接,每次使用完毕后要全部关闭资源,这样的话我们可以使用数据库连接池技术
- 优点:
- 资源重用:避免重复创建,释放连接,大量节约性能开销
- 更快的响应:在连接池初始化的过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间。
- 新的资源分配手段: 对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源
- 统一的连接管理,避免数据库连接泄露: 在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露。
- 创建的数据库连接池
- DBCP:由于性能问题,已经很少使用了
- C3P0:目前在很多项目中都在使用
- Druid(阿里巴巴):阿里巴巴开源的一个数据库连接池
- 下面我们示范常用的C3p0的使用
- 导入jar包c3p0-0.9.1.2.jar
- 在项目src目录下新建c3p0.properties
- 文件内容(当然还有很多其他配置,下面最简单配置)
-
c3p0.driverClass=com.mysql.jdbc.Driverc3p0.jdbcUrl=jdbc:mysql://localhost:3306/testc3p0.user=rootc3p0.password=root
- 在与数据库交互时
-
1 //创建一个数据库连接池ComboPooledDataSource ds = new ComboPooledDataSource();2 //创建QueryRunner接口3 QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());4 //通过接口可以执行查询或者更新,修改操作5 qr.update(sql); //返回受影响的行数6 qr.query(sql, null); //返回各种类型
-
- 关于QueryRunner的query方法其实功能是很强大的,可以根据查询的内容自动封装各种类型
- 封装入一个javaBean中
-
1 public Category getById(String cid) throws Exception {2 QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());3 String sql = "select * from category where cid = ?";4 return qr.query(sql, new BeanHandler<>(Category.class), cid);5 }
- 封装成一个可以指定类型的list集合
-
1 public List
findAll() throws Exception {2 QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());3 String sql = "select * from category";4 List list = qr.query(sql, new BeanListHandler<>(Category.class));5 return list;6 } - 返回单条数据
-
1 /** 2 * 查询数据总条数 3 */ 4 @Override 5 public Integer getTotalSize() throws Exception { 6 // 创建查询接口 7 QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource()); 8 String sql = "select count(*) from links"; 9 return ((Long) qr.query(sql, new ScalarHandler())).intValue();10 }
- C3p0是在项目中是很详细的,详细的学习该请大家参考正式的文档
- 关于QueryRunner的query方法其实功能是很强大的,可以根据查询的内容自动封装各种类型