JavaEEDay35數據庫
@toc
preparedstatement 接口使用
提供一個 POJO 文件:Person.java
然後在 PersonDao.java 中實現增刪改查方法
與 Day34 代碼不同點: 通過在方法中傳入 Person 對象,實現 參數中方式的是 get 方法得到;
最後來使用 PersonView.java 實現頁面;
- 首先對應數據庫建立一個實體類:Person.java
- 實體類:一般情況會與數據庫中表內的數據類型一致
- 建議:成員變量的名字要和數據庫裏面的字段名一致
- 建議:使用基本數據類型的包裝類
package jdbc.preparedStatement;
/**
* @author GJXAIOU
* @create 2019-08-01-20:09
*/
public class Person {
private Integer id;
private String name;
private String gender;
private Integer score;
private String home;
private String hobby;
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 getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
public String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
return "Person{" +
"id=" + this.getId()+
", name='" + this.getName() + '\'' +
", gender='" + this.getGender() + '\'' +
", score=" + this.getScore() +
", home='" + this.getHome() + '\'' +
", hobby='" + this.getHobby() + '\'' +
'}';
}
}
- 然後完成對應的具體實現類 PersonDao.java
package jdbc.preparedStatement;
import org.junit.jupiter.api.Test;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**通過使用PreparedStatement實現增刪改查
* @author GJXAIOU
* @create 2019-08-01-21:23
*/
public class PersonDao {
/**
* 輸入一個Person類對象,保存數據到數據庫中
* @param person
* @return int類型,返回值大於0表示添加成功,等於0表示添加數據失敗
*/
public int addTest(Person person) {
// 1.建立連接
Connection connection = JdbcUtil.getConnection();
// 2.準備預處理SQL語句
String sql = "insert into person(name, gender, score, home, hobby) values(?, ?, ?, ?, ?)";
PreparedStatement preparedStatement = null;
try {
// 3.使用preparedStatement處理SQL語句
preparedStatement = connection.prepareStatement(sql);
//插入數據
preparedStatement.setString(1,person.getName());
preparedStatement.setString(2,person.getGender());
preparedStatement.setInt(3, person.getScore());
preparedStatement.setString(4,person.getHome());
preparedStatement.setString(5, person.getHobby());
//指向SQL語句,返回的int 類型爲影響的行數
return preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.closeConnection(connection, preparedStatement);
}
return 0;
}
/**
* 根據id刪除數據庫中數據
* @param id
* @return int類型,返回值大於0表示刪除成功,返回0表示刪除數據失敗
*/
public int deleteTest(int id){
// 1.建立數據庫連接
Connection connection = JdbcUtil.getConnection();
// 2.準備預處理SQL語句
String sql = "delete from person where id = ?";
// 3.使用preparedStatement處理SQL語句
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
// 4.輸入參數
preparedStatement.setInt(1, id);
return preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtil.closeConnection(connection, preparedStatement);
}
return 0;
}
/**
* 修改Person表中數據信息
* @param person 傳入的person類對象
* @return int類型,返回值大於0表示修改成功,返回0表示修改數據失敗
*/
public int updateTest(Person person){
// 1.建立連接
Connection connection = JdbcUtil.getConnection();
// 2.準備預處理的SQL語句
String sql = "update person set name = ? , gender = ? where id = ?";
// 3.使用preparedstatement處理SQL語句
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
// 4.輸入參數
preparedStatement.setString(1, person.getName());
preparedStatement.setString(2, person.getGender());
preparedStatement.setInt(3, person.getId());
return preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtil.closeConnection(connection, preparedStatement);
}
return 0;
}
/**
* 查詢數據庫person中所有的信息,返回一個list集合
* @return 返回保存person類對象的list集合
*/
public List<Person> selectTest() {
ResultSet set = null;
PreparedStatement preparedStatement = null;
List<Person> list = new ArrayList<Person>();
// 1.建立連接
Connection connection = JdbcUtil.getConnection();
// 2.準備SQL語句
String sql = "select * from person";
// 3.使用preparedstatement執行SQL語句
try {
preparedStatement = connection.prepareStatement(sql);
// 4.接收結果集
set = preparedStatement.executeQuery();
// 5.獲取查找結果
while (set.next()){
Person person = new Person();
person.setId(set.getInt("id"));
person.setName(set.getString("name"));
person.setGender(set.getString("gender"));
person.setScore(set.getInt("score"));
person.setHome(set.getString("home"));
person.setHobby(set.getString("hobby"));
list.add(person);
}
return list;
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtil.closeConnectionWithResult(connection, preparedStatement, set);
}
return null;
}
/**
* 根據ID,查詢數據庫person中的對應信息,返回一個person類對象
* @param id 要查詢的id
* @return 返回一個person類對象,如果沒有找到,返回null
*/
public Person selectByIdTest(int id){
ResultSet set = null;
PreparedStatement preparedStatement = null;
Connection connection = null;
Person person = new Person();
// 1.連接數據庫
connection = JdbcUtil.getConnection();
// 2.準備SQL語句
String sql = "select * from person where id = ?";
// 3.使用Preparedstatement指向SQL語句
try {
preparedStatement = connection.prepareStatement(sql);
// 4.傳入參數:
preparedStatement.setInt(1,id);
set = preparedStatement.executeQuery();
if (set.next()){
person.setId(set.getInt("id"));
person.setName(set.getString("name"));
person.setGender(set.getString("gender"));
person.setScore(set.getInt("score"));
person.setHome(set.getString("home"));
person.setHobby(set.getString("hobby"));
}
return person;
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtil.closeConnectionWithResult(connection, preparedStatement, set);
}
return null;
}
}
- 最後實現界面的 PersonView.java
package jdbc.preparedStatement;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @author GJXAIOU
* @create 2019-08-02-9:39
*/
public class PersonView {
public static void main(String[] args) {
PersonDao personDao = new PersonDao();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("$$$$$$$$$$$$$$$$$$$$$$");
System.out.println("1. 添加數據");
System.out.println("2. 刪除數據");
System.out.println("3. 更新數據");
System.out.println("4. 查詢所有數據");
System.out.println("5. 查看指定數據");
System.out.println("6. 退出");
System.out.println("$$$$$$$$$$$$$$$$$$$$$$");
int choose = scanner.nextInt();
switch (choose) {
case 1:
System.out.println("請輸入姓名");
String name = scanner.next();
System.out.println("請輸入性別");
String gender = scanner.next();
System.out.println("請輸入分數");
int score = scanner.nextInt();
System.out.println("請輸入家鄉:江蘇、上海、杭州");
String home = scanner.next();
System.out.println("請輸入愛好(多選):游泳、打球、跑步");
String hobby = scanner.next();
Person person = new Person();
person.setName(name);
person.setGender(gender);
person.setScore(score);
person.setHome(home);
person.setHobby(hobby);
personDao.addTest(person);
break;
case 2:
System.out.println("請輸入要刪除的ID號");
int idDelete = scanner.nextInt();
personDao.deleteTest(idDelete);
break;
case 3:
Person person1 = new Person();
System.out.println("請輸入要修改人員的ID號:");
int idUpdate = scanner.nextInt();
person1.setId(idUpdate);
System.out.println("請輸入修改後的姓名:");
String nameUpdate = scanner.next();
person1.setName(nameUpdate);
System.out.println("請輸入修改後的性別:");
String genderUpdate = scanner.next();
person1.setGender(genderUpdate);
personDao.updateTest(person1);
break;
case 4:
System.out.println("person數據表中所有數據爲:");
for (Person person2 : personDao.selectTest()) {
System.out.println(person2.toString());
}
break;
case 5:
System.out.println("請輸入要查詢人員的ID號:");
int idSelect = scanner.nextInt();
System.out.println(personDao.selectByIdTest(idSelect).toString());
break;
case 6:
System.out.println("退出程序");
System.exit(0);
break;
default:
break;
}
}
}
}
批處理操作
如果通過ps.executeUpdate的方式一條條 地執行語句 , 那麼每次執行語句都包括 “ 連 數據庫+執行語句+釋放數據庫 連接" 3個動作。相比之下 ,如果用批處理的方式, 那麼耗費的代價是 “—次連接+多次執行+一次釋放 ” ,這樣就能省去多次連接和釋放數據庫 資源從而提升操作性能。
一般針對於批量插入操作;BatchPractice.java
package jdbc.batching;
import jdbc.preparedStatement.JdbcUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @author GJXAIOU
* @create 2019-08-02-15:15
*/
public class BatchPratice {
public static void main(String[] args) {
batch();
}
public static void batch() {
// 1.建立連接
Connection connection = JdbcUtil.getConnection();
// 2.準備是SQL語句
String sql = "insert into person(name, gender, score, home, hobby) value(?, ?, ?, ?, ?)";
// 3.使用preparedstatement運輸SQL語句
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
int flag = 0;
for (int i = 0; i < 10; i++) {
String name = "張三" + i + "號";
String gender = "男";
int score = 87 + i;
String home = "江蘇";
String hobby = "游泳";
preparedStatement.setString(1, name);
preparedStatement.setString(2, gender);
preparedStatement.setInt(3, score);
preparedStatement.setString(4, home);
preparedStatement.setString(5, hobby);
// 4.添加批處理,addBatch會將所有記錄先放入緩存
preparedStatement.addBatch();
flag++;
// 設置每5條批處理一次
if (flag % 5 == 0){
// 執行保存到批處理裏面的SQL語句
preparedStatement.executeBatch();
// 執行保存在批處理裏面的SQL語句之後,清空批處理的緩衝區
preparedStatement.clearBatch();
flag = 0;
}
}
// 處理批處理中剩餘的SQL語句,即剩餘不夠5個的倍數
if (flag > 0){
// 執行批處理
preparedStatement.executeBatch();
preparedStatement.clearBatch();
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtil.closeConnection(connection, preparedStatement);
}
}
}
保存文本數據到數據庫
內容使用 blob 格式
package c_blob;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import utils.JDBCUtil;
public class Demo {
public static void main(String[] args) throws Exception {
//writeTest();
readTest();
}
/**
* 把文件數據,保存到數據庫
* @throws Exception
*/
public static void writeTest() throws Exception {
Connection conn = JDBCUtil.getConnection();
String sql = "insert into testblob(value) values(?)";
PreparedStatement statement = conn.prepareStatement(sql);
//使用緩衝字節流讀取數據
BufferedInputStream bs = new BufferedInputStream(
new FileInputStream(new File("./res/《The Story of the Stone》.txt")));
//設置字節流
statement.setBinaryStream(1, bs);
//statement.setCharacterStream(int parameterIndex, Reader reader);
statement.executeUpdate();
JDBCUtil.close(conn, statement);
bs.close();
}
//將剛纔放入數據庫是的數據拿出
public static void readTest() throws Exception {
Connection conn = JDBCUtil.getConnection();
String sql = "select value from testblob where id = 1";
PreparedStatement statement = conn.prepareStatement(sql);
BufferedInputStream bs = null;
BufferedOutputStream bos = null;
ResultSet set = statement.executeQuery();
if (set.next()) {
//採用字符流進行讀取
InputStream in = set.getBinaryStream(1);
bs = new BufferedInputStream(in);
bos = new BufferedOutputStream(
new FileOutputStream(new File("C:\\javaEE1707\\Day36\\res\\1.txt")));
int length = 0;
byte[] buf = new byte[8 * 1024];
while ((length = bs.read(buf)) != -1) {
bos.write(buf, 0, length);
}
}
JDBCUtil.close(conn, statement, set);
bos.close();
bs.close();
}
}
獲取自增長值
package d_getincrement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import utils.JDBCUtil;
public class Demo {
public static void main(String[] args) throws SQLException {
//getCount();
getAutoIncrementValue();
}
public static void getAutoIncrementValue() throws SQLException {
Connection conn = JDBCUtil.getConnection();
String sql = "insert into person(name, age) values('吳京', 40)";
/*
* 想要在插入數據的同時獲取到當前插入數據的ID號
* 實際意義:秒殺活動第幾名,第幾個註冊用戶
*/
//獲取PreparedStatement添加一個參數 Statement.RETURN_GENERATED_KEYS
PreparedStatement statement = conn.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
statement.executeUpdate();
//從已經設置過參數的PreparedStatement裏面獲取到自增長值結果集ResultSet類型
ResultSet generatedKeys = statement.getGeneratedKeys();
if (generatedKeys.next()) {
int id = generatedKeys.getInt(1);
System.out.println("id = " + id);
}
JDBCUtil.close(conn, statement, generatedKeys);
}
//計算數據庫中數量
public static void getCount() throws SQLException {
Connection conn = JDBCUtil.getConnection();
String sql = "select count(*) c from person";
PreparedStatement statement = conn.prepareStatement(sql);
ResultSet set = statement.executeQuery();
if (set.next()) {
//System.out.println(set.getInt("count(*)"));
System.out.println(set.getInt("c"));
}
JDBCUtil.close(conn, statement, set);
}
}
事務處理
- 方式一:關閉自動提交
package e_transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
//Savepoint
import utils.JDBCUtil;
public class Demo1 {
public static void main(String[] args) {
account();
}
/**
* 最基本在Java中使用數據庫的回滾機制
*/
public static void account() {
Connection conn = JDBCUtil.getConnection();
PreparedStatement statement1 = null;
PreparedStatement statement2 = null;
try {
//關閉自動提交,這就是開啓事務,設置回滾點
conn.setAutoCommit(false);
String sql1 = "update bank set money = money - 1000000000 where userID=1";
statement1 = conn.prepareStatement(sql1);
String sql2 = "update bank set money = money + 1000000000 where userID=2";
statement2 = conn.prepareStatement(sql2);
statement1.executeUpdate();
statement2.executeUpdate();
//如果這裏沒有確定提交SQL語句,也就是沒有commit,數據庫裏面的數據不會發生改變
conn.commit();
} catch (SQLException e) {
//如果在執行某一個SQL語句時發生了異常,那麼一般情況下,這裏事務之後的SQL語句,全部要回滾到事件之前
e.printStackTrace();
try {
//回滾到事務之前
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
statement1.close();
statement2.close();
//關閉數據庫連接要放到最後面,確定在數據庫操作中產生的資源全部釋放掉之後,再斷開數據庫連接
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
- 方式二:設置還原點
注意 commit 位置,如果還原點之後代碼沒有問題,就應該將還原點之前操作和之後的操作都提交;如果有問題,應該將還原點之前的代碼進行提交。
package e_transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
//Savepoint
import utils.JDBCUtil;
public class Demo1 {
public static void main(String[] args) {
useSavepoint();
}
public static void useSavepoint() {
Connection conn = JDBCUtil.getConnection();
PreparedStatement statement1 = null;
PreparedStatement statement2 = null;
//還原點!!!
Savepoint savepoint = null;
try {
//下面這裏沒有還原點
conn.setAutoCommit(false);
String sql1 = "update bank set money = money - 1000000000 where userID=1";
statement1 = conn.prepareStatement(sql1);
String sql2 = "update bank set money = money + 1000000000 where userID=2";
statement2 = conn.prepareStatement(sql2);
statement1.executeUpdate();
statement2.executeUpdate();
statement1.close();
statement2.close();
//下面有還原點
//設置還原點
savepoint = conn.setSavepoint();
sql1 = "update bank set name = '馬雲' where userID=1";
statement1 = conn.prepareStatement(sql1);
sql2 = "update bank set name = '匿名君' where userID=2";
statement2 = conn.prepareStatement(sql2);
statement1.executeUpdate();
statement2.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
try {
//回滾到還原點,相當於取消設置還原點之後的代碼執行
conn.rollback(savepoint);
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} finally {
try {
conn.commit();
statement1.close();
statement2.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}