这是一种不太合规的PreparedStatement调用使用方式 , 没有让Dao单独执行它单纯的任务.
AccountDao.java
package heartl_jdbc;
/**
* 银行操作系统构建snapshot
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;
public class AccountDao {
static Scanner in = new Scanner(System.in);
String sql;
////////////////////////////////////////////////////
///// * 获取Connection连接对象
///// * public static Connection jdbcStart()
////////////////////////////////////////////////////
public static Connection jdbcStart() throws ClassNotFoundException, SQLException {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE", "hr", "system");
return conn;
}
/////////////////////////////////////////////////////////////////////////////////////
///// * 插入新用户
///// * insertAccount()
/////////////////////////////////////////////////////////////////////////////////////
protected void insertAccount() throws ClassNotFoundException, SQLException {
String sql = "insert into Account values(seq_account.nextval,?,?,?)";
PreparedStatement ps = jdbcStart().prepareStatement(sql);
// 将新的ps传入到insertPPS
PreparedStatement psnew = TestAccountDao.insertPS(ps);
long start = System.currentTimeMillis();
boolean insertOk = psnew.execute();
if (insertOk) {
System.out.println("插入数据成功!");
long end = System.currentTimeMillis();
long useTime = end - start;
System.out.println("与数据库交互完成!,耗时:" + useTime + "毫秒.");
psnew.close();
ps.close();
jdbcStart().close();
}
}
/////////////////////////////////////////////////////////////////////////////////////
///// * 更改用户的:用户名/密码/余额
///// * updateAccount(String 选择number)
/////////////////////////////////////////////////////////////////////////////////////
protected static void updateAccount(String selectStr) throws ClassNotFoundException, SQLException {
String nameSql = "update Account set user_name = ? where user_name= ?";
String passSql = "update Account set user_password = ? where user_name= ?";
String balanceSql = "update Account set user_balance = user_balance +? where user_name = ?";
if (selectStr.equals("1")) {
PreparedStatement namePs = AccountDao.jdbcStart().prepareStatement(nameSql);
PreparedStatement namePsNew = TestAccountDao.updatePS(namePs, "1");
long start = System.currentTimeMillis();
int nChange = namePsNew.executeUpdate();
if (nChange == 1) {
System.out.println("姓名更改成功!");
long end = System.currentTimeMillis();
long useTime = end - start;
System.out.println("与数据库交互完成!,耗时:" + useTime + "毫秒.");
namePsNew.close();
namePs.close();
jdbcStart().close();
}
} else if (selectStr.equals("2")) {
PreparedStatement passPs = AccountDao.jdbcStart().prepareStatement(passSql);
PreparedStatement passPsNew = TestAccountDao.updatePS(passPs, "2");
long start = System.currentTimeMillis();
int pChange = passPsNew.executeUpdate();
if (pChange == 1) {
System.out.println("密码更改成功!");
long end = System.currentTimeMillis();
long useTime = end - start;
System.out.println("与数据库交互完成!,耗时:" + useTime + "毫秒.");
passPsNew.close();
passPs.close();
jdbcStart().close();
}
} else if (selectStr.equals("3")) {
PreparedStatement balancePs = AccountDao.jdbcStart().prepareStatement(balanceSql);
PreparedStatement balancePsNew = TestAccountDao.updatePS(balancePs, "3");
long start = System.currentTimeMillis();
int bChange = balancePsNew.executeUpdate();
if (bChange == 1) {
System.out.println("余额更改成功!");
long end = System.currentTimeMillis();
long useTime = end - start;
System.out.println("与数据库交互完成!,耗时:" + useTime + "毫秒.");
balancePsNew.close();
balancePs.close();
jdbcStart().close();
}
}
}
//////////////////////////////////////////////////////////////////////////////////
///// * 按照用户名删除整个用户元组数据
///// * deleteAccount()
//////////////////////////////////////////////////////////////////////////////////
protected void deleteAccount() throws ClassNotFoundException, SQLException {
String sql = "delete from Account where user_name = ?";
PreparedStatement ps = jdbcStart().prepareStatement(sql);
PreparedStatement psNew = TestAccountDao.deletePS(ps);
long start = System.currentTimeMillis();
boolean isDelete = psNew.execute();
if (isDelete) {
System.out.println("删除账户成功~!");
long end = System.currentTimeMillis();
long useTime = end - start;
System.out.println("与数据库交互完成!,耗时:" + useTime + "毫秒.");
}
}
}
TestAccountDao.java
package heartl_jdbc;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
/**
* Dao的测试类
*
* @author SeeClanUkyo
*
*/
public class TestAccountDao {
private static Scanner in = new Scanner(System.in);
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 创建Dao层对象
AccountDao ad = new AccountDao();
// TestAccountDao test = new TestAccountDao();
getHello(ad);
}
/////////////////////////////////////////////////////////
///// * STEP 1 . 欢迎界面
///// * public static void getHello(AccountDao ad)
/////////////////////////////////////////////////////////
public static void getHello(AccountDao ad) throws ClassNotFoundException, SQLException {
System.out.println("欢迎来到魔偶银行系统,管理员,请选择您要执行的操作\n1.设置账户初始化\n2.更改账户信息\n3.删除账户\n4.下载数据库文件");
String selectNum = in.next();
boolean isRightInput = selectNum.equals("1") || selectNum.equals("2") || selectNum.equals("3")
|| selectNum.equals("4");
if (isRightInput) {
if (selectNum.equals("1")) {
ad.insertAccount();
} else if (selectNum.equals("2")) {
select_2();
} else if (selectNum.equals("3")) {
ad.deleteAccount();
} else if (selectNum.equals("4")) {
MariaDownload.downLoadTableData();
}
} else {
System.out.println("对不起,您输入有误,请重新输入:");
getHello(ad);
}
}
//////////////////////////////////////////////////////////////////////////////////////
///// * 插入用户的,用户输入界面
///// * protected static PreparedStatement insertPS(PreparedStatement ps)
///// * 半成品的插入SQL语句传递过来,并使用setObject(index,data)方式设置填充SQL(ps)内容并返回.
//////////////////////////////////////////////////////////////////////////////////////
protected static PreparedStatement insertPS(PreparedStatement ps) throws SQLException, ClassNotFoundException {
showUser();
System.out.println("请输入不同于以上的用户名(用户名大于3位)");
String username = in.next();
System.out.println("请输入密码(13位<=密码=>6位)");
long password = in.nextInt();
System.out.println("请输入存款金额(金额不能为null,不能为负数,最小为0)");
String balance = in.next();
ps.setObject(1, username);
ps.setObject(2, password);
ps.setObject(3, balance);
return ps;
}
//////////////////////////////////////////////////////////////
///// *选择为2时,再进行区分,询问用户具体要更改哪个字段
///// *根据不同的选择,执行不同的字段的操作
//////////////////////////////////////////////////////////////
protected static void select_2() throws ClassNotFoundException, SQLException {
System.out.println("请问您要更改哪个字段?");
System.out.println("1.user_name\n2.user_password\n3.user_balance");
String selectUp = in.next();
boolean isRightNum = selectUp.equals("1") || selectUp.equals("2") || selectUp.equals("3");
if (isRightNum) {
if (selectUp.equals("1")) {
AccountDao.updateAccount("1");
} else if (selectUp.equals("2")) {
AccountDao.updateAccount("2");
} else if (selectUp.equals("3")) {
AccountDao.updateAccount("3");
}
} else {
System.out.println("选择错误,没有该字段,请重新选择:");
select_2();
}
}
/////////////////////////////////////////////////////////////////
///// * 更改用户信息,对应上面的select2_()
///// * AccountDao传递过来半成品的Update类型SQL语句.
///// * 之后该方法用于接受具体输入,并将设置完整的SQL语句返回给AccountDao执行操作
/////////////////////////////////////////////////////////////////
protected static PreparedStatement updatePS(PreparedStatement ps, String selectUp)
throws ClassNotFoundException, SQLException {
if (selectUp.equals("1")) {
showUser();
System.out.println("请输入您要更改的用户姓名:(现有)");// 单独把遍历用户名的方法提取
String oldname = in.next();
ps.setObject(2, oldname);
System.out.println("请输入要更替为的姓名:(新名称)");
String newname = in.next();
ps.setObject(1, newname);
return ps;
} else if (selectUp.equals("2")) {
showUser();
System.out.println("请输入您要更替密码的用户名:");
String nameAboutPassword = in.next();
ps.setObject(2, nameAboutPassword);
System.out.println("请输入新密码:(13<=密码=>6)number类型");
long passWNew = in.nextInt();// 超过13 要更改为String 或使用long
ps.setObject(1, passWNew);
return ps;
} else if (selectUp.equals("3")) {
showUser();
System.out.println("请输入您要更替余额的账户名称:");
String nameAboutBalance = in.next();
ps.setObject(2, nameAboutBalance);
System.out.println("请输入要+的钱数或-的钱数,加上+/-号");
long changBalance = in.nextLong();
ps.setObject(1, changBalance);
return ps;
} else {
return ps;
}
}
////////////////////////////////////////////////////////////////
///// * 接受半成品删除SQL语句,该方法进行完整设置并返回到AccountDao进行执行
////////////////////////////////////////////////////////////////
public static PreparedStatement deletePS(PreparedStatement ps) throws ClassNotFoundException, SQLException {
showUser();
System.out.println("请输入要删除的用户名:");
String deleteName = in.next();
ps.setObject(1, deleteName);
return ps;
}
///////////////////////////////////////////////////////////////////////////////
///// * 遍历现有用户 from Account */////
///// * public static void showUser() *////////////////////////////////////////
public static void showUser() throws ClassNotFoundException, SQLException {
System.out.println("现有用户为:");
String sqlname = "select user_name from Account";
PreparedStatement nameps = AccountDao.jdbcStart().prepareStatement(sqlname);
ResultSet rsnow = nameps.executeQuery();
while (rsnow.next()) {
System.out.println(rsnow.getString("user_name"));
}
}
}
PreparedStatement预防sql注入危险,传值时使用setObject(位置,数据)进行传值预处理. (或者setString(),,setInt()等.)
这样对PreparedStatement的实例ps进行了来回的传送,看起来很繁琐.也可以这样,似乎好了些:
其中一边传入数据.
ArrayList<Object> userDatas_Reg = new ArrayList<>();
String register_SQL = null;
userDatas_Reg.add(getUserName());
userDatas_Reg.add(getPassWord());
userDatas_Reg.add(getSex());
userDatas_Reg.add(getNickName());
userDatas_Reg.add(getAge());
userDatas_Reg.add(getIdentity());
register_SQL = "insert into lib_users values(seq_lib_users.nextval,?,?,?,?,?,?,sysdate,seq_card_id.nextval)";
MariaSQLManager.sql_Handler(register_SQL,userDatas_Reg);
另一边的接收半成品sql和数据集合,其将这两个传入值传入getFullPreparedStatementPS进行了设置
//设置sql_Handler的重载形式 多个值的设置
protected static void sql_Handler(String half_SQL, ArrayList<Object> userDatas) {
// Connection conn = MariaTools.jdbcStart();
// PreparedStatement ps = conn.prepareStatement(half_SQL);
int sql_type = sql_Judger(half_SQL);
PreparedStatement ps = MariaTools.getFullPreparedStatementPS(half_SQL, userDatas);
ResultSet rs = null;
LoginStuff log = new LoginStuff();
log.set_NamePasswordOk(false);
try {
if (sql_type == 1) {
rs = ps.executeQuery();
if (rs.next()) {
log.set_NamePasswordOk(true);
}
}
if (sql_type == 2) {
for (int i = 0; i < userDatas.size(); i++) {
ps.setObject(i + 1, userDatas.get(i));
}
ps.executeUpdate();
}
// 如果有结果集返回,说明用户名和密码正确了
} catch (SQLException e) {
e.printStackTrace();
}
}
但因为都是setObject,而没有针对某一种数据进行不同的set,显得不是很合规
///// * 对半成品的sql进行填全工具 */////
public static PreparedStatement getFullPreparedStatementPS(String sql, ArrayList<Object> userDatas) {
// 传入一个setObject的需求的总数量
PreparedStatement ps = null;
try {
ps = MariaTools.jdbcStart().prepareStatement(sql);
for (int i = 0; i < userDatas.size(); i++) {
ps.setObject(i + 1, userDatas.get(i));
}
} catch (SQLException e) {
e.printStackTrace();
}
return ps;
}
看来需要对整个的JDBC的规范写法有所了解才可以!
将编程看作是一门艺术,而不单单是个技术。
敲打的英文字符是我的黑白琴键,
思维图纸画出的是我编写的五线谱。
当美妙的华章响起,现实通往二进制的大门即将被打开。