1. PreparedStatement 研究
1.1 PreparedStatement 概念1.2 为什么要多用 PreparedStatement ?而少用 Statement1.3 如何使用 PreparedStatement1.4 使用 PreparedStatement 示例 2. 如何获得元数据 metaData
2.1 元数据就是字段那些2.2 元数据访问示例 3. 事务处理
3.1 什么是 Java 事务3.2 数据库事务编程示例
1. PreparedStatement 研究 1.1 PreparedStatement 概念什么是带参数的 SQL 语句?
String sql = "select * from students where sno = ?";
解释参数 “ ?”(占位符)
- 这里并不是查询学号为 ? 号的学生。 - 而是代表一个参数,在执行该语句之前,必须给参数赋值。1.2 为什么要多用 PreparedStatement ?而少用 Statement
- 代码的可读性和可维护性。
在这里插入代码片
- PreparedStatement 提高性能。
- 有一种常见情况:写好的 JDBC 代码,编译器会对代码预编译,而预编译语句可能重复调用。 - 因而,使用 PreparedStatement 可以提高性能。 - 因为,只需要将参数直接传入编译过的语句执行代码。
- 防止 SQL 注入攻击。
SQL 注入攻击: - 用户合法的输入:但提交的是特殊的非法代码。 - 输入注入了 SQL 中,改变了 SQL 原有的逻辑。 例如: - 在登陆界面,用户名输入: - 'or'1'='1'or'1'='1 - SQL 语句就变成了: - select * from students where sname = ''or'1'='1'or'1'='1'1.3 如何使用 PreparedStatement
- 连接数据库
String driver = "com.mysql.jdbc.Driver";
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String passwd = "123456";
Connection con = null;
try {
con = DriverManager.getConnection(url, user, passwd);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
- 创建命令对象——PreparedStatement
String sql = "select * from students where sno = ?";
PreparedStatement cmd = null;
try {
cmd = con.prepareStatement(sql);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
- 输入参数
try {
cmd.setString(1, "张三");
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
- 执行
try {
System.out.print("执行是否成功:" + cmd.execute());
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
- 关闭接口
try {
if (cmd != null) {
cmd.close();
cmd = null;
}
if (con != null) {
con.close();
con = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
执行是否成功:true1.4 使用 PreparedStatement 示例
public static void addStudent() throws UnsupportedEncodingException {
Connection con = null;
PreparedStatement cmd = null;
ResultSet rs = null;
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String passwd = "123456";
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(url, user, passwd);
String sql1 = "insert into students(sno, sname, ssex) values(?, ?, ?);";
cmd = con.prepareStatement(sql1);
cmd.setString(1, "1005");
cmd.setString(2, "李四");
cmd.setString(3, "男");
cmd.executeUpdate();
String sql2 = "select * from students";
rs = cmd.executeQuery(sql2);
while (rs.next()) {
String sno = rs.getString("sno");
String sname = rs.getString(2);
String ssex = rs.getString("ssex");
System.out.printf("%-8s%-6s%-3sn", sno, sname, ssex);
}
} catch (ClassNotFoundException e) {
// TODO JDBC 驱动
e.printStackTrace();
} catch (SQLException e) {
// TODO 连接数据库
e.printStackTrace();
} finally {
try {
if (rs != null) {
rs.close();
rs = null;
}
if (cmd != null) {
cmd.close();
cmd = null;
}
if (con != null) {
con.close();
con = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
控制台输出:
1001 李晨 男 1002 王丽 女 1003 陈军 男 1004 张三 男 1005 李四 男
MySQL:
2. 如何获得元数据 metaData 2.1 元数据就是字段那些元数据最本质的定义为:data about data(关于数据的数据)。JDBC 通过元数据(metaData)来获得表的相关信息,如:字段,字段属性等。JDBC 提供了两个元数据对象类型:DatabasemetaData 和 ResultSetmetadata 2.2 元数据访问示例
public static void practicemetaData() throws Exception {
Connection con = null;
Statement cmd = null;
ResultSet rs = null;
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String passwd = "123456";
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(url, user, passwd);
DatabasemetaData meta = con.getmetaData(); // 获取数据库的元数据对象
System.out.println("数据库名为:" + meta.getDatabaseProductName());
System.out.println("数据库版本号为:" + meta.getDatabaseProductVersion());
System.out.println("数据库Url为:" + meta.getURL());
System.out.println("数据库登录名为:" + meta.getUserName());
System.out.println("数据库驱动名为:" + meta.getDriverName());
System.out.println("Students 表为:");
cmd = con.createStatement();
String sql2 = "select * from students";
rs = cmd.executeQuery(sql2);
// 1
ResultSetmetaData rsmd = rs.getmetaData();
System.out.println("第一列的类型为:" + rsmd.getColumnType(1));
System.out.println("第一列的列类型名为:" + rsmd.getColumnTypeName(1));
System.out.println("第一列所在的表为:" + rsmd.getTableName(1));
// 2
while (rs.next()) {
String sno = rs.getString("sno");
String sname = rs.getString(2);
String ssex = rs.getString("ssex");
System.out.printf("%-8s%-6s%-3sn", sno, sname, ssex);
}
} catch (ClassNotFoundException e) {
// TODO JDBC 驱动
e.printStackTrace();
} catch (SQLException e) {
// TODO 连接数据库
e.printStackTrace();
} finally {
try {
if (rs != null) {
rs.close();
rs = null;
}
if (cmd != null) {
cmd.close();
cmd = null;
}
if (con != null) {
con.close();
con = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
数据库名为:MySQL 数据库版本号为:8.0.23 数据库Url为:jdbc:mysql://localhost:3306/mydb 数据库登录名为:root@localhost 数据库驱动名为:MySQL Connector/J Students 表为: 第一列的类型为:4 第一列的列类型名为:INT 第一列所在的表为:students 1001 李晨 男 1002 王丽 女 1003 陈军 男 1004 张三 男 1005 李四 男3. 事务处理 3.1 什么是 Java 事务
要么全部执行成功,要么撤销全部不执行。数据库 JDBC 操作的事务习惯就称为 Java 事务。 3.2 数据库事务编程示例
public static void practiceTransaction() {
Connection con = null;
Statement cmd = null;
ResultSet rs = null;
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String passwd = "123456";
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(url, user, passwd);
String sql1 = "insert into students(sno, sname, ssex) values(1006, "王老五", "男");";
cmd = con.createStatement();
try {
con.setAutoCommit(false); // 禁止自动提交事务,我们自己定义事务
cmd.executeUpdate(sql1);
cmd.executeUpdate(sql1);
con.commit(); // 提交事务
} catch (Exception e) {
// TODO 事务
try {
con.rollback();
} catch (SQLException ee) {
ee.printStackTrace();
}
}
String sql2 = "select * from students";
rs = cmd.executeQuery(sql2);
while (rs.next()) {
String sno = rs.getString("sno");
String sname = rs.getString(2);
String ssex = rs.getString("ssex");
System.out.printf("%-8s%-6s%-3sn", sno, sname, ssex);
}
} catch (ClassNotFoundException e) {
// TODO JDBC 驱动
e.printStackTrace();
} catch (SQLException e) {
// TODO 连接数据库
e.printStackTrace();
} finally {
try {
if (rs != null) {
rs.close();
rs = null;
}
if (cmd != null) {
cmd.close();
cmd = null;
}
if (con != null) {
con.close();
con = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
可以看到,并没有插入数据
1001 李晨 男 1002 王丽 女 1003 陈军 男 1004 张三 男 1005 李四 男



