springmvc+mybatis如何分層


  通常情況下,我們之間調用mapper,spring會為我們注入其實現,很方便,mybatis也提供了一個generator供我們生成bean、dao接口等。但是總有一種感覺叫不爽,感覺除了bean和mapping.xml之外,dao接口有着共性,沒有必要每一個都寫一遍,共性的東東要提出來。下面就說一下怎么利用面向接口的思想進行提煉!

1、bean接口IModel

package com.jdw.bean;

/**
 * 所有的bean都要implements該接口
 * 至於原因,且往后看!
 * @author Administrator
 *
 */
public interface IModel {

}
View Code

2、實現IModel接口的Category

package com.jdw.bean;
/**
 * 實現了IModel接口的Category Bean
 * @author Administrator
 *
 */
public class Category implements IModel {

    private Integer cId;

    private String cName;

    private Boolean hot;

    public Integer getCId() {
        return cId;
    }

    public void setCId(Integer cId) {
        this.cId = cId;
    }

    public String getCName() {
        return cName;
    }

    public void setCName(String cName) {
        this.cName = cName == null ? null : cName.trim();
    }

    public Boolean getHot() {
        return hot;
    }

    public void setHot(Boolean hot) {
        this.hot = hot;
    }

    @Override
    public String toString() {
        return "Category [cId=" + cId + ", cName=" + cName + ", hot=" + hot + "]";
    }

}
View Code

3、dao接口的接口IMapper

package com.jdw.dao;

import com.jdw.bean.IModel;

/**
 * mybatis mapper都要extends該接口
 * @author Administrator
 *
 * @param <M>
 */
public interface IMapper<M extends IModel>{

    int deleteByPrimaryKey(Integer id);

    int insert(M model);

    int insertSelective(M model);

    M selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(M model);

    int updateByPrimaryKey(M model);
}
View Code

4、繼承了IMapper接口的Category接口

package com.jdw.dao;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

import com.jdw.bean.Category;

/**
 * 繼承了IMapper接口的CategoryMapper接口
 * 可以看出,現在只需要在這里面寫特有的接口了,共性的接口放到IMapper里面了
 * @author Administrator
 *
 */
public interface CategoryMapper extends IMapper<Category> {
    public List<Category> selectCategoryByType(@Param("type") String type);

    public void deleteByIds(String ids);

    public List<Category> selectCategoryByPage(Map<String, Object> map);
}
View Code

