JDBC
驅動加載 => 連接創建 => 創建編譯 / 預編譯陳述句 => 獲取結果集 => 遍歷結果集 => 回傳結果集
| 介面 | |
|---|---|
| Driver | 驅動 |
| Connection | 連接 |
| Statement | 操作 |
| ResultSet | 結果集 |
-
具體的實作不需要由Java的公司自己提供
-
所有開發者使用JDBC的規范都被統一定義
連接資料庫(mysql)
統一資源定位符URL:jdbc:mysql:// + ip地址 + 埠 + 訪問的資料庫 + 請求引數(配置資訊)
mysql驅動類的完整路徑:com.mysql.jdbc.Driver
public class DBUtil {
// 定義用戶名
private static final String USER_NAME = "root";
// 定義密碼
private static final String PASSWORD = "123456";
// URL--統一資源定位符
// jdbc:mysql:// + ip地址 + 埠 + 訪問的資料庫 + 請求引數(配置資訊)
private static final String URL = "jdbc:mysql://localhost:3306/iWeb?characterEncoding=utf8";
// 加載驅動(靜態代碼塊)
static {
// mysql驅動類的完整路徑
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("驅動加載失敗!");
}
}
// 定義一個獲取資料庫連接的方法
public static Connection getConnection(){
try {
return DriverManager.getConnection(URL,USER_NAME,PASSWORD);
} catch (SQLException e) {
System.out.println("連接獲取失敗!");
return null;
}
}
}
// 連接測驗
public static void main(String[] args) {
// 定義sql陳述句
String sql = "insert into student(name) values('robot03')";
// try-with 代碼塊,在try后額外提供一個括號,括號里面的資源在try-catch結束后自動釋放
// 只有實作了AutoCloseable介面的類,才支持使用try-with自動關閉
// 獲取資料庫連接 + 生成statement編譯陳述句
try(Connection connection = DBUtil.getConnection();
Statement statement = connection.createStatement()) {
// 執行陳述句
statement.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
代碼封裝(DAO)& CRUD
? DAO層:負責提供JDBC支持,提供對應的DAO介面和實作類
? ORM(object relation model):物件應用模型,對資料庫物件的映射
// 測驗表對應的JavaBean
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private long id;
private String name;
private String gender;
private String address;
private long phone;
}
增(insert)
// 增(insert)
public void insert(Student student) {
// 空值判斷
if(student == null || student.getName() == null || "".equals(student.getName())){
System.out.println("引數有誤!");
return;
}
String sql = "insert into student(NAME,GENDER,ADDRESS,PHONE) values(?,?,?,?)";
try(Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)){
// 添加引數
preparedStatement.setString(1,student.getName());
preparedStatement.setString(2,student.getGender());
preparedStatement.setString(3,student.getAddress());
preparedStatement.setInt(4,student.getPhone());
// 執行陳述句
preparedStatement.execute();
}catch(SQLException e){
e.printStackTrace();
}
}
刪(delete)
// 刪(delete)
public void delete(Student student) {
String sql = "delete from student where 1=1";
if(student == null){
System.out.println("引數有誤!");
return;
}
if(student.getId() > 0 && (student.getName() == null || "".equals(student.getName()))){
// 使用 PreparedStatement 進行引數傳遞,只需要將 sql 中的引數標記為 ? 即可
sql = sql +" and id = ?";
// 使用預編譯物件的時候,在創建物件時就需要傳入sql
try(Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)){
// 數字代表引數序號
preparedStatement.setInt(1, student.getId());
// 執行sql陳述句
preparedStatement.execute();
}catch(SQLException e){
e.printStackTrace();
}
} else if (student.getId() <= 0 && student.getName() != null && (!"".equals(student.getName()))) {
sql = sql +" and NAME = ?";
try(Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)){
// 數字代表引數序號
preparedStatement.setString(1, student.getName());
// 執行sql陳述句
preparedStatement.execute();
}catch(SQLException e){
e.printStackTrace();
}
}else {
System.out.println("引數有誤!");
}
}
改(update)
public void update(Student student) {
String sql = "update student set name = ? where id = ?";
// 空值判斷
if(student == null || student.getName() == null || "".equals(student.getName())){
System.out.println("引數有誤!");
return;
}
try(Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)){
// 傳參
preparedStatement.setString(1,student.getName());
preparedStatement.setInt(2,student.getId());
// 執行sql陳述句
preparedStatement.execute();
}catch(SQLException e){
e.printStackTrace();
}
}
查(select)
// 普通查詢
public Collection<Student> listByPage(int start, int count) {
List<Student> result = new ArrayList<>();
String sql = "select * from student limit ?,?";
try(Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)){
// 傳參
preparedStatement.setInt(1,start);
preparedStatement.setInt(2,count);
// 執行查詢陳述句的時候,需要使用 ResultSet 接收結果
ResultSet resultSet = preparedStatement.executeQuery();
while(resultSet.next()){
result.add(new Student(resultSet.getInt("id"),resultSet.getString("name"), resultSet.getString("gender"),resultSet.getString("address"),resultSet.getInt("phone")));
}
}catch(SQLException e){
e.printStackTrace();
}
if(result.size() == 0){
return null;
}else{
return result;
}
}
// 模糊查詢(字串拼接)
public Collection<Student> listWithNameLike(String key) {
List<Student> result = new ArrayList<>();
String sql = "select * from student where name like ?";
try(Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)){
// 傳參
preparedStatement.setString(1,"%" + key + "%");
// 接收結果
ResultSet resultSet = preparedStatement.executeQuery();
while(resultSet.next()){
result.add(new Student(resultSet.getInt("id"),resultSet.getString("name"), resultSet.getString("gender"),resultSet.getString("address"),resultSet.getInt("phone")));
}
}catch(SQLException e){
e.printStackTrace();
}
if(result.size() == 0){
return null;
}else{
return result;
}
}
preparedStatement ?? 和 statement ??的區別:
- 引數傳遞的區別,preparedStatement 更加方便,可讀性更強
- 性能差異,statement 先傳參再編譯(每次執行陳述句都需要進行一次編譯),preparedStatement 先編譯后傳參(相同的陳述句只需要編譯一次),相比較 preparedStatement 性能更好??
- ??安全問題,statement 存在 sql 注入!!!!
Junit 單元測驗
public class TestStudentDAO {
private StudentDAO studentDAO;
@Before
// 被該注解修飾的方法會在所有@Test修飾的方法執行之前執行,一般用于資源加載
public void init(){
studentDAO = new StudentDAOImpl();
System.out.println("假裝資源被初始化,,,");
}
@After
// 被該注解修飾的方法會在所有@Test修飾的方法執行之后執行,一般用于資源釋放
public void destroy(){
System.out.println("假裝資源被銷毀,,,");
}
@Test
public void test(){
Collection<Student> students = studentDAO.listAll();
// 斷言類
// 判斷是否不為空
Assert.assertFalse(students.isEmpty());
// 判斷大小是否和預期值一樣
Assert.assertEquals(3,students.size());
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/556922.html
標籤:其他
上一篇:C++類模板實作工廠模式(優化if else/switch case)
下一篇:返回列表
