1. 程式人生 > >jdbc-mysql基礎 增刪查改 簡單示例

jdbc-mysql基礎 增刪查改 簡單示例

做的 裏的 http exec pda 針對 ping 含義 ade

禮悟:
   好好學習多思考,尊師重道存感恩。葉見尋根三二一,江河湖海同一體。
虛懷若谷良心主,願行無悔給最苦。讀書鍛煉強身心,誠勸且行且珍惜。


  數據、數據,命根就在數據。雲計算、AI等技術,都是以數據為基礎。操作數據庫一定要謹慎小心。給最苦 這裏的代碼,看看就好,要有自己的判斷。遇到抉擇,要不恥上下問。
javaSE:8
mysql:5.7.14
mysql-connector-java:5.1.44
os:windows7 x64
ide:MyEclipse 2017

項目結構

技術分享

下面是各個包下的各個類的代碼展示

com.jizuiku.jdbc

  - JDBCUtils

package com.jizuiku.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.jizuiku.jdbc.dao.DaoException;


/**
 * 
 * 
 * @author 給最苦
 * @version V17.11.07
 */
public final class JDBCUtils {

	/**
	 * url格式 -> jdbc:子協議:子名稱//主機名:端口號/數據庫的名字?屬性名=屬性值&屬性名=屬性值
	 * configString變量中有多個參數,需要深入地去研究它們的具體含義
	 */
	private static String configString = "?useUnicode=true&characterEncoding=utf8&useSSL=true";
	private static String url = "jdbc:mysql://localhost:3306/jdbcforjava" + configString;
	// 本地的mysql數據庫(無子名稱) 端口號3306 數據庫jdbcforjava

	private static String user = "root";
	private static String password = "";

	// 工具類,直接使用,不可生對象
	private JDBCUtils() {
	}

	// 把註冊驅動放到靜態代碼塊中,因為 靜態代碼塊只執行一次
	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			// 異常要拋出去
			throw new ExceptionInInitializerError(e);
		}
	}

	/**
	 * 獲取與指定數據庫的鏈接
	 * 
	 */
	public static Connection getConnection() throws SQLException {
		return DriverManager.getConnection(url, user, password);
	}

	/**
	 * 釋放三種資源ResultSet Statement Connection
	 * 
	 */
	public static void free(ResultSet rs, PreparedStatement ps, Connection con) {
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			throw new DaoException(e);
		} finally {
			try {
				if (ps != null) {
					ps.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				throw new DaoException(e);
			} finally {
				try {
					if (con != null) {
						con.close();
					}
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					throw new DaoException(e);
				}
			}
		}
	}
}

com.jizuiku.jdbc.dao

  - BookDao

package com.jizuiku.jdbc.dao;

import com.jizuiku.jdbc.domain.Book;

/**
 * 這個接口可以將 業務邏輯層與數據訪問層 分割開來的,是一種很強的思想。 
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public interface BookDao {
	/**
	 * 添加新的書籍
	 * 
	 */
	public void addBook(Book book);

	/**
	 * 根據id來查詢相關書籍的信息,因為id是唯一的
	 * 
	 */
	public Book getBook(int id);
	
	/**
	 * 更新數據庫中的書籍
	 * 
	 * */
	public void updateBook(Book book);
	
	/**
	 * 刪除數據庫中的指定書籍
	 * 
	 * */
	public void deleteBook(Book book);
}

  - DaoException

package com.jizuiku.jdbc.dao;

/**
 * 這個類很重要,即完成了拋異常的動作、通過編譯,又可以使數據邏輯層的接口保持簡潔。
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public class DaoException extends RuntimeException {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public DaoException() {
		// TODO Auto-generated constructor stub
	}

	public DaoException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public DaoException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}

	public DaoException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public DaoException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

}

  - DaoFactory

package com.jizuiku.jdbc.dao;

import java.io.InputStream;
import java.util.Properties;

/**
 * 工廠類-單例模式
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public class DaoFactory {
	
	/*
	 * 這裏有個大坑:只要把這兩句話,調換一下位置。那麽返回的bookDao總是null
	 * 為什麽?
	 * 	     因為想想初始化的順序,new DaoFactory()經過千辛萬苦 把bookDao弄好了,
	 * 	     緊接著 BookDao bookDao = null;...前功盡棄
	 * */
	private static BookDao bookDao = null;
	private static DaoFactory instance = new DaoFactory();
	
	/**
	 * Properties + 反射 ->初始化
	 * 這樣的話,以後 給最苦 把接口從新實現了一下,生出了一個新的類。那麽 只需要改配置文件就OK了
	 * 天呀,這是哪位前輩想到的。。。
	 * 
	 * */
	private DaoFactory() {
		// TODO Auto-generated constructor stub
		// 這裏使用Properties讀取配置文件
		// 也可以使用xml
		Properties prop = new Properties();
		InputStream inputStream = null;
		
		try {
			
			// 這個寫的,很強!
			inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("bookDao.properties");
			
			// 通過流加載配置文件
			prop.load(inputStream);
			
			/* 
			 * bookDao=com.jizuiku.jdbc.dao.impl.BookDaoJDBCImpl
			 * key:bookDao
			 * value:com.jizuiku.jdbc.dao.impl.BookDaoJDBCImpl
			 * value剛好是bookDao接口的實現類
			 */
			String bookDaoImplClassPath = prop.getProperty("bookDao");
			
			// 有了bookDaoImplClassPath,就可以應用反射來構造這個類
			bookDao = (BookDao)Class.forName(bookDaoImplClassPath).newInstance();
			
		} catch (Exception e) {
			// try中所有的代碼都是初始化的過程,所以 一旦有錯誤,那麽直接報錯!
			throw new ExceptionInInitializerError(e);
		}
		
	}

	public static DaoFactory getInstance() {
		return instance;
	}

	public BookDao getBookDao() {
		return bookDao;
	}

}

com.jizuiku.jdbc.dao.impl

  - BookDaoJDBCImpl

package com.jizuiku.jdbc.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.jizuiku.jdbc.JDBCUtils;
import com.jizuiku.jdbc.dao.BookDao;
import com.jizuiku.jdbc.dao.DaoException;
import com.jizuiku.jdbc.domain.Book;

/**
 * 
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public class BookDaoJDBCImpl implements BookDao {
	
	/**
	 * 增加操作
	 * 
	 * */
	@Override
	public void addBook(Book book) {
		// TODO Auto-generated method stub
		Connection con = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		
		try {

			// 註冊驅動並建立連接
			con = JDBCUtils.getConnection();

			// 創建語句 並 對sql語句進行一些預處理
			String sql = "insert into book(name,quantity,time,price) values(?,?,?,?)";
			// 註明要返回主鍵
			ps = con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);

			// 向sql語句中傳入值
			ps.setString(1, book.getName());
			ps.setInt(2, book.getQuantity());
			ps.setDate(3, new java.sql.Date(book.getTime().getTime()));
			ps.setBigDecimal(4, book.getPrice());

			// 執行sql語句
			ps.executeUpdate();
			
			// 得到的主鍵
			// 因為主鍵就一個,而且是Int類型的
			int id = 0;
			rs = ps.getGeneratedKeys();
			if(rs.next()){
				// 該對象成功插入數據庫,把得到的主鍵給這個book對象
				id = rs.getInt(1);
				book.setId(id);
			}
						 		
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			// 這裏針對異常的處理,蘊含著智慧,十分關鍵!
			throw new DaoException(e.getMessage(), e);

		} finally {
			// 釋放資源
			JDBCUtils.free(rs, ps, con);

		}
	}
	
	
	/**
	 * 查詢操作
	 * */
	@Override
	public Book getBook(int id) {
		// TODO Auto-generated method stub
		Connection con = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		Book book = null;

		try {
			// 註冊驅動並建立連接
			con = JDBCUtils.getConnection();

			// 創建語句
			String sql = "select id,name,quantity,time,price from book where id=?";
			ps = con.prepareStatement(sql);
			ps.setInt(1, id);

			// 執行語句
			rs = ps.executeQuery();
			
			// 處理結果
			if (rs.next()) {
				// 有查詢到,那麽創建一個對象s
				book = mappingBook(rs);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			// 這裏針對異常的處理,蘊含著智慧,十分關鍵!
			throw new DaoException(e.getMessage(), e);

		} finally {
			// 釋放資源
			JDBCUtils.free(rs, ps, con);
		}

		return book;
	}
	
	/**
	 * 修改操作
	 * 
	 * */
	@Override
	public void updateBook(Book book) {
		// TODO Auto-generated method stub
		Connection con = null;
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			// 註冊驅動並建立連接
			con = JDBCUtils.getConnection();

			// 創建語句
			String sql = "update book set name=?,quantity=?,time=?,price=? where id=?";
			ps = con.prepareStatement(sql);
		
			// 向sql語句中傳入值
			ps.setString(1, book.getName());
			ps.setInt(2, book.getQuantity());
			// 進行轉換 從util包下的date轉為 sql包下的date
			ps.setDate(3, new java.sql.Date(book.getTime().getTime()));
			ps.setBigDecimal(4, book.getPrice());
			ps.setInt(5, book.getId());
			
			// 執行語句
			ps.executeUpdate();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			// 這裏針對異常的處理,蘊含著智慧,十分關鍵!
			throw new DaoException(e.getMessage(), e);

		} finally {
			// 釋放資源
			JDBCUtils.free(rs, ps, con);
		}
	}
	
	/**
	 * 刪除操作
	 * 
	 * */
	@Override
	public void deleteBook(Book book) {
		// TODO Auto-generated method stub

		Connection con = null;
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			// 註冊驅動並建立連接
			con = JDBCUtils.getConnection();

			// 創建語句
			String sql = "delete from book where id=?";
			ps = con.prepareStatement(sql);
			ps.setInt(1, book.getId());

			// 執行語句
			ps.executeUpdate();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			// 這裏針對異常的處理,蘊含著智慧,十分關鍵!
			throw new DaoException(e.getMessage(), e);

		} finally {
			// 釋放資源
			JDBCUtils.free(rs, ps, con);
		}

	}

	/**
	 * 根據查詢結果對Book對象進行賦值,並返回一個賦值好的對象
	 * 
	 */
	private Book mappingBook(ResultSet rs) throws SQLException {
		// 這樣做的好處是:減少代碼重復使用
		// 便於以後的優化
		Book book = new Book();
		book.setId(rs.getInt("id"));
		book.setName(rs.getString("name"));
		book.setQuantity(rs.getInt("quantity"));
		book.setTime(rs.getTimestamp("time"));
		book.setPrice(rs.getBigDecimal("price"));
		return book;
	}

}

com.jizuiku.jdbc.domain

  - Book

package com.jizuiku.jdbc.domain;

import java.math.BigDecimal;

/**
 * Book對象與數據庫的表示對應的
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public class Book {
	
	
	private int id;
	private String name;
	private int quantity;
	private java.util.Date time;
	private BigDecimal price;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getQuantity() {
		return quantity;
	}
	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}
	public java.util.Date getTime() {
		return time;
	}
	public void setTime(java.util.Date time) {
		this.time = time;
	}
	public BigDecimal getPrice() {
		return price;
	}
	public void setPrice(BigDecimal price) {
		this.price = price;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((price == null) ? 0 : price.hashCode());
		result = prime * result + quantity;
		result = prime * result + ((time == null) ? 0 : time.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Book other = (Book) obj;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (price == null) {
			if (other.price != null)
				return false;
		} else if (!price.equals(other.price))
			return false;
		if (quantity != other.quantity)
			return false;
		if (time == null) {
			if (other.time != null)
				return false;
		} else if (!time.equals(other.time))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "Book [id=" + id + ", name=" + name + ", quantity=" + quantity + ", time=" + time + ", price=" + price
				+ "]";
	}
	
	
	
}

數據庫中的數據

技術分享

下面進行 增刪查改 的測試!

com.jizuiku.jdbc.demo

  - Demo

  刪除測試

package com.jizuiku.jdbc.demo;

import java.math.BigDecimal;
import java.util.Date;

import com.jizuiku.jdbc.dao.BookDao;
import com.jizuiku.jdbc.dao.DaoFactory;
import com.jizuiku.jdbc.domain.Book;

/**
 * 測試類
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public class Demo {

	public static void main(String[] args) {
		
		// 使用工廠類,擴展性變得更強!
		BookDao bookDao = DaoFactory.getInstance().getBookDao();
		
		Book book = new Book();
		book.setId(15);
		
		// 刪除測試
		// 刪除id=15的那條記錄
		bookDao.deleteBook(book);
		 System.out.println(book.toString());
	}
}

  運行代碼前數據庫的狀態

技術分享

  運行代碼,控制臺的輸出是

技術分享

  

  數據庫中的數據發生變動

技術分享

  增加測試

package com.jizuiku.jdbc.demo;

import java.math.BigDecimal;
import java.util.Date;

import com.jizuiku.jdbc.dao.BookDao;
import com.jizuiku.jdbc.dao.DaoFactory;
import com.jizuiku.jdbc.domain.Book;

/**
 * 測試類
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public class Demo {

	public static void main(String[] args) {
		
		// 使用工廠類,擴展性變得更強!
		BookDao bookDao = DaoFactory.getInstance().getBookDao();
		
		Book book = new Book();
		book.setName("孟子");
		book.setQuantity(40);
		book.setTime(new Date());
		book.setPrice(new BigDecimal(Double.toString(99.99)));
			
		// 增加測試完成!
	        bookDao.addBook(book);
		
		System.out.println(book.toString());
	}
	
	 

}

  運行代碼前數據庫的狀態

技術分享

  運行代碼,控制臺的輸出是

技術分享

  數據庫中的數據發生變動

技術分享

  查找測試

package com.jizuiku.jdbc.demo;

import java.math.BigDecimal;
import java.util.Date;

import com.jizuiku.jdbc.dao.BookDao;
import com.jizuiku.jdbc.dao.DaoFactory;
import com.jizuiku.jdbc.domain.Book;

/**
 * 測試類
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public class Demo {

	public static void main(String[] args) {
		
		// 使用工廠類,擴展性變得更強!
		BookDao bookDao = DaoFactory.getInstance().getBookDao();
		
		Book book = new Book();
		
		// 查找測試完成!
		 book = bookDao.getBook(5);
		 System.out.println(book.toString());
	}
	
	 

}

  數據庫中存儲的數據

技術分享

  運行代碼後,控制臺輸出的結果

技術分享

  註:給最苦 所做的這個查詢是按照 id值來查詢的,結果唯一。給最苦 沒有實現結果不唯一的查詢。

  修改測試

package com.jizuiku.jdbc.demo;

import java.math.BigDecimal;
import java.util.Date;

import com.jizuiku.jdbc.dao.BookDao;
import com.jizuiku.jdbc.dao.DaoFactory;
import com.jizuiku.jdbc.domain.Book;

/**
 * 測試類
 * 
 * @author 博客園-給最苦
 * @version V17.11.08
 */
public class Demo {

	public static void main(String[] args) {
		
		// 使用工廠類,擴展性變得更強!
		BookDao bookDao = DaoFactory.getInstance().getBookDao();
		
		Book book = new Book();
		book.setId(6);
		book.setName("孟子");
		book.setQuantity(40);
		book.setTime(new Date());
		book.setPrice(new BigDecimal(Double.toString(99.99)));
		
		// 更改測試完成!
	        // 是根據Id值來更改的
		bookDao.updateBook(book);

		 System.out.println(book.toString());
	}
	
	 

}

  執行代碼前,數據庫的內容

技術分享

  執行代碼後,控制臺的輸出

技術分享

  數據庫的變動

技術分享

  好,博文到這裏就結束了。。。終於結束了。給最苦 都寫累了。

  那個《金剛經》上講:“以無我無人無眾生無壽者。修一切善法。”,所以 給最苦 在這裏就不討要個 感恩的心了。但是,還是講如果有心的話,在心裏說聲謝謝唄。雖然 給最苦 的技術很差,這篇博文的水平也只能用來參考。但是,這份堅持把 給最苦 都感動壞了。

  還是博文開頭的那句話:

  數據、數據,命根就在數據。雲計算、AI等技術,都是以數據為基礎。操作數據庫一定要謹慎小心。給最苦 這裏的代碼,看看就好,要有自己的判斷。遇到抉擇,要不恥上下問。

  加油!


學習資源:itcast和itheima視頻庫。如果您有公開的資源,可以分享給我的話,用您的資源學習也可以。
博文是觀看視頻後,融入思考寫成的。博文好,是老師講得好。博文壞,是 給最苦 沒認真。

jdbc-mysql基礎 增刪查改 簡單示例