Jdbc
1.概述 1.JDBC为访问不同的数据库提供了统一的接口,为使用者屏蔽了细节问题 2.Java程序员使用JDBC,可以连接任何提供了JDBC驱动程序的数据库系统,从而完成对数据库的各种操作 3.java利用Jdbc规定一套接口规范,让不同的数据库厂商实现,在java程序中直接调用接口的方法即可,java程序员直接面对接口编程即可 4.JDBC相关类和接口在java.sql和javax.sql包中
1.1总体步骤 (1) 加载驱动 -- 加载Driver 类
(2) 获取连接 -- connection
(3) 写sql语句 -- CRUD
(4) 释放资源-- close
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 mport java.sql.*;import java.util.Properties;import java.util.logging.Logger;import com.mysql.jdbc.Driver;public class jdbc01 { public static void main (String[] args) throws SQLException { Driver driver = new Driver (); String url = "jdbc:mysql://127.0.0.1:3306/haozi" ; Properties properties = new Properties (); properties.setProperty("user" ,"root" ); properties.setProperty("password" ,"5399joker" ); Connection connect = driver.connect(url, properties); String sql = "insert into test1 values(1,'耗子',18)" ; Statement statement = connect.createStatement(); int rows = statement.executeUpdate(sql); System.out.println(rows>0 ? "成功" :"失败" ); statement.close(); connect.close(); } }
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 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 80 81 82 83 84 85 86 import com.mysql.jdbc.Driver;import org.junit.Test;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.Properties;public class JdbcConn { @Test public void connect01 () throws SQLException { Driver driver = new Driver (); String url = "jdbc:mysql://127.0.0.1:3306/haozi" ; Properties properties = new Properties (); properties.setProperty("user" ,"root" ); properties.setProperty("password" ,"5399joker" ); Connection connect = driver.connect(url, properties); System.out.println(connect); } @Test public void connect02 () throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException { Class<?> aClass = Class.forName("com.mysql.jdbc.Driver" ); Driver driver = (Driver) aClass.newInstance(); String url = "jdbc:mysql://127.0.0.1:3306/haozi" ; Properties properties = new Properties (); properties.setProperty("user" ,"root" ); properties.setProperty("password" ,"5399joker" ); Connection connect = driver.connect(url, properties); System.out.println(connect); } @Test public void connect03 () throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException { Class<?> aClass = Class.forName("com.mysql.jdbc.Driver" ); Driver driver = (Driver) aClass.newInstance(); String url = "jdbc:mysql://127.0.0.1:3306/haozi" ; String user = "root" ; String password = "5399joker" ; DriverManager.registerDriver(driver); Connection connection = DriverManager.getConnection(url, user, password); System.out.println(connection); } @Test public void connect04 () throws ClassNotFoundException,SQLException{ Class.forName("com.mysql.jdbc.Driver" ); String url = "jdbc:mysql://127.0.0.1:3306/haozi" ; String user = "root" ; String password = "5399joker" ; Connection connection = DriverManager.getConnection(url,user,password); System.out.println(connection); } @Test public void connect05 () throws IOException, ClassNotFoundException, SQLException { Properties properties = new Properties (); properties.load(new FileInputStream ("src\\mysql.properties" )); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); String driver = properties.getProperty("driver" ); String url = properties.getProperty("url" ); Connection connection = DriverManager.getConnection(url,user,password); System.out.println(connection); } }
3.ResultSet(结果集) 1.表示数据库结果集的数据表,通常通过执行查询数据库的语句生成 2.ResultSet对象保持一个光标指向其当前的数据行,最初,光标位于第一行之前 3.next方法将光标移动到下一行,并且由于在ResultSet对象中没有更多行时返回false,因此可以在while循环中使用循环来遍历结果集
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 import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.sql.*;import java.util.Properties;public class ResultSet_ { public static void main (String[] args) throws IOException, SQLException { Properties properties = new Properties (); properties.load(new FileInputStream ("src\\mysql.properties" )); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); String driver = properties.getProperty("driver" ); String url = properties.getProperty("url" ); Connection connection = DriverManager.getConnection(url,user,password); Statement statement = connection.createStatement(); String sql = "select id,name,age from test1" ; ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()){ int id = resultSet.getInt(1 ); String name = resultSet.getNString(2 ); int age = resultSet.getInt(3 ); System.out.println(id+"\t" +name+"\t" +age); } resultSet.close(); statement.close(); connection.close(); } }
4.SQL注入 1.Statement对象用于执行静态SQL语句并返回其生成的结果的对象 2.在连接建立后,需要对数据库进行访问,执行命令或是SQL语句,可以通过 Statement [存在SQL注入] PreparedStatement [预处理] CallableStatement [存储过程] 3.Statement对象执行SQL语句,存在SQL注入风险 4.要防范SQL注入,只要用PreparedStatement(从Statement扩展而来)取代Statement就可以了
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 import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.sql.*;import java.util.Properties;import java.util.Scanner;public class Statement_ { public static void main (String[] args) throws IOException, SQLException { Scanner sc = new Scanner (System.in); System.out.print("请输入管理员的名字:" ); String admin_name = sc.nextLine(); System.out.print("请输入管理员的密码:" ); String admin_passwd = sc.nextLine(); Properties properties = new Properties (); properties.load(new FileInputStream ("src\\mysql.properties" )); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); String driver = properties.getProperty("driver" ); String url = properties.getProperty("url" ); Connection connection = DriverManager.getConnection(url,user,password); Statement statement = connection.createStatement(); String sql = "select name,pwd from admin where name ='" +admin_name+"'and pwd = '" +admin_passwd+"'" ; ResultSet resultSet = statement.executeQuery(sql); if (resultSet.next()){ System.out.println("登陆成功" ); }else { System.out.println("登陆失败" ); } resultSet.close();; statement.close();; connection.close(); } }
5.PreparedStatement预处理 1.PreparedStatement执行的SQL语句中的参数用问号来表示,调用PreparedStatement对象的setXxx()方法来设置这些参数,setXxx()方法有两个参数,第一个参数是要设置的SQL语句中的参数的索引(从1开始),第二个是设置的SQL语句中的参数的值 2.调用excuteQuery()返回ResultSet对象 3.调用excuteUpdate()执行更新,包括增、删、修改
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 import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.sql.*;import java.util.Properties;import java.util.Scanner;public class PreparedStatement_ { public static void main (String[] args) throws IOException, SQLException { Scanner sc = new Scanner (System.in); System.out.print("请输入管理员的名字:" ); String admin_name = sc.nextLine(); System.out.print("请输入管理员的密码:" ); String admin_passwd = sc.nextLine(); Properties properties = new Properties (); properties.load(new FileInputStream ("src\\mysql.properties" )); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); String driver = properties.getProperty("driver" ); String url = properties.getProperty("url" ); Connection connection = DriverManager.getConnection(url,user,password); String sql = "select name,pwd from admin where name = ? and pwd = ? " ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1 ,admin_name); preparedStatement.setString(2 ,admin_passwd); ResultSet resultSet = preparedStatement.executeQuery(); if (resultSet.next()){ System.out.println("登陆成功" ); }else { System.out.println("登陆失败" ); } resultSet.close(); preparedStatement.close(); connection.close(); } }
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 public class PreparedStatementDML_ { public static void main (String[] args) throws IOException, SQLException { Scanner sc = new Scanner (System.in); System.out.print("请输入ID:" ); String admin_ID = sc.nextLine(); System.out.print("请输入管理员的名字:" ); String admin_name = sc.nextLine(); System.out.print("请输入管理员的密码:" ); String admin_passwd = sc.nextLine(); Properties properties = new Properties (); properties.load(new FileInputStream ("src\\mysql.properties" )); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); String driver = properties.getProperty("driver" ); String url = properties.getProperty("url" ); Connection connection = DriverManager.getConnection(url,user,password); String sql = "insert into admin values (?,?,?)" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(2 ,admin_name); preparedStatement.setString(1 ,admin_ID); preparedStatement.setString(3 ,admin_passwd); int rows = preparedStatement.executeUpdate(); System.out.println(rows>0 ?"执行成功" :"执行失败" ); preparedStatement.close(); connection.close(); } }
6.通过自定义的JDBCUtils工具包来操作数据库 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 public class JDBCUtils { private static String user; private static String password; private static String url; private static String driver; static { try { Properties properties = new Properties (); properties.load(new FileInputStream ("src\\mysql.properties" )); user =properties.getProperty("user" ); password = properties.getProperty("password" ); url = properties.getProperty("url" ); driver = properties.getProperty("driver" ); }catch (IOException e) { throw new RuntimeException (e); } } public static Connection getConnection () { try { return DriverManager.getConnection(url,user,password); }catch (SQLException e){ throw new RuntimeException (e); } } public static void close (ResultSet set, Statement statement,Connection connection) { try { if (set != null ) { set.close(); } if (statement != null ) { statement.close(); } if (connection != null ) { connection.close(); } }catch (SQLException e){ throw new RuntimeException (e); } } }
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 public class JDBCUtils_Use { public static void main (String[] args) { } @Test public void testSelect () { Connection connection = null ; PreparedStatement preparedStatement=null ; ResultSet set = null ; String sql = "select * from test1" ; try { connection = JDBCUtils.getConnection(); preparedStatement = connection.prepareStatement(sql); set = preparedStatement.executeQuery(); while (set.next()){ int id = set.getInt("id" ); String name = set.getString("name" ); int age = set.getInt("age" ); System.out.println(id+"\t" +name+"\t" +age); } }catch (SQLException e){ e.printStackTrace(); }finally { JDBCUtils.close(set,preparedStatement,connection); } } @Test public void testDML () { Connection connection = JDBCUtils.getConnection(); PreparedStatement preparedStatement = null ; String sql = "update test1 set name = ? where id = ?" ; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1 ,"强子" ); preparedStatement.setInt(2 ,1 ); preparedStatement.executeUpdate(); }catch (SQLException e){ e.printStackTrace(); }finally { JDBCUtils.close(null ,preparedStatement,connection); } } }
7.事务 1.JDBC程序中当一个Connection对象创建时,默认下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚 2.JDBC程序中为了让多个SQL语句作为一个整体执行,需要使用事务 3.调用Connection的setAutoCommit(false)可以取消自动提交事务 4.再所有的SQL语句都成功执行后,调用Connection的commit();方法提交事务 5.通过调用Connection的rollback();方法回滚事务
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 public class Transaction_ { @Test public void noTransaction () { Connection connection = null ; String sql1 = "update account set balance = balance -100 where id = 1" ; String sql2= "update account set balance = balance +100 where id = 2" ; PreparedStatement preparedStatement = null ; try { connection = JDBCUtils.getConnection(); preparedStatement = connection.prepareStatement(sql1); preparedStatement.executeUpdate(); int i = 1 /0 ; preparedStatement = connection.prepareStatement(sql2); preparedStatement.executeUpdate(); }catch (SQLException e){ e.printStackTrace(); }finally { JDBCUtils.close(null ,preparedStatement,connection); } } @Test public void useTransaction () { Connection connection = null ; String sql1 = "update account set balance = balance -100 where id = 1" ; String sql2= "update account set balance = balance +100 where id = 2" ; PreparedStatement preparedStatement = null ; try { connection = JDBCUtils.getConnection(); connection.setAutoCommit(false ); preparedStatement = connection.prepareStatement(sql1); preparedStatement.executeUpdate(); preparedStatement = connection.prepareStatement(sql2); preparedStatement.executeUpdate(); connection.commit(); }catch (SQLException e){ System.out.println("执行发生了异常,撤销执行的sql" ); try { connection.rollback(); }catch (SQLException throwables){ throwables.printStackTrace(); } e.printStackTrace(); }finally { JDBCUtils.close(null ,preparedStatement,connection); } } }
8.批处理 1.当需要成批插入或者更新记录时,可以采用java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理,通常情况下比单独提交处理更有效率 2.JDBC的批量处理语句包括下面方法: 2.1addBatch():添加需要批量处理的SQL语句或参数 2.2executeBatch():执行批量处理语句 2.3clearBatch();清空批处理包的语句 3.JDBC连接MySQL时,如果要使用批处理功能,请再url中添加参数?rewriteBatchedStatements=true; 4.批处理往往和PreparedStatement一起搭配使用,既可以减少编译次数,又减少运行次数,效率大大提高
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 public class Batch_ { @Test public void noBatch () throws Exception{ Connection connection = JDBCUtils.getConnection(); String sql = "insert into admin2 values(null,?,?)" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); long start = System.currentTimeMillis(); for (int i = 0 ;i<500 ;i++){ preparedStatement.setString(1 ,"jack" +i); preparedStatement.setString(2 ,"666" ); preparedStatement.executeUpdate(); } long end = System.currentTimeMillis(); System.out.println("耗时" +(end-start)); JDBCUtils.close(null ,preparedStatement,connection); } @Test public void batch () throws Exception{ Connection connection = JDBCUtils.getConnection(); String sql = "insert into admin2 values(null,?,?)" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); long start = System.currentTimeMillis(); for (int i = 0 ;i<500 ;i++){ preparedStatement.setString(1 ,"jack" +i); preparedStatement.setString(2 ,"666" ); preparedStatement.addBatch(); if ((i+1 )%100 ==0 ){ preparedStatement.executeBatch(); preparedStatement.clearBatch(); } } long end = System.currentTimeMillis(); System.out.println("批量方式耗时" +(end-start)); JDBCUtils.close(null ,preparedStatement,connection); } }
9.数据库连接池 1.传统的JDBC数据库连接使用DriverManager来获取,每次获取连接的时候都要将Connection加载到内存,在验证,频繁的连接数据库会占用很多系统资源,容易造成崩溃 2.每一次数据库连接,使用完后都得断开,如果程序出现异常而未能关闭,将导致数据库内存泄漏 3.传统的连接方式不能控制创建连接的数量 4.解决可以使用数据库连接池技术(connection pool) 5.预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从”缓冲池”中取出一个,使用完毕后再放回去 6.数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个 7.当出现很多请求连接数据库时,这些请求将被加入到等待队列
9.1连接池种类 1.JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方提供实现 2.C3P0数据库连接池,速度相对较慢,稳定性不错(hibernate,spring) 3.DBCP数据库连接池,速度相对C3p0较快,但不稳定 4.Proxool数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点 5.BoneCP数据库连接池,速度快 6.Druid(德鲁伊)是阿里提供的数据库连接池,很多优点,推荐用
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 public class C3P0_ { @Test public void testC3P0_01 () throws Exception{ ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource (); Properties properties = new Properties (); properties.load(new FileInputStream ("src\\mysql.properties" )); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); String url = properties.getProperty("url" ); String driver = properties.getProperty("drover" ); comboPooledDataSource.setDriverClass(driver); comboPooledDataSource.setJdbcUrl(url); comboPooledDataSource.setUser(user); comboPooledDataSource.setPassword(password); comboPooledDataSource.setInitialPoolSize(10 ); comboPooledDataSource.setMaxPoolSize(50 ); Connection connection = comboPooledDataSource.getConnection(); System.out.println("连接成功" ); } }
10.德鲁伊连接池 1 2 3 4 5 6 7 8 9 10 配置文件key =vlauedriverClassName =com.mysql.jdbc.Driverurl =jdbc:mysql://127.0.0.1:3306/haozi?rewriteBatchedStatements=trueusername =rootpassword =5399jokerinitialSize =10minIdle =5maxActive =50maxWait =5000
1 2 3 4 5 6 7 8 9 10 public void testDruid () throws Exception { Properties properties = new Properties (); properties.load(new FileInputStream ("src\\Druid-config.perproties" )); DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); Connection connection = dataSource.getConnection(); System.out.println("连接成功" ); connection.close(); }
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 配置文件public class JDBCUtilsByDruid { private static DataSource ds; static { Properties properties = new Properties(); try { properties.load(new FileInputStream("src\\Druid-config.perproties" )); ds = DruidDataSourceFactory.createDataSource(properties); }catch (Exception e){ e.printStackTrace(); } } public static Connection getConnection () throws SQLException { return ds.getConnection () ; } public static void close (ResultSet resultSet, Statement statement,Connection connection) { try { if (resultSet!=null ){ resultSet.close(); } if (statement!=null ){ statement.close(); } if (connection!=null ){ connection.close(); } }catch (SQLException e){ throw new RuntimeException(e); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public void testSelect () { Connection connection = null ; String sql = "select * from test1 where id = ?" ; PreparedStatement preparedStatement = null ; ResultSet set = null ; try { connection = JDBCUtilsByDruid.getConnection(); preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1 ,1 ); set = preparedStatement.executeQuery(); while (set.next()) { int id = set.getInt("id" ); String name = set.getString("name" ); int age = set.getInt("age" ); System.out.println(id + "\t" + name + "\t" + age); } }catch (SQLException e){ e.printStackTrace(); }finally { JDBCUtilsByDruid.close(set,preparedStatement,connection); } }
11.DBUtils 1.是Apache组织提供的一个开源JDBC工具类 2.DbUtils类 2.1 QueryRunner类:该类封装了SQL的执行,是线程安全的,可以实现增、删、改、查、批处理 2.2使用QueryRunner类实现查询 2.3ResultSetHandler接口:该接口用于处理java.sql.ResultSet,将数据按要求转换成另一种形式
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 Actor 文件 package JDBC .datasource ;public class Actor { private Integer id; private String name; private Integer age; public Actor (){ } public Actor (Integer id,String name,Integer age){ this .id = id; this .name = name; this .age = age; } public Integer getId ( ) { return id; } public void setId (Integer id ) { this .id = id; } public String getName ( ) { return name; } public void setName (String name ) { this .name = name; } public Integer getAge ( ) { return age; } public void setAge (Integer age ) { this .age = age; } @Override public String toString ( ) { return "\nActor{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}' ; } }
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 public class DBUtils_USE { @Test public void testQueryMany () throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner (); String sql = "select * from test1 where id >= ?" ; List<Actor> list = queryRunner.query(connection,sql,new BeanListHandler <>(Actor.class),1 ); for (Actor actor:list){ System.out.println(actor); } JDBCUtilsByDruid.close(null ,null ,connection); } @Test public void testQuerySingle () throws SQLException { System.out.println("使用druid方式完成" ); Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner (); String sql = "select * from test1 where id = ?" ; Actor query = queryRunner.query(connection, sql, new BeanHandler <>(Actor.class), 1 ); System.out.println(query); JDBCUtilsByDruid.close(null ,null ,connection); } @Test public void Scalar () throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner (); String sql = "select name from test1 where id = ?" ; Object query = queryRunner.query(connection, sql, new ScalarHandler (), 1 ); System.out.println(query); JDBCUtilsByDruid.close(null ,null ,connection); } @Test public void testDML () throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner (); String sql = "update test1 set name = ? where id = ?" ; String sql2 = "insert into test1 values(null,?,?)" ; String sql3 = "delete from test1 where id = ?" ; int affectedRow = queryRunner.update(connection,sql3, 3 ); System.out.println(affectedRow); JDBCUtilsByDruid.close(null ,null ,connection); } }
12.BasicDao 1.apache-dbutils+Druid简化了JDBC开发,但还有不足 1.1SQL语句是固定的,不能通过参数传入,通用性不好 1.2对于select操作,如果有返回值,返回类型不能固定,需要使用泛型 1.3将来的表很多,业务需求复杂,不可能只靠一个java类完成