}
----------------------------------------------------------------------------------------------------------------------------------------------------
JdbcTools工具类:
package com.zhou.jdbc;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
/**
* 版本1:后面这些方法还可以升级,比方说我们不能每次操作都获取一个数据库连接,比方说后面会学数据库连接池;
*
* 操作JDBC的工具类:其中封装了一些工具方法:
*
* 1.获取连接的方法;
*
* @author Administrator
*
*/
public class JdbcTools {
/**
* 1.获取连接的方法:这个方法在前面已经写过了,只是这个是工具方法,需要加上static: ---通过读取配置文件从数据库服务器获取一个连接;
*
* 用DriverManager来把之前那个通用的方法写一遍:
*
* @throws Exception
*/
public static Connection getConnection() throws Exception {
// 1.准备连接数据库的四个字符串:
// 1).创建Properties对象:
Properties properties = new Properties();
// 2).获取jdbc.properties对应的输入流:
InputStream in = JdbcTools.class.getClassLoader().getResourceAsStream("jdbc.properties");
// 3).加载2) 对应的输入流:
properties.load(in);
// 4).具体决定user、password、jdbcUrl、driverClass四个字符串:
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String jdbcUrl = properties.getProperty("jdbcUrl");
String driverClass = properties.getProperty("dirver");
// 2.加载数据库驱动程序(实际上这一步应该叫:注册驱动,对应的Driver实现类中有注册驱动的静态代码块):
Class.forName(driverClass);
// 3.获取数据库的连接:
// Connection connection = DriverManager.getConnection(jdbcUrl, user,
// password);
// return connection;
return DriverManager.getConnection(jdbcUrl, user, password);
}
/**
* 2.关闭数据库资源的方法: 它关闭一个Statement,再关闭一个Connection:
*/
public static void release(Statement statement, Connection connection) {
if (statement != null) {
try {
statement.close();
} catch (Exception e1) {
e1.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
/**
* 3.关闭数据库资源的方法: 它关闭三个:ResultSet、Statement、Connection:
*/
public static void release_2(ResultSet resultSet ,Statement statement, Connection connection) {
if (resultSet != null) {
try {
resultSet.close();
} catch (Exception e1) {
e1.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
}
/**
* 4.执行SQL的方法:
* SQL:INSERT、UPDATE、DELETE,而不包含SELECT;
*/
public static void update(String sql){
Connection connection = null;
Statement statement = null;
try {
connection = getConnection();
statement = connection.createStatement();
statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭连接:这里不再写那个嵌套的try……catch……finally了
release(statement, connection);
}
}
/**
*
* 执行SQL语句,使用PreparedStatement:
*
* 写一个使用PreparedStatement的update方法:
* 这个方法我除了传一个sql以外,我还需要传入什么?我还需要传入
* 这个SQL语句中一个一个占位符的值吧,传多少个呢,各个sql语句
* 都可能传的值的个数不一样吧;
* 所以说第二个参数是个什么为好啊?是一个可变参数为好;
* 刚好和上面的那个public static void update(String sql)可以构成方法的重载;
*
* @param sql
* @param args:填写sql占位符的可变参数;
*/
public static void update(String sql,Object ... args){
/**
* 这个方法体跟上面那个update方法体过程差不多,
*/
//声明Connection和PreparedStatement:
Connection connection = null;
PreparedStatement preparedStatement = null;
//写一个大的try……catch……finally:
try {
//获得连接:
connection = JdbcTools.getConnection();
//创建PreparedStatement:
preparedStatement = connection.prepareStatement(sql);
//这一步比较关键:我是不是要从里面传参数啊,Object ... args这个我也不知道吧,这是不是一个数组啊,我使用一个for循环:
for(int i = 0;i < args.length; i++){
preparedStatement.setObject(i+1, args[i]);
//所有的索引是不是从1开始啊,而数组的索引是不是从0开始啊;
}
//执行SQL语句:
preparedStatement.executeUpdate();
//注意,SQL语句已经在创建PreparedStatement的时候已经传进去了,这里不要再传SQL语句了;
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcTools.release_2(null, preparedStatement, connection);
}
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------
用PreparedStatement来改写用Statement的方式拼写SQL语句麻烦、容易出错的缺点:
/**
* 写完public void addNewStudent_2(Student student)之后呢,我们可以来写这样一个测试的方法
*/
@Test
public void testAddNewStudent() {
// 首先获取一个Student对象,从控制台的输入中获取:
Student student = getStudentFromConsole();
// 然后调用addNewStudent(Student student)方法添加一个学生信息:
//addNewStudent(student);
addNewStudent_2(student);
}
/**
* 创建用从控制台获取Student对象的方法:getStudentFromConsole()
*
* @return
*/
private Student getStudentFromConsole() {
// 创建一个Scanner类的对象;
Scanner scanner = new Scanner(System.in);
// 然后呢?创建一个Student类的对象:
Student student = new Student();
// 然后怎么整啊?一个一个输入啊:
System.out.print("flowId:");
student.setFlowId(scanner.nextInt());
System.out.print("type:");
student.setType(scanner.nextInt());
System.out.print("idCard:");
student.setIdCard(scanner.next());
System.out.print("examCard:");
student.setExamCard(scanner.next());
System.out.print("studentName:");
student.setStudentName(scanner.next());
System.out.print("Location:");
student.setLocation(scanner.next());
System.out.print("Grade:");
student.setGrade(scanner.nextInt());
// 把对象进行返回;
return student;
}
/**
* 第一个我们叫什么呢?叫addNewStudent 这样就写成了一个方法,我要添加一个学生进来,我们当然可以硬写,怎么写呢?
* 就是真的从控制台逐步读入那些信息,然后把这些信息插入到数据库里面;
*/
public void addNewStudent(Student student) {
/**
* 这个方法基本在写流程的时候已经写过了:
*/
// 1.准备一条SQL语句:
// String sql = “INSERT INTO examstudent”+" VALUES(1,4,’’,’’,’’,’’,90)”;
String sql = "INSERT INTO examstudent" + " VALUES("
+ student.getFlowId() + "," + student.getType() + ",'"
+ student.getIdCard() + "','" + student.getExamCard() + "','"
+ student.getStudentName() + "','" + student.getLocation()
+ "'," + student.getGrade() + ")";
// 我打印一下这个SQL语句:
System.out.println(sql);
// 2.调用JdbcTools工具类的update(sql)方法执行插入操作;
JdbcTools.update(sql);
}
/**
* 用PreparedStatement来改写:public void addNewStudent(Student student)这个方法:
* 改写这个方法的话是因为我在JdbcTools工具类里面有update()方法吧,这个update()方法用的是谁啊?用的是不是
* Statement啊,这个时候我需要把这个JdbcTools工具类里面的这个update()方法进行升级,升级成使用
* PreparedStatement,因为你再用这个Statement写的update()方法肯定不行了啊,
*
*/
public void addNewStudent_2(Student student){
//我需要来预写一个SQL语句:
String sql = "INSERT INTO examstudent (flowid,type,idcard,"
+ "examcard,studentname,location,grade)" +
"VALUES(?,?,?,?,?,?,?)";
//把列名写上后面就会清楚了写什么:
//然后我要去调JdbcTools的update方法,这个时候我只传一个SQL不够吧?我还需要传入这一个一个占位符的值;
JdbcTools.update(sql, student.getFlowId(),student.getType(),
student.getIdCard(),student.getExamCard(),
student.getStudentName(),student.getLocation(),
student.getGrade());
/*
* 这个时候我不用拼这个字符串了,但是我传参是必须的,写的时候的确是比前一个方便了;
* 拼串确实比较辛苦,但是我写这样一个带问号占位符的sql语句的话缺容易得多,然后把
* 这个值一个一个的传了;
*/
}