5、CategoryMapping.xml不需要什么改動

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.jdw.dao.CategoryMapper">
    <resultMap id="BaseResultMap" type="com.jdw.bean.Category">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        <id column="c_id" property="cId" jdbcType="INTEGER" />
        <result column="c_name" property="cName" jdbcType="VARCHAR" />
        <result column="hot" property="hot" jdbcType="BIT" />
    </resultMap>
    <sql id="Base_Column_List">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        c_id, c_name, hot
    </sql>
    <select id="selectByPrimaryKey" resultMap="BaseResultMap"
        parameterType="java.lang.Integer">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        select
        <include refid="Base_Column_List" />
        from category
        where c_id = #{cId,jdbcType=INTEGER}
    </select>
    <select id="selectCategoryByType" resultMap="BaseResultMap"
        parameterType="java.lang.String">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        select
        <include refid="Base_Column_List" />
        from category
        where 1 = 1
        <if test="type != null and type !=''">
            AND c_name = #{type,jdbcType=VARCHAR}
        </if>
        ORDER BY c_id
    </select>
    <select id="selectCategoryByPage" resultMap="BaseResultMap"
        parameterType="java.util.Map">

        select
        <include refid="Base_Column_List" />
        from category
        where 1 = 1
        <if test="type != null and type !=''">
            AND c_name = #{type,jdbcType=VARCHAR}
        </if>
        ORDER BY c_id
        limit #{pageIndex},#{pageSize}
    </select>
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        delete from category
        where c_id = #{cId,jdbcType=INTEGER}
    </delete>
    <insert id="insert" parameterType="com.jdw.bean.Category">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        insert into category (c_id, c_name, hot)
        values (#{cId,jdbcType=INTEGER}, #{cName,jdbcType=VARCHAR},
        #{hot,jdbcType=BIT})
    </insert>
    <insert id="insertSelective" parameterType="com.jdw.bean.Category">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        insert into category
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="cId != null">
                c_id,
            </if>
            <if test="cName != null">
                c_name,
            </if>
            <if test="hot != null">
                hot,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="cId != null">
                #{cId,jdbcType=INTEGER},
            </if>
            <if test="cName != null">
                #{cName,jdbcType=VARCHAR},
            </if>
            <if test="hot != null">
                #{hot,jdbcType=BIT},
            </if>
        </trim>
    </insert>
    <update id="updateByPrimaryKeySelective" parameterType="com.jdw.bean.Category">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        update category
        <set>
            <if test="cName != null">
                c_name = #{cName,jdbcType=VARCHAR},
            </if>
            <if test="hot != null">
                hot = #{hot,jdbcType=BIT},
            </if>
        </set>
        where c_id = #{cId,jdbcType=INTEGER}
    </update>
    <update id="updateByPrimaryKey" parameterType="com.jdw.bean.Category">
        <!-- WARNING - @mbggenerated This element is automatically generated by 
            MyBatis Generator, do not modify. -->
        update category
        set c_name = #{cName,jdbcType=VARCHAR},
        hot = #{hot,jdbcType=BIT}
        where c_id = #{cId,jdbcType=INTEGER}
    </update>
</mapper>
View Code

6、來點猛料,實現IMapper接口的BaseDaoImpl,注意看其中的T,spring可以Autowired泛型T,這個很巧妙!

package com.jdw.dao.impl;

import org.springframework.beans.factory.annotation.Autowired;

import com.jdw.bean.IModel;
import com.jdw.dao.IMapper;

/**
 * 面向接口+泛型的威力初體驗
 * 
 * @author Administrator
 *
 * @param <T>
 * @param <M>
 */
public class BaseDaoImpl<T extends IMapper<M>,M extends IModel> implements IMapper<M> {

    @Autowired
    protected T t;

    @Override
    public int deleteByPrimaryKey(Integer id) {
        int result = this.t.deleteByPrimaryKey(id);
        return result;
    }

    @Override
    public int insert(M model) {
        int result = this.t.insert(model);
        return result;
    }

    @Override
    public int insertSelective(M model) {
        int result = this.t.insertSelective(model);
        return result;
    }

    @Override
    public M selectByPrimaryKey(Integer id) {
        M m=this.t.selectByPrimaryKey(id);
        return m;
    }

    @Override
    public int updateByPrimaryKeySelective(M model) {
        int result=this.t.updateByPrimaryKeySelective(model);
        return result;
    }

    @Override
    public int updateByPrimaryKey(M model) {
        int result=this.t.updateByPrimaryKey(model);
        return result;
    }

}
View Code

7、繼承了BaseDaoImpl的CategoryDaoImpl,注意少了很多共性代碼,只有特性接口的實現,連spring mapper注入都省了!

package com.jdw.dao.impl;

import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.jdw.bean.Category;
import com.jdw.dao.CategoryMapper;
/**
 * 繼承了BaseDaoImpl的CategoryImpl
 * 注意:
 * (1)這里只需要實現特有的接口方法
 * (2)注意這里的mybatis mapper是根據泛型從BaseDaoImpl繼承而來的
 * @author Administrator
 *
 */
@Repository(value = "categoryDao")
public class CategoryDaoImpl extends BaseDaoImpl<CategoryMapper, Category> implements CategoryMapper {

    @Override
    public List<Category> selectCategoryByType(String type) {
        List<Category> list = this.t.selectCategoryByType(type);
        return list;
    }

    @Override
    public void deleteByIds(String ids) {
    
    }

    @Override
    public List<Category> selectCategoryByPage(Map<String, Object> map) {
        List<Category> list = this.t.selectCategoryByPage(map);
        return list;
    }

}
View Code

8、BaseService接口

package com.jdw.service;

import com.jdw.bean.IModel;
import com.jdw.dao.IMapper;
import com.jdw.dao.impl.BaseDaoImpl;

/**
 * 共性的泛型化的Service接口
 * @author Administrator
 *
 * @param <M>
 * @param <T>
 * @param <D>
 */
public interface BaseService<M extends IModel,T extends IMapper<M>, D extends BaseDaoImpl<T,M>> {
    int insert(M model);

    int insertSelective(M model);

    int updateByPrimaryKeySelective(M model);

    int updateByPrimaryKey(M model);

    int deleteByPrimaryKey(int id);

    M selectByPrimaryKey(int id);
}
View Code

9、繼承了BaseService接口的CategoryService接口

package com.jdw.service;

import java.util.List;
import java.util.Map;

import com.jdw.bean.Category;
import com.jdw.dao.CategoryMapper;
import com.jdw.dao.impl.CategoryDaoImpl;

/**
 * 繼承了BaseService接口的CategoryService接口
 * @author Administrator
 *
 */
public interface CategoryService extends BaseService<Category,CategoryMapper,CategoryDaoImpl> {
    public Map<String,Object> query(String type, Integer page, Integer size);
    public void deleteByIds(String ids);
    public List<Category> getAll(Map<String,Object> map);
}
View Code

10、BaseServiceImpl

package com.jdw.service.impl;

import org.springframework.beans.factory.annotation.Autowired;

import com.jdw.bean.IModel;
import com.jdw.dao.IMapper;
import com.jdw.dao.impl.BaseDaoImpl;
import com.jdw.service.BaseService;

/**
 * 泛型化的共性service實現
 * @author Administrator
 *
 * @param <M>
 * @param <T>
 * @param <D>
 */
public class BaseServiceImpl<M extends IModel,T extends IMapper<M>, D extends BaseDaoImpl<T,M>> implements BaseService<M, T, D> {

    @Autowired
    protected D dao;
    
    @Override
    public int insert(M model) {
        int result=dao.insert(model);
        return result;
    }

    @Override
    public int insertSelective(M model) {
        int result=dao.insertSelective(model);
        return result;
    }

    @Override
    public int updateByPrimaryKeySelective(M model) {
        int result=dao.updateByPrimaryKeySelective(model);
        return result;
    }

    @Override
    public int updateByPrimaryKey(M model) {
        int result=dao.updateByPrimaryKey(model);
        return result;
    }

    @Override
    public int deleteByPrimaryKey(int id) {
        int result=dao.deleteByPrimaryKey(id);
        return result;
    }

    @Override
    public M selectByPrimaryKey(int id) {
        M model=dao.selectByPrimaryKey(id);
        return model;
    }

}
View Code

11、CategoryServiceImpl,原理同7,不再贅述

package com.jdw.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jdw.bean.Category;
import com.jdw.dao.CategoryMapper;
import com.jdw.dao.impl.CategoryDaoImpl;
import com.jdw.service.CategoryService;

@Service("categoryService")
public class CategoryServicImpl extends BaseServiceImpl<Category, CategoryMapper, CategoryDaoImpl>
        implements CategoryService {

    @Override
    public void deleteByIds(String ids) {

    }

    @Override
    public Map<String, Object> query(String type, Integer pageNo, Integer pageSize) {
        pageNo = pageNo == null ? 1 : pageNo;
        pageSize = pageSize == null ? 10 : pageSize;
        PageHelper.startPage(pageNo, pageSize);
        List<Category> list = this.dao.selectCategoryByType(type);
        for (Category c : list) {
            System.out.println(c);
        }
        // 用PageInfo對結果進行包裝
        PageInfo<Category> page = new PageInfo<Category>(list);

        // 測試PageInfo全部屬性
        /*
         * System.out.println(page.getPageNum());
         * System.out.println(page.getPageSize());
         * System.out.println(page.getStartRow());
         * System.out.println(page.getEndRow());
         * System.out.println(page.getTotal());
         * System.out.println(page.getPages());
         * System.out.println(page.getFirstPage());
         * System.out.println(page.getLastPage());
         * System.out.println(page.isHasPreviousPage());
         * System.out.println(page.isHasNextPage());
         */
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("total", page.getTotal());
        map.put("rows", page.getList());
        return map;
    }

    @Override
    public List<Category> getAll(Map<String, Object> map) {

        return this.dao.selectCategoryByPage(map);
    }

}
View Code

12、總結說明

  有的人覺的這么寫好麻煩啊,又是接口,又是泛型,還是基類的。他們覺得直接Service里面用mapper就行了,又簡單又方便,想用哪個mapper就注入哪個mapper。想法有多好,耦合就有多高!

  面向接口會讓各模塊之間的耦合程度很低,比如哪天你不想用mybatis了,只需要修改dao層的實現就可以了,service層不需要動!如果你service里有mybatis注入代碼呢?如果service沒有接口的話,controller估計也要改了,跟重做沒有什么區別,也許更麻煩,面向接口讓代碼更規范,重用度更高。一句話,面向接口是各種設計模式的基礎。

  泛型讓代碼更簡練,讓共性成為共性,讓特性更加特性,一目了然!

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM