(點選上方公眾號,可快速關註)
來源:locality,
www.jianshu.com/p/84ead3cf70bb
前言
這裡我會採用mybatis3.2做資料庫的持久化,很多小夥伴或許還停留在老師的教導下,仍然停留在使用傳統的JDBC持久化訪問資料層。今天,我們來聊聊面向介面程式設計和怎麼充分利用註解的優勢!
實現DAO持久層
從目前的Java框架趨勢來看,spring框架仍舊佔據主流,不論你使用SSH框架和SSM框架開發,必透徹spring是無可厚非的。
從目前網際網路公司的分佈來看,中小型公司仍舊擁有半壁江山,它們沒有雄厚的資金和開發資源,也就是說極少有公司會使用hibernate+struts開發專案,對中小型公司來說開發超大型專案是不在它們的考慮範圍之內的。那麼,mybatis+springmvc開發框架就此興起…
閑聊結束,我先說說原理吧:
使用mybatis定義介面完成sql陳述句的對映,該介面還可以直接作為DAO的元件使用。
橋接樣式知道嗎?
橋接樣式在這裡的應用:
使用該樣式能夠體現業務邏輯元件封裝DAO元件的樣式,也可以分離業務邏輯元件和DAO元件的功能。也就是說,業務邏輯元件負責業務邏輯的變化,而DAO元件負責持久化的變化。
這樣做的好處:
①每個DAO元件包含了資料庫的訪問邏輯。
②每個DAO元件可對一個資料表完成基本的CRUD等操作。
1.公共常量類
HrmConstants 類
/**
*
* 常量
*
*/
public class HrmConstants {
//資料庫表常量
public static final String USERTABLE=”user_inf”;
public static final String DEPTTABLE=”dept_inf”;
public static final String JOBTABLE=”job_inf”;
public static final String EMPLOYEETABLE=”employee_inf”;
public static final String NOTICETABLE=”notice_inf”;
public static final String DOCUMENTTABLE=”document_inf”;
//登入
public static final String LOGIN=”loginFrom”;
//使用者的session物件
public static final String USER_SESSION=”user_session”;
//預設每頁4條資料
public static int PAGE_DEFAULT_SIZE=4;
}
這裡資料庫我就不貼出來了。這個公共常量類根據資料庫表的結構定義得,也就是說在資料庫裡面我一共建立了6個表,每個表和此類是一一對應的。至於這裡的session物件,是為了後期編寫控制層所鋪墊的,與本次所講內容無影響噢。
2.物體類
/**
*
* 使用者物體類
*
*/
public class User {
private Integer id;//id
private String username;//使用者名稱
private String loginname;//登入名
private String password;//密碼
private Integer status;//狀態
private Date createDate;//建檔日期
public User() {
}
//setter和getter方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
這裡,我會以使用者物體類做一個案例介紹。物體類的基本準則就是遵循javabean規則,也就是常說的公有的類、私有的成員變數以及自帶一個無參的構造方法。當然,這裡我用了setter和getter方法對其進行了簡單的封裝。
3.定義DAO介面
/**
*
* UserDao的介面實現類
*
*/
public interface UserDao {
//登入使用者名稱和密碼查詢員工
@Select(“select * from “+USERTABLE+” where loginname = #{loginname} and password = #{password} “)
User selectByLoginnmameAndPassword(
@Param(“loginname”) String loginname,
@Param(“password”) String password
);
//根據Id查詢使用者
@Select(“select * from “+USERTABLE+” where id = #{id} “)
User selectById(Integer id);
//根據Id刪除使用者
@Delete(“delete from “+USERTABLE+” where id = #{id} “)
void deleteById(Integer id);
//動態修改使用者
@SelectProvider(method = “updateUser”, type = UserDynaSqlProvider.class)
void update(User user);
//動態查詢
@SelectProvider(method = “selectWhitParam”, type = UserDynaSqlProvider.class)
List
selectByPage(Map params);
//根據引數查詢使用者總數
@SelectProvider(method = “count”, type = UserDynaSqlProvider.class)
Integer count(Map
params);
//動態插入使用者
@SelectProvider(method = “inserUser”, type = UserDynaSqlProvider.class)
void save(User user);
}
這裡才是真正的開始升華了,首先我只定義了一個 UserDao的介面,然後充分利用mybatis的註解優勢,定義了’登入使用者名稱和密碼查詢員工’的方法……
這裡為大家補充一下註解知識:
@Select註解,這個不用解釋了吧,就相當於存放查詢陳述句的一個註解,定義在某一個方法上,效果相當於在配置檔案裡面編寫查詢陳述句。
@Param註解,是對引數的解釋。這裡用的 string loginname是前面在公共常量類裡面定義的。怎麼說呢,我們可以理解成request.setAttribute(“”,””)這種形式的升華吧。
@SelectProvider註解,用於生成查詢用的sql陳述句,有別於@Select註解。結構上看,@SelectProvide指定了一個Class及其方法,透過呼叫Class上的這個方法來獲得sql陳述句。
註意事項:
①這裡的@Param註解是基於mybatis框架的,不是spring框架上的,匯入包的時候要註意喲!
②@SelectProvider註解在程式設計的思維上有一個跨度,因為它本身需要一個class和其方法,所以在定義這個註解的時候,務必思考好下一個層次結構裡面的類和方法所需要做的事哦!當然,在介面裡面的方法,是可以事先預算好的,但是在它上面的註解,就要多思考思考才能做決定哦!
③公共常量類。在此介面的運用上,既然是面向介面程式設計,還要完成資料庫的基本操作,那麼是一定要匯入公共常量類裡面的USERTABLE的。
④id = #{id} 生成的sql陳述句是 id = ?
4.動態SQL提供類
public class UserDynaSqlProvider {
//分頁動態查詢
public String selectWhitParam(final Map
params) { String sql=new SQL(){
{
SELECT(“*”);
FROM(USERTABLE);
if (params.get(“user”)!=null) {
User user=(User) params.get(“user”);
if (user.getUsername()!=null && !user.getUsername().equals(“”)) {
WHERE(” username LIKE CONCAT(‘%’,#{user.username},’%’) “);
}
if (user.getStatus()!=null && !user.getStatus().equals(“”)) {
WHERE(” status LIKE CONCAT(‘%’,#{user.status},’%’) “);
}
}
}
}.toString();
if (params.get(“pageModel”)!=null) {
sql += ” limit #{pageModel.firstLimitParam} , #{pageModel.pageSize} “;
}
return sql;
}
//動態查詢總數量
public String count(final Map
params) { return new SQL(){
{
SELECT(“*”);
FROM(USERTABLE);
if (params.get(“user”) !=null) {
User user=(User) params.get(“user”);
if (user.getUsername()!=null && !user.getUsername().equals(“”)) {
WHERE(” username LIKE CONCAT(‘%’,#{user.username},’%’) “);
}
if (user.getStatus()!=null && !user.getStatus().equals(“”)) {
WHERE(” status LIKE CONCAT(‘%’,#{user.status},’%’) “);
}
}
}
}.toString();
}
//動態插入
public String inserUser(final User user) {
return new SQL(){
{
INSERT_INTO(USERTABLE);
if (user.getUsername()!=null && !user.getUsername().equals(“”)) {
VALUES(“username”, “#{username}”);
}
if (user.getStatus()!=null && !user.getStatus().equals(“”)) {
VALUES(“status”, “#{status}”);
}
if (user.getLoginname()!=null && !user.getLoginname().equals(“”)) {
VALUES(“loginname”, “#{loginname}”);
}
if (user.getPassword()!=null && !user.getPassword().equals(“”)) {
VALUES(“password”, “#{password}”);
}
}
}.toString();
}
//動態更新
public String updateUser(final User user) {
return new SQL(){
{
UPDATE(USERTABLE);
if (user.getUsername()!=null) {
SET(” username = #{username} “);
}
if (user.getLoginname()!=null) {
SET(” loginname = #{loginname} “);
}
if (user.getPassword()!=null) {
SET(” password = #{password} “);
}
if (user.getStatus()!=null) {
SET(” status = #{status} “);
}
if (user.getCreateDate()!=null) {
SET(” create_date = #{createDate} “);
}
WHERE(” id = #{id} “);
}
}.toString();
}
}
正如前面編寫介面類的時候所說,既然用了@SelectProvider註解,必然會使用到一個class和它的方法。我們在介面類裡面用了四次@SelectProvider註解,那麼與之對應的就應該有四個方法,分別是分頁動態查詢(selectWhitParam)、動態查詢總數量(count)、動態插入(inserUser)、動態更新(updateUser)。
這個類是專門為介面提供sql陳述句服務的,不再需要傳統的去實現介面,用註解代替了原本繁瑣的事情。
ps:或許有人會疑惑,我們怎麼把所寫的配置在applicationContext.xml裡面呢?會不會很麻煩?現在,我告訴你,一點也不麻煩哦!
配置檔案
applicationContext.xml
db.properties
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://127.0.0.1:3306/hrm_db
dataSource.user=root
dataSource.password=root
dataSource.maxPoolSize=20
dataSource.maxIdleTime=1000
dataSource.minPoolSize=6
dataSource.initialPoolSize=5
原理:mybatis的持久化DAO介面只需要透過SqlSession的getMapper方法獲得對應的介面實體,從而達到呼叫介面方法完成資料庫的操作,而在spring容器裡,只負責生成和管理DAO的元件。
看完了?那麼大家覺得是不是要比傳統的JDBC持久化訪問要簡單些呢?我想,至少也要方便一些吧。
看完本文有收穫?請轉發分享給更多人
關註「ImportNew」,提升Java技能