springboot泛型封裝開發(fā)

JDK1.5出來后,Java開始支持泛型開發(fā)赘淮,通過將父類聲明為泛型,子類繼承父類睦霎,子類就能擁有父類的方法梢卸,而不需要再寫代碼。泛型開發(fā)能使我們的代碼開發(fā)提供了很大的簡便副女,簡化了我們的代碼蛤高。
在springboot項目中(其他項目也一樣),我們經(jīng)常要用到增刪改查接口,從controller/service/dao層戴陡,每一層都要寫增刪改查代碼塞绿,每一張數(shù)據(jù)表都要重復一遍增刪改查功能。雖然寫起來簡單恤批,但是作為程序員來講异吻,寫重復性的代碼就是在浪費時間,浪費生命喜庞。
程序員的主要精力應該放在如何實現(xiàn)業(yè)務上面诀浪。
下面我們來看下怎樣通過泛型開發(fā)來封裝代碼,簡化開發(fā)赋荆。
一笋妥、聲明泛型父類
泛型父類包括:controller/service/dao三層。

1窄潭、聲明泛型虛基類AbstractController,定義接口方法:

public abstract class AbstractController<T, K>{

    /**
     * 新增
     * @param t
     * @return
     */
    public abstract RtnData insert(T t);

    /**
     * 修改
     * @param t
     * @return
     */
    public abstract RtnData update(T t);

    /**
     * 刪除
     * @param
     * @return
     */
    public abstract RtnData delete(K id);

    /**
     * 按主鍵查詢
     * @param
     * @return
     */
    public abstract RtnData get(K Id);

    /**
     * 分頁查詢
     * @return
     */
    public abstract RtnData queryPageList(int pageSize, int pageIndex, Map<String,Object> params);

    /**
     * 多條件查詢
     * @return
     */
    public abstract RtnData queryList(Map<String,Object> params);

}

2酵颁、實現(xiàn)泛型父類BaseController嫉你,繼承 AbstractController
這里我們定義泛型父類BaseController,繼承并實現(xiàn)AbstractController方法躏惋,并且在BaseController中定義每個方法的RequestMapping幽污。這樣業(yè)務類直接繼承BaseController就可以使用默認實現(xiàn)好的增刪改查接口了。

public class BaseController<T, K> extends AbstractController<T, K> {

    @Autowired
    private IService<T, K> service;

    @PostMapping("/insert")
    @Override
    public RtnData insert(@RequestBody T t) {
        return RtnData.ok(service.insert(t));
    }

    @PostMapping("/update")
    @Override
    public RtnData update(@RequestBody T t) {
        return RtnData.ok(service.update(t));
    }

    @GetMapping("/delete")
    @Override
    public RtnData delete(K id) {
        return RtnData.ok(service.delete(id));
    }

    @GetMapping("/get")
    @Override
    public RtnData get(K id) {
        return RtnData.ok(service.get(id));
    }

    @GetMapping("/page-list")
    @Override
    public RtnData queryPageList(@RequestParam(required = false, defaultValue = "20") int pageSize,
                                 @RequestParam(required = false, defaultValue = "1") int pageIndex,
                                 @RequestParam Map<String,Object> params) {
        return RtnData.ok(service.queryPageList(pageSize, pageIndex, params));
    }

    @GetMapping("/list")
    @Override
    public RtnData queryList(@RequestParam Map<String, Object> params) {
        return RtnData.ok(service.queryList(params));
    }
}

BaseController注入了泛型IService簿姨,用于實現(xiàn)具體的業(yè)務操作

3距误、聲明泛型業(yè)務接口類IService

public interface IService<T,K>{

    /**
     * 新增
     * @param t
     * @return
     */
    public Object insert(T t);

    /**
     * 修改
     * @param t
     * @return
     */
    public Object update(T t);

    /**
     * 刪除
     * @param
     * @return
     */
    public Object delete(K id);

    /**
     * 按主鍵查詢
     * @param
     * @return
     */
    public T get(K id);

    /**
     * 分頁查詢
     * @param pageSize
     * @param pageIndex
     * @param params
     * @return
     */
    Object queryPageList(int pageSize, int pageIndex, Map<String, Object> params);

    /**
     * 條件查詢
     * @param params
     * @return
     */
    Object queryList(Map<String, Object> params);
}

4、定義泛型業(yè)務類BaseService扁位,實現(xiàn)IService類
BaseService實現(xiàn)IService接口中發(fā)方法准潭,編寫增刪改查操作默認業(yè)務實現(xiàn)。子類通過繼承BaseService就擁有它的方法域仇。

public class BaseService<T,K> implements IService<T,K> {

    @Autowired
    protected Mapper<T, K> mapper;

    private Class<T> modelClass;//當前泛型的真實類型Class

    public BaseService() {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    @Override
    public Object insert(T t) {
        return mapper.insert(t);
    }

    @Override
    public Object update(T t) {
        return mapper.updateByPrimaryKey(t);
    }

    @Override
    public Object delete(K id) {
        return mapper.deleteByPrimaryKey(id);
    }

    @Override
    public T get(K id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public Object queryPageList(int pageSize, int pageIndex, Map<String, Object> params) {
        PageHelper.startPage(pageIndex, pageSize);
        Page page = mapper.queryPageList(params);//Page本身是一個ArrayList對象刑然,轉(zhuǎn)換為json時不會保留分頁信息
        PageInfo pageInfo = page.toPageInfo();//將page轉(zhuǎn)換成pageInfo會保存分頁信息返回
        return new PageModel(pageInfo);
    }

    @Override
    public Object queryList(Map<String, Object> params) {
        return mapper.queryList(params);
    }

}

這里最重要的兩行代碼:
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
modelClass = (Class<T>) pt.getActualTypeArguments()[0];
通過泛型反射,獲取子類中實際要操作的對象class暇务,通過class泼掠,service就知道要對哪個對象進行增刪改查操操作。
另外垦细,我們注入了dao層的泛型Mapper<T, K>择镇,通過Mybatis對數(shù)據(jù)庫進行增刪改查操作

5、聲明Dao層泛型Mapper

public interface Mapper<T, K> {

    int deleteByPrimaryKey(K id);

    int insert(T record);

    int insertSelective(T record);

    T selectByPrimaryKey(K id);

    int updateByPrimaryKeySelective(T record);

    int updateByPrimaryKey(T record);

    /**
     * 分頁查詢(由子類實現(xiàn))
     * @param params
     * @return
     */
    Page queryPageList(Map<String, Object> params);

    /**
     * 多條件查詢(由子類實現(xiàn))
     * @param params
     * @return
     */
    List<Map<String,Object>> queryList(Map<String, Object> params);
}

這里我們使用mybatis實現(xiàn)dao層的操作括改,這里的聲明的接口方法名稱與mybatis工具生成mapper.xml一致

到這里腻豌,我們的泛型父類代碼已經(jīng)全部編寫完成。可以將上述代碼達成jar包饲梭,放入項目里面作為基礎包直接引用乘盖。
下面我們來說說怎么在項目里面實際使用。

二憔涉、項目應用
在項目里面引用订框,只需在子類代碼層中繼承上述父類,子類就擁有父類中的功能兜叨。

1穿扳、子類Controller

@RestController
@RequestMapping("/api/dic")
public class DataDicController extends BaseController<DataDic, Integer> {
}

看到?jīng)],里面什么方法也沒寫国旷,只聲明了RequestMapping矛物,另外將泛型用具體對象類型替換。
DataDic是我操作的對象跪但,Integer是DataDic的主鍵類型履羞。
這個BaseController的新增接口地址是/api/dic/insert,/insert是使用父類的RequestMapping屡久。
另外我也沒寫Service的注入忆首,因為容器會根據(jù)要父類中要注入的泛型Service,直接找到IService對應的泛型實例

2被环、子類Service

@Service
public class DataDicService extends BaseService<DataDic, Integer> {
}

同樣糙及,Service也沒有任何代碼,也沒有注入Mapper筛欢,只繼承了泛型

3浸锨、子類Mapper

@Mapper
public interface DataDicMapper extends com.cc.app.base.dao.Mapper<DataDic, Integer> {
}

Mapper需要繼承我們自己定義的泛型Mapper,這樣才能被Service找到版姑。
說明:我們通過工具生成的Mapper對象會包含默認的方法柱搜,大家不用刪除,因為和繼承的Mapper方法名一致漠酿,就當是覆蓋Override

到此冯凹,所有工作結(jié)束,我們的DataDicController的增刪改查接口寫好 炒嘲,下面我們來測試宇姚。

三、接口測試

1夫凸、查詢接口get


image.png

2浑劳、插入接口insert


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市夭拌,隨后出現(xiàn)的幾起案子魔熏,更是在濱河造成了極大的恐慌衷咽,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒜绽,死亡現(xiàn)場離奇詭異镶骗,居然都是意外死亡,警方通過查閱死者的電腦和手機躲雅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門鼎姊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人相赁,你說我怎么就攤上這事相寇。” “怎么了钮科?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵唤衫,是天一觀的道長。 經(jīng)常有香客問我绵脯,道長佳励,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任蛆挫,我火速辦了婚禮植兰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘璃吧。我一直安慰自己,他們只是感情好废境,可當我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布畜挨。 她就那樣靜靜地躺著,像睡著了一般噩凹。 火紅的嫁衣襯著肌膚如雪巴元。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天驮宴,我揣著相機與錄音逮刨,去河邊找鬼。 笑死堵泽,一個胖子當著我的面吹牛修己,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播迎罗,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼睬愤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了纹安?” 一聲冷哼從身側(cè)響起尤辱,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤砂豌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后光督,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阳距,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年结借,在試婚紗的時候發(fā)現(xiàn)自己被綠了筐摘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡映跟,死狀恐怖蓄拣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情努隙,我是刑警寧澤球恤,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站荸镊,受9級特大地震影響咽斧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躬存,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一张惹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岭洲,春花似錦宛逗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至告私,卻和暖如春屎暇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背驻粟。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工根悼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜀撑。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓挤巡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親屯掖。 傳聞我的和親對象是個殘疾皇子玄柏,可洞房花燭夜當晚...
    茶點故事閱讀 45,446評論 2 359

推薦閱讀更多精彩內(nèi)容