一. JDBC JDBC 为访问不同的数据库提供了统一的接口, 为使用者屏蔽了细节问题; Java 程序员试用 JDBC, 可以连接任何提供了 JDBC 驱动程序的数据库系统, 从而完成对数据库的操作
MySQL 驱动下载 : https://dev.mysql.com/downloads/connector/j/
JDBC 程序编写步骤:
注册驱动 : 加载 driver 类在项目中创建 libs 文件夹, 将 mysql.jar 拷贝到该目录下, 将 jar 文件 添加到项目中 获取连接 : 得到 Connectionjdbc:mysql : 表示规定好的协议, 通过 jdbc 连接 MySQL localhost : 表示 ip 地址 3306 : 表示监听的端口 执行增删改查 : 发送 sql 给 mysql 执行 释放资源 : 关闭相关连接
1. 数据库连接方式 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 MysqlDemo1 { public static void main (String[] args) { } @Test public void connect4 () throws ClassNotFoundException, SQLException { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/db_02" ; String user = "root" ; String password = "12345678" ; Connection connection = DriverManager.getConnection(url, user, password); System.out.println(connection); } @Test public void connect5 () throws ClassNotFoundException, SQLException, IOException { String filePath = new File ("" ).getAbsolutePath()+"/src/mysql.properties" ; Properties properties = new Properties (); properties.load(new FileInputStream (filePath)); String url = properties.getProperty("url" ); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); String driver = properties.getProperty("driver" ); Class.forName(driver); Connection connection = DriverManager.getConnection(url, user, password); System.out.println(connection); } }
1 2 3 4 5 6 // 配置文件 - mysql.properties driver =com.mysql.cj.jdbc.Driver url =jdbc:mysql://localhost:3306/db_02 user =root password =12345678
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 public class HomeWork1 { public static void main (String[] args) throws IOException, ClassNotFoundException, SQLException { Properties properties = new Properties (); properties.load(new FileInputStream ("./src/mysql.properties" )); String driver = properties.getProperty("driver" ); String url = properties.getProperty("url" ); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); Class.forName(driver); Connection connection = DriverManager.getConnection(url, user, password); Statement statement = connection.createStatement(); String sql_newTable = "create table news(id int primary key auto_increment, `name` varchar(32) not null default '')" ; int i = statement.executeUpdate(sql_newTable); System.out.println(i > 0 ? "成功" : "失败" ); String sql_insert = "insert into news values(null, '张三'),(null, '李四'),(null, '王五'),(null, '赵六')" ; int i1 = statement.executeUpdate(sql_insert); System.out.println(i1 > 0 ? "成功" : "失败" ); String sql_update = "update news set `name` = '张三疯' where id = 3" ; int i2 = statement.executeUpdate(sql_update); System.out.println(i2 > 0 ? "成功" : "失败" ); String sql_delete = "delete from news where id = 4" ; int i3 = statement.executeUpdate(sql_delete); System.out.println(i3 > 0 ? "成功" : "失败" ); connection.close(); statement.close(); } }
3. PreparedStatement Statement 对象 : 用于执行 SQL 语句, 并返回其生成的结果对象;
执行 SQL 语句可以通过以下方式:
Statement : 存在 SQL 注入的问题 PreparedStatement : 预处理, 实际工作中使用 不用拼接 SQL 语句, 减少语法错误 预防 SQL 注入问题 减少编译次数, 效率较高 CallableStatement : 存储过程 Statement 对象执行 SQL 语句时, 存在 SQL 注入的风险; SQL 注入 : 利用某些系统没有对用户输入的数据进行充分的检查, 而在用户输入数据中注入非法的 SQL 语句断货命令, 恶意攻击数据库; PreparedStatement : 用于执行 SQL 语句, 规避 SQL 注入的风险执行 SQL 语句中的 参数 可以用 ? 来表示; 调用 对象的 setXxx(参数 1, 参数 2) 方法来设置这些参数;参数 1 : 表示要设置 SQL 语句中的第几个参数 (第几个问号), 从 1 开始; 参数 2 : 表示要设置的参数值; 调用 executeQuery() 方法, 返回 ResultSet 对象; 调用 executeUpdate() 方法 : 执行 SQL 语句的 增, 删, 改; 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 MysqlDemo2 { public static void main (String[] args) throws IOException, SQLException, ClassNotFoundException { Properties properties = new Properties (); properties.load(new FileInputStream ("./src/mysql.properties" )); String driver = properties.getProperty("driver" ); String url = properties.getProperty("url" ); String user = properties.getProperty("user" ); String password = properties.getProperty("password" ); Class.forName(driver); Connection connection = DriverManager.getConnection(url, user, password); String sql = "select * from news where `name` = ?" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1 ,"张三" ); ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()){ String string = resultSet.getString(1 ); System.out.println(string); } resultSet.close(); preparedStatement.close(); connection.close(); } }
4. JDBCUtils 封装及使用 封装 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 52 53 54 public class JdbcUtils { private static String user; private static String password; private static String url; private static String driver; public static void loadFile (String filePath) { Properties properties = new Properties (); try { properties.load(new FileInputStream (filePath)); 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 { Class.forName(driver); } catch (ClassNotFoundException e) { throw new RuntimeException (e); } 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 public class MysqlTest1 { public static void main (String[] args) { selectTest(); } public static void selectTest () { JdbcUtils.loadFile("./src/mysql.properties" ); Connection connection = JdbcUtils.getConnection(); String sql = "select * from news" ; PreparedStatement preparedStatement = null ; ResultSet resultSet = null ; try { preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); while (resultSet.next()){ String id = resultSet.getString("id" ); String name = resultSet.getString("name" ); System.out.println(id + " " + name); } } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.close(resultSet, preparedStatement, connection); } } public void dmlTest () { JdbcUtils.loadFile("./src/mysql.properties" ); Connection connection = JdbcUtils.getConnection(); String sql = "insert into news values(null, '郭富城')" ; PreparedStatement preparedStatement = null ; try { preparedStatement = connection.prepareStatement(sql); int i = preparedStatement.executeUpdate(); System.out.println(i > 0 ? "成功" : "失败" ); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.close(null , preparedStatement, connection); } } }
5.事务 JDBC 程序中, 当一个 connection 对象创建时, 默认情况下是 自动提交事务;每次执行 SQL 语句时, 成功则自动完成提交, 不能回滚; JDBC 程序中, 可以使用事务, 将多个 SQL 语句作为一个整体执行; 调用 Connection 的 setAutoCommit(false) 可以取消自动提交事务; 在所有 SQL 语句执行成功后, 调用 connection 的 commit() 方法 提交事务 在其中某个操作失败或出现异常时, 调用 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 public class MysqlTest2 { public static void main (String[] args) { transfer(); } public static void createTable () { JdbcUtils.loadFile("./src/mysql.properties" ); Connection connection = JdbcUtils.getConnection(); String sql_createTable = "create table account(id int primary key auto_increment, `name` varchar(32)not null default '', balance double not null default 0)character set utf8" ; PreparedStatement statement = null ; try { statement = connection.prepareStatement(sql_createTable); boolean execute = statement.execute(); System.out.println(execute ? "创建表失败" : "创建表是成功" ); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.close(null , statement, connection); } } public static void insertInto () { JdbcUtils.loadFile("./src/mysql.properties" ); Connection connection = JdbcUtils.getConnection(); String sql_insert = "insert into account values(null, '刘德华', 3000), (null, '王宝强', 500)" ; PreparedStatement statement = null ; try { statement = connection.prepareStatement(sql_insert); boolean execute = statement.execute(); System.out.println(execute); System.out.println(!execute ? "添加成功" : "添加失败" ); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.close(null , statement, connection); } } public static void transfer () { JdbcUtils.loadFile("./src/mysql.properties" ); Connection connection = JdbcUtils.getConnection(); String sql_update1 = "update account set balance = balance - 1000 where `name` = '刘德华'" ; String sql_update2 = "update account set balance = balance + 1000 where `name` = '王宝强'" ; PreparedStatement statement = null ; try { connection.setAutoCommit(false ); statement = connection.prepareStatement(sql_update1); statement.execute(); statement = connection.prepareStatement(sql_update2); statement.execute(); connection.commit(); } catch (SQLException e) { try { System.out.println("转账执行失败, 回滚到事务开始" ); connection.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } e.printStackTrace(); } finally { JdbcUtils.close(null , statement, connection); } } }
6. 批量处理 当需要批量插入或更新记录时, 可以采用 Java 的批量更新机制;将多条 sql 语句 一次性交给数据库, 比单条提交更有效率; JDBC 批量处理语句的方法:addBatch() : 添加需要批量处理的 sql 语句或参数; executeBatch() : 执行批量处理包的语句; clearBatch() : 清空批量处理包的语句; JDBC 连接 mysql 时, 如果要使用批量处理功能, 需要 在 URL 中加参数?rewriteBatchedStatements=true 批量处理 一般和 PreparedStatement 搭配使用, 可以减少编译次数,运行次数; 1 2 3 4 5 6 // 配置更新 - ?rewriteBatchedStatements=true driver =com.mysql.cj.jdbc.Driver url =jdbc:mysql://localhost:3306/db_02?rewriteBatchedStatements=true user =root password =12345678
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 public class BatchDemo1 { @Test public void batch () throws Exception { JdbcUtils.loadFile("./src/mysql.properties" ); Connection connection = JdbcUtils.getConnection(); String sql = "insert into admin2 values(null, ?, ?)" ; PreparedStatement statement = connection.prepareStatement(sql); System.out.println("开始执行" ); long start = System.currentTimeMillis(); for (int i = 0 ; i < 5000 ; i++) { statement.setString(1 ,"jack" + i); statement.setString(2 , "123" ); statement.addBatch(); if ((i + 1 ) == 1000 ){ statement.executeBatch(); statement.clearBatch(); } } long end = System.currentTimeMillis(); System.out.println("执行结束, 共计耗时 : " + (end - start) ); JdbcUtils.close(null ,statement,connection); } }
二. 连接池 预先在缓冲池中放入一定数量的连接, 当需要连接数据库时, 只需取出一个, 使用完毕之后再放回去 数据库连接池 负责分配、管理和释放数据库连接;连接池 允许应用程序 重复使用 一个现有的数据库连接, 而不是重新建立一个; 当应用程序向连接池请求的连接数超过最大连接数时, 将加入到等待队列中; JDBC 的数据库连接池使用 javax.sql.DataSource 来表示;DataSource 只是一个接口, 该接口通常由第三方提供实现; 连接池的种类:
C3P0 连接池 : 速度较慢, 稳定性较好; DBCP 连接池 : 速度 相对 C3P0 较快, 稳定性较差; Proxool 连接池 : 有监控连接池状态的功能, 稳定性较差; BoneCP 连接池 : 速度快 Druid (德鲁伊) 连接池 : 阿里提供的连接池, 集 DBCP、C3P0、Proxool 优点于一身1. 环境配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 配置文件 - druid.properties driverClassName =com.mysql.cj.jdbc.Driver url =jdbc:mysql://localhost:3306/db_02?rewriteBatchedStatements=true username =root password =12345678 initialSize =10 minIdle =5 maxActive =20 maxWait =5000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class DruidDemo1 { @Test public void druidTest1 () throws Exception { Properties properties = new Properties (); properties.load(new FileInputStream ("src/druid.properties" )); DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); Connection connection = dataSource.getConnection(); System.out.println("连接成功" ); connection.close(); } }
2. JDBCUtilsByDruid 封装及使用 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 JDBCUtilsByDruid { private static DataSource ds; static { Properties properties = new Properties (); try { properties.load(new FileInputStream ("src\\druid.properties" )); ds = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection () throws SQLException { return ds.getConnection(); } 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 public class DruidDemo2 { @Test public void druidTest1 () { Connection connection = null ; PreparedStatement statement = null ; ResultSet resultSet = null ; String sql = "select * from actor" ; try { connection = JDBCUtilsByDruid.getConnection(); statement = connection.prepareStatement(sql); resultSet = statement.executeQuery(); while (resultSet.next()){ int id = resultSet.getInt("id" ); String name = resultSet.getString("name" ); String sex = resultSet.getString("sex" ); String borndate = resultSet.getString("borndate" ); String phone = resultSet.getString("phone" ); System.out.println(id + name + sex + borndate + phone); } } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtilsByDruid.close(resultSet, statement, connection); } } }
3. DBUtils 工具类 DBUtils 类:
QueryRunner 类 : 该类封装了 sql 的执行, 是线程安全的;ResultSetHandler 接口 : 该接口用于处理 java.sql.ResultSet, 将数据按要求转换为另一种形式; 命令 说明 ArrayHandler 把 结果集 中的第一行数据转成 对象数组; ArrayListHandler 把 结果集 中的每行数据都转成一个数组, 再存放到 list 中 BeanHandler 将 结果集 中的第一行数据封装到一个对应的 JavaBean 实例中 BeanListHandler 将 结果集 中的每一行数据都封装到一个对应的 JavaBean 实例中,存放到 list 里 ColumnListHandler 将 结果集 中的某一列的数据存放的 List 中 KeyedHandler(name) 将 结果集 中的每行数据都封装到 map 里, MapHandler 将 结果集 中的第一行数据封装到一个 Map 里, key 为列名, values 对应值 MapListHandler 将 结果集 中的每行数据都封装到一个 Map 里, 然后放到 L 冲突
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 public class Actor { private Integer id; private String name; private String sex; private Date borndate; private String phone; public Actor () { } public Actor (Integer id, String name, String sex, Date borndate, String phone) { this .id = id; this .name = name; this .sex = sex; this .borndate = borndate; this .phone = phone; } 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 String getSex () { return sex; } public void setSex (String sex) { this .sex = sex; } public Date getBorndate () { return borndate; } public void setBorndate (Date borndate) { this .borndate = borndate; } public String getPhone () { return phone; } public void setPhone (String phone) { this .phone = phone; } @Override public String toString () { return "\nActor{" + "id=" + id + ", name='" + name + '\'' + ", sex='" + sex + '\'' + ", borndate=" + borndate + ", phone='" + phone + '\'' + '}' ; } }
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 public class DBUtilsDemo1 { @Test public void testQueryMany () throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner (); String sql = "select * from actor where id >= ?" ; List<Actor> actorList = queryRunner.query(connection, sql, new BeanListHandler <>(Actor.class), 1 ); for (Actor actor : actorList) { System.out.println(actor); } JDBCUtilsByDruid.close(null , null , connection); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Test public void testQueryDml () throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner (); String sql_insert = "insert into actor values(null, ?, ?, ?, ?)" ; String sql_update = "update actor set name = ? where id = ?" ; String sql_delete = "delete from actor where id = ?" ; int insert = queryRunner.update(connection, sql_insert, "虚竹" , "男" , "1999-11-23" , "13243435656" ); int update = queryRunner.update(connection, sql_update, "完颜洪烈" , 2 ); int delete = queryRunner.update(connection, sql_delete, 6 ); System.out.println(insert > 0 ? "修改成功" : "修改失败" ); System.out.println(update > 0 ? "修改成功" : "修改失败" ); System.out.println(delete > 0 ? "修改成功" : "修改失败" ); JDBCUtilsByDruid.close(null , null , connection); }
4. DAO 和 增删改查通用方法 - BasicDao DAO : 数据访问对象 BasicDao : 专门和数据库交互, 即完成对数据库表的 crud 操作; 在 BaicsDao 的基础上, 实现一张表 对应 一个 Dao, 更好的完成功能;如 Customer 表 —-> Customer.java 类(javabean) —-> CustomerDao.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 public class JDBCUtilsByDruid { private static DataSource ds; static { Properties properties = new Properties (); try { properties.load(new FileInputStream ("./src/druid.properties" )); ds = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection () throws SQLException { return ds.getConnection(); } public static void close (Connection connection) { if (connection != null ){ try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
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 public class Actor { private Integer id; private String name; private String sex; private Date borndate; private String phone; public Actor () { } public Actor (Integer id, String name, String sex, Date borndate, String phone) { this .id = id; this .name = name; this .sex = sex; this .borndate = borndate; this .phone = phone; } 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 String getSex () { return sex; } public void setSex (String sex) { this .sex = sex; } public Date getBorndate () { return borndate; } public void setBorndate (Date borndate) { this .borndate = borndate; } public String getPhone () { return phone; } public void setPhone (String phone) { this .phone = phone; } @Override public String toString () { return "Actor{" + "id=" + id + ", name='" + name + '\'' + ", sex='" + sex + '\'' + ", borndate=" + borndate + ", phone='" + phone + '\'' + '}' ; } }
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 public class BasicDao <T> { private final QueryRunner qr = new QueryRunner (); public int dml (String sql, Object... parameters) { Connection connection = null ; try { connection = JDBCUtilsByDruid.getConnection(); return qr.update(connection, sql, parameters); } catch (SQLException e) { throw new RuntimeException (e); } finally { JDBCUtilsByDruid.close(connection); } } public List<T> queryMulti (String sql, Class<T> clazz, Object... parameters) { Connection connection = null ; try { connection = JDBCUtilsByDruid.getConnection(); return qr.query(connection, sql, new BeanListHandler <T>(clazz), parameters); } catch (SQLException e) { throw new RuntimeException (e); } finally { JDBCUtilsByDruid.close(connection); } } public T querySingle (String sql, Class<T> clazz, Object... parameters) { Connection connection = null ; try { connection = JDBCUtilsByDruid.getConnection(); return qr.query(connection, sql, new BeanHandler <>(clazz), parameters); } catch (SQLException e) { throw new RuntimeException (e); } finally { JDBCUtilsByDruid.close(connection); } } public Object queryScalar (String sql, Object... parameters) { Connection connection = null ; try { connection = JDBCUtilsByDruid.getConnection(); return qr.query(connection, sql, new ScalarHandler <>(), parameters); } catch (SQLException e) { throw new RuntimeException (e); } finally { JDBCUtilsByDruid.close(connection); } } }
1 2 3 4 5 public class ActorDao extends BasicDao <Actor> {}
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 public class TestDaoDemo1 { @Test public void testActorDao1 () { ActorDao actorDao = new ActorDao (); List<Actor> list = actorDao.queryMulti("select * from actor where id >= ?" , Actor.class, 2 ); System.out.println("=====多行查询=====" ); for (Actor actor : list) { System.out.println(actor); } Actor actor = actorDao.querySingle("select * from actor where id = ?" , Actor.class, 2 ); System.out.println("单行查询 : " + actor); Object o = actorDao.queryScalar("select name from actor where id = ?" , 2 ); System.out.println("单个字段值查询 : " + o); int dml = actorDao.dml("insert into actor values(null, ?,?,?,?)" , "马云" , "男" , "1956-1-12" , "88889999" ); System.out.println(dml > 0 ? "添加成功" : "添加失败" ); int dml1 = actorDao.dml("update actor set name = ? where name = ?" , "马化腾" , "马云" ); System.out.println(dml1 > 0 ? "修改成功" : "修改失败" ); int dml2 = actorDao.dml("delete from actor where name = ?" , "马云" ); System.out.println(dml > 0 ? "删除成功" : "删除失败" ); } }