mybatis03-mybatis 關(guān)系映射萨咕,緩存機(jī)制, spring 與 mybatis 的整合,分頁(yè)插件配置-G07

Mybatis-03

(mybatis 關(guān)系映射丑孩,緩存機(jī)制, spring 與 mybatis 的整合,分頁(yè)插件配置)

一泳炉、 映射關(guān)系的問(wèn)題

1.數(shù)據(jù)庫(kù)的分類(lèi)(2類(lèi))

1.1關(guān)系型數(shù)據(jù)庫(kù): Mysql Oracle

表與表之前的關(guān)系:

(1) 1 VS 1 主外鍵

(2) 1 VS 多 使用中間表

(3) 多 VS 多 拆成兩個(gè)1對(duì)多,再使用中間表

(4)

1.2非關(guān)系型數(shù)據(jù)庫(kù): Redis MongoDB...

特征就是: key - value 存儲(chǔ)


#

2.一對(duì)一關(guān)系

實(shí)現(xiàn)方式 resultType/resultMap

注意: VO(value object)

DTO(data transfer object)
數(shù)據(jù)傳輸對(duì)象,主要用于遠(yuǎn)程調(diào)用等需要大量傳輸對(duì)象的地方.一般接受多表聯(lián)查結(jié)果.

image.png

2.1--1對(duì)1關(guān)聯(lián)查詢(xún),1個(gè)user對(duì)應(yīng)1個(gè)card
1)UserMapper.xml中配置,利用resultMap方式實(shí)現(xiàn)

<!--    測(cè)試一對(duì)一關(guān)聯(lián)查詢(xún)r(jià)esultMap方式實(shí)現(xiàn)-->
   <resultMap id="user_card" type="userDto" >
       <!--映射user對(duì)象-->
       <association property="user" javaType="user">
       <id column="id" property="id"></id>      <!-- 唯一標(biāo)識(shí)用戶(hù)記錄字段 -->
       <result column="user_name" property="userName"></result>         <!-- 普通字段信息配置標(biāo)簽 -->
       <result column="user_pwd" property="userPwd"></result>
       <result column="real_name" property="realName"></result>
       <result column="nation" property="nation"></result>
       <result column="card_id" property="cardId"></result>
       </association>

       <!--映射card對(duì)象-->
       <association property="card" javaType="card">
           <id column="cid" property="id"></id>
            <result column="card_num" property="cardNum"></result>

       </association>
   </resultMap>

<select id="queryUserCard" resultMap="user_card">
    SELECT
        u.id,
        u.user_name,
        u.user_pwd,
        u.real_name,
        u.nation,
        u.card_id,
        c.id as cid,
        c.card_num
        FROM
        `user` AS u
        LEFT JOIN card AS c ON c.id = u.card_id
</select>


2)userMapper中添加方法

public interface UserMapper {

/*
    1對(duì)1關(guān)系映射
 */
    public List<UserDto> queryUserCard();


3)mybatis中加包掃描

<typeAliases>
    <!-- 定義別名 -->
    <!--<typeAlias alias="user" tyUserUser"></typeAlias>-->
    <!-- 包掃描 -->
    <package name="com.shsxt.po"/>
    <package name="com.shsxt.dto"/>
</typeAliases>


4)Mybatis中加測(cè)試方法

public class MyBatisTest {

    UserMapper userMapper;

    @Before
    public void init() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
        SqlSession session = build.openSession();
        userMapper = session.getMapper(UserMapper.class);
    }
/*
    測(cè)試1對(duì)1映射關(guān)系
 */
    @Test
    public void queryUserCard() {
        List<UserDto> userDtoList = userMapper.queryUserCard();
        userDtoList.stream().forEach(System.out::println);
    }


測(cè)試一對(duì)一查詢(xún)結(jié)果

image.png

3.一對(duì)多關(guān)系
實(shí)現(xiàn)方式:resultMap 實(shí)現(xiàn)
resultType 有局限,無(wú)法去重嚎杨,需手動(dòng)處理。

模擬一對(duì)多操作

1)UserMapper.xml配置 resultMap繼承上例

<!--測(cè)試一對(duì)多關(guān)聯(lián)查詢(xún)-->
    <resultMap id="user_card_account" type="userDto" extends="user_card">  <!-- 繼承上面的reusltMap-->
        <collection property="accounts" ofType="account">
            <id column="aid" property="id"></id>
            <result column="aname" property="aname"></result>
            <result column="type" property="type"></result>
            <result column="money" property="money"></result>
            <result column="user_id" property="userId"></result>
            <result column="create_time" property="createTime"></result>
            <result column="update_time" property="updateTime"></result>
        </collection>
    </resultMap>
    <!-- 1 vs 多  一個(gè)用戶(hù)user關(guān)聯(lián)多個(gè)account賬號(hào)-->
    <select id="queryUserCardAccount" resultMap="user_card_account">
        SELECT
        u.id,
        u.user_name,
        u.user_pwd,
        u.real_name,
        u.nation,
        u.card_id,
        c.id AS cid,
        c.card_num,
        a.id AS aid,
        a.aname,
        a.type,
        a.money,
        a.user_id,
        a.create_time,
        a.update_time,
        a.remark
        FROM
        `user` AS u
        LEFT JOIN card AS c ON c.id = u.card_id
        LEFT JOIN account AS a ON a.user_id = u.id

    </select>


2)UseMapper中添加一對(duì)多關(guān)聯(lián)查詢(xún)方法

public interface UserMapper {

  /*  一對(duì)多關(guān)聯(lián)查詢(xún)
 */
  public List<UserDto> queryUserCardAccount();


3)PO中UserDto中存儲(chǔ)查詢(xún)信息

注意一對(duì)多查詢(xún)時(shí),不能使用user對(duì)象,因?yàn)閚ew兩個(gè)不同user,引用地址不一致,會(huì)造成結(jié)果無(wú)法去重.

image.png
**
 * 接收多表聯(lián)查的結(jié)果(注意一對(duì)多查詢(xún)時(shí),不能使用user對(duì)象,因?yàn)閚ew兩個(gè)不同user,引用地址不一致)
 */
public class UserDto {

    private Integer id;
    private String userName;
    private String userPwd;
    private String realName;
    private String nation;
    private Integer cardId;

    private User user;//代表user對(duì)象

    private Integer cid;
    private Integer cardNum;

    private Card card;//代表card對(duì)象

    private List<Account> accounts; //多個(gè)賬戶(hù)


    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Card getCard() {
        return card;
    }

    public void setCard(Card card) {
        this.card = card;
    }

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }

    @Override
    public String toString() {
        return "UserDto{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", userPwd='" + userPwd + '\'' +
                ", realName='" + realName + '\'' +
                ", nation='" + nation + '\'' +
                ", cardId=" + cardId +
                ", user=" + user +
                ", cid=" + cid +
                ", cardNum=" + cardNum +
                ", card=" + card +
                ", accounts=" + accounts +
                '}';
    }
}



4)mybatisTest測(cè)試類(lèi)

public class MyBatisTest {

    UserMapper userMapper;
    AccountDao accountDao;

    @Before
    public void init() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
        SqlSession session = build.openSession();
        userMapper = session.getMapper(UserMapper.class);
        accountDao =session.getMapper(AccountDao.class);
    }

    /*
        測(cè)試一對(duì)多關(guān)聯(lián)查詢(xún)
     */

    @Test
    public void queryUserCardAccount() {
        List<UserDto> userDtoList = userMapper.queryUserCardAccount();
        userDtoList.stream().forEach(System.out::println);
    }



測(cè)試一對(duì)多查詢(xún)結(jié)果

image.png

二氧腰、 Mybatis 緩存
正如大多數(shù)持久層框架一樣枫浙,MyBatis
同樣提供了一級(jí)緩存和二級(jí)緩存的支持;
一級(jí)緩存
基于 PerpetualCache 的 HashMap 本地緩存(mybatis 內(nèi)部實(shí)現(xiàn) cache
接口)古拴,
其存儲(chǔ)作用域?yàn)?Session箩帚,當(dāng) Session flush 或 close 之后,該 Session
中的所有 Cache
就將清空黄痪;
二級(jí)緩存
一級(jí)緩存其機(jī)制相同紧帕,默認(rèn)也是采用 PerpetualCache 的 HashMap 存儲(chǔ),不同在
于其存儲(chǔ)作用域?yàn)?Mapper(Namespace)桅打,并且可自定義存儲(chǔ)源是嗜,如 Ehcache;
對(duì)于緩存數(shù)據(jù)更新機(jī)制挺尾,當(dāng)某一個(gè)作用域(一級(jí)緩存 Session/二級(jí)緩存
Namespaces)的進(jìn)行了 C/U/D 操作后鹅搪,默認(rèn)該作用域下所有 select 中的緩存將被
clear。
如果二緩存開(kāi)啟遭铺,首先從二級(jí)緩存查詢(xún)數(shù)據(jù)丽柿,如果二級(jí)緩存有則從二級(jí)緩存中獲取數(shù)據(jù),
如果二級(jí)緩存沒(méi)有魂挂,從一級(jí)緩存找是否有緩存數(shù)據(jù)甫题,如果一級(jí)緩存沒(méi)有,查詢(xún)數(shù)據(jù)庫(kù)
涂召。

二級(jí)緩存局限性

mybatis
二級(jí)緩存對(duì)細(xì)粒度的數(shù)據(jù)級(jí)別的緩存實(shí)現(xiàn)不好坠非,對(duì)同時(shí)緩存較多條數(shù)據(jù)的緩
存,比如如下需求:對(duì)商品信息進(jìn)行緩存芹扭,由于商品信息查詢(xún)?cè)L問(wèn)量大麻顶,但是要求用
戶(hù)每次都能查詢(xún)最新的商品信息赦抖,此時(shí)如果使用 mybatis
的二級(jí)緩存就無(wú)法實(shí)現(xiàn)當(dāng)一
個(gè)商品變化時(shí)只刷新該商品的緩存信息而不刷新其它商品的信息,因?yàn)?mybaits
的二
級(jí)緩存區(qū)域以 mapper
為單位劃分辅肾,當(dāng)一個(gè)商品信息變化會(huì)將所有商品信息的緩存數(shù)
據(jù)全部清空.

1.一級(jí)緩存
Mybatis 默認(rèn)提供一級(jí)緩存队萤,緩存范圍是一個(gè) sqlSession。在同一個(gè)
SqlSession
中矫钓,兩次執(zhí)行相同的 sql 查詢(xún)要尔,第二次不再?gòu)臄?shù)據(jù)庫(kù)查詢(xún)。
原理:一級(jí)緩存采用 Hashmap 存儲(chǔ)新娜,mybatis
執(zhí)行查詢(xún)時(shí)赵辕,從緩存中查詢(xún),如果緩存中沒(méi)有從數(shù)據(jù)庫(kù)查詢(xún)概龄。如果該
**SqlSession 執(zhí)行 clearCache()提交 或者增加 刪除 修改操作还惠,
清除緩存。
**
a.緩存存在情況 (session 未提交)

1)創(chuàng)建MyBatisCacheTest.java類(lèi)

image.png

只有一次查詢(xún)

image.png

b.刷新緩存
Session 提交 此時(shí)緩存數(shù)據(jù)被刷新

1)session.clearCahe(),清空緩存,兩條sql.兩次查詢(xún)

2)在做增,刪,改時(shí),會(huì)清除緩存,保證查詢(xún)的數(shù)據(jù)與數(shù)據(jù)庫(kù)一致.

3)測(cè)試,在UserMapper.xml中插入一條sql語(yǔ)句


<insert id="addUser" parameterType="user">
INSERT into user (`user_name`, `user_pwd`) VALUES (#{userName}, #{userPwd})
</insert>


4)UserMapper中加方法

public List<UserDto> queryUserCardAccount();

5)MyBatisCacheTest中測(cè)試查詢(xún)添加查詢(xún)

public class MyBatisCacheTest {

    UserMapper userMapper;
    SqlSession session;
    @Before
    public void init() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
        session = build.openSession();
        userMapper = session.getMapper(UserMapper.class);
    }


    @Test
    public void queryUserByUserName() {
        User user = new User();
        List<User> userList = userMapper.queryUserByUserName(user);
       //session.clearCache();// 清空緩存

        user.setUserName("abc");
        user.setUserPwd("abc123456");
        userMapper.addUser(user);

        List<User> userList2 = userMapper.queryUserByUserName(user);
        List<User> userList3 = userMapper.queryUserByUserName(user);
    }
}

image.png

2.二級(jí)緩存
一級(jí)緩存是在同一個(gè) sqlSession 中私杜,二級(jí)緩存是在同一個(gè) namespace
中蚕键,因此相
同的 namespace 不同的 sqlsession 可以使用二級(jí)緩存。
使用場(chǎng)景
? 1衰粹、 對(duì)查詢(xún)頻率高锣光, 變化頻率低的數(shù)據(jù)建議使用二級(jí)緩存。
? 2铝耻、 對(duì)于訪(fǎng)問(wèn)多的查詢(xún)請(qǐng)求且用戶(hù)對(duì)查詢(xún)結(jié)果實(shí)時(shí)性要求不高誊爹, 此時(shí)可采用
mybatis 二級(jí)緩存技術(shù)降低數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)量, 提高訪(fǎng)問(wèn)速度瓢捉, 業(yè)務(wù)場(chǎng)景比
如: 耗時(shí)較高的統(tǒng)計(jì)分析 sql频丘、 電話(huà)賬單查詢(xún) sql 等。

注:

cache 標(biāo)簽常用屬性

<cache
eviction="FIFO" <!--回收策略為先進(jìn)先出-->
flushInterval="60000" <!--自動(dòng)刷新時(shí)間 60s-->
size="512" <!--最多緩存 512 個(gè)引用對(duì)象-->
readOnly="true"/> <!--只讀-->

說(shuō)明:\

  1. 映射語(yǔ)句文件中的所有 select 語(yǔ)句將會(huì)被緩存泡态。\
  2. 映射語(yǔ)句文件中的所有 insert椎镣,update 和 delete 語(yǔ)句會(huì)刷新緩存。\
  3. 緩存會(huì)使用 Least Recently Used(LRU兽赁,最近最少使用的)算法來(lái)收回状答。\
  4. 緩存會(huì)根據(jù)指定的時(shí)間間隔來(lái)刷新.\
  5. 緩存會(huì)存儲(chǔ) 1024 個(gè)對(duì)象

1)全局文件配置mybatis.xml中加配置


    <properties resource="db.properties"></properties>

    <!-- 開(kāi)啟緩存 -->
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>


2)UserMapper.xml中開(kāi)啟改mapper的二級(jí)緩存


    <!-- 開(kāi)啟該mapper的二級(jí)緩存 -->
  <cache/>


3)PO對(duì)象必須支持序列號(hào)

public class Account implements Serializable {

    private static final long serialVersionUID = 1L;


刷新二級(jí)緩存
操作 CUD 的 statement 時(shí)候, 會(huì)強(qiáng)制刷新二級(jí)緩存 即默認(rèn)
flushCache="true" 刀崖, 如果想關(guān)閉設(shè)定為 flushCache="false"即可 惊科,
不建議關(guān)閉刷新, 因?yàn)椴僮鞲聞h除修改亮钦, 關(guān)閉后容易獲取臟數(shù)據(jù)馆截。
4)二級(jí)緩存測(cè)試:

@Test
public void test03() {
SqlSession sqlSession=sqlSessionFactory.openSession();
AccountDao accountDao=sqlSession.getMapper(AccountDao.class);
Account account=accountDao.queryAccountById(1);
System.out.println(account);
sqlSession.close();
SqlSession sqlSession2=sqlSessionFactory.openSession();
AccountDao accountDao2=sqlSession2.getMapper(AccountDao.class);
accountDao2.queryAccountById(1);
sqlSession.close();
}

image.png

3.分布式緩存 ehcache
如果有多臺(tái)服務(wù)器 , 不使用分布緩存, 緩存的數(shù)據(jù)在各個(gè)服務(wù)器單獨(dú)存儲(chǔ)蜡娶,
不方便
系統(tǒng) 開(kāi)發(fā)混卵。 所以要使用分布式緩存對(duì)緩存數(shù)據(jù)進(jìn)行集中管理。

mybatis 本身來(lái)說(shuō)是無(wú)法實(shí)現(xiàn)分布式緩存的窖张,
所以要與分布式緩存框架進(jìn)行整合幕随。
EhCache 是一個(gè)純 Java 的進(jìn)程內(nèi)緩存框架, 具有快速宿接、 精干等特點(diǎn);Ehcache
是一種廣泛使用的開(kāi)源 Java 分布式緩存赘淮。 主要面向通用緩存,Java EE
和輕量級(jí)容器。 它具有內(nèi)存和磁盤(pán)存儲(chǔ)睦霎,
緩存加載器,緩存擴(kuò)展,緩存異常處理程序,一個(gè) gzip 緩存 servlet 過(guò)濾器,支持
REST 和 SOAP api 等特點(diǎn)梢卸。

3.1添加依賴(lài) pom.xml

<!--    使用分布式緩存依賴(lài)-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.12</version>
    </dependency>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache-core</artifactId>
      <version>2.4.4</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis.caches</groupId>
      <artifactId>mybatis-ehcache</artifactId>
      <version>1.0.3</version>
    </dependency>


3.2配置緩存接口

mybatis.xml中配置開(kāi)啟緩存

<!-- 開(kāi)啟緩存 -->
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>


UserMapper.xml中使用分布式緩存標(biāo)簽


<!-- 使用分布式緩存 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>


3.3在resources文件夾中新增ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="../bin/ehcache.xsd">
    <!--
    name:Cache的唯一標(biāo)識(shí)
    maxElementsInMemory:內(nèi)存中最大緩存對(duì)象數(shù)
    maxElementsOnDisk:磁盤(pán)中最大緩存對(duì)象數(shù),若是0表示無(wú)窮大
    eternal:Element是否永遠(yuǎn)不過(guò)期副女,如果為true蛤高,則緩存的數(shù)據(jù)始終有效,如果為false那么還要根據(jù)timeToIdleSeconds碑幅,timeToLiveSeconds判斷
    overflowToDisk:配置此屬性襟齿,當(dāng)內(nèi)存中Element數(shù)量達(dá)到maxElementsInMemory時(shí),Ehcache將會(huì)Element寫(xiě)到磁盤(pán)中
    timeToIdleSeconds:設(shè)置Element在失效前的允許閑置時(shí)間枕赵。僅當(dāng)element不是永久有效時(shí)使用,可選屬性位隶,默認(rèn)值是0拷窜,也就是可閑置時(shí)間無(wú)窮大
    timeToLiveSeconds:設(shè)置Element在失效前允許存活時(shí)間。最大時(shí)間介于創(chuàng)建時(shí)間和失效時(shí)間之間涧黄。僅當(dāng)element不是永久有效時(shí)使用篮昧,默認(rèn)是0.,也就是element存活時(shí)間無(wú)窮大
    diskPersistent:是否緩存虛擬機(jī)重啟期數(shù)據(jù)
    diskExpiryThreadIntervalSeconds:磁盤(pán)失效線(xiàn)程運(yùn)行時(shí)間間隔笋妥,默認(rèn)是120秒
    diskSpoolBufferSizeMB:這個(gè)參數(shù)設(shè)置DiskStore(磁盤(pán)緩存)的緩存區(qū)大小懊昨。默認(rèn)是30MB。每個(gè)Cache都應(yīng)該有自己的一個(gè)緩沖區(qū)
     memoryStoreEvictionPolicy:當(dāng)達(dá)到maxElementsInMemory限制時(shí)春宣,Ehcache將會(huì)根據(jù)指定的策略去清理內(nèi)存酵颁。默認(rèn)策略是LRU(最近最少使用)。你可以設(shè)置為FIFO(先進(jìn)先出)或是LFU(較少使用)
    -->
    <defaultCache overflowToDisk="true" eternal="false"/>
    <diskStore path="D:/cache" />
    <!--
        <cache name="sxtcache" overflowToDisk="true" eternal="false"
        timeToIdleSeconds="300" timeToLiveSeconds="600" maxElementsInMemory="1000"
        maxElementsOnDisk="10" diskPersistent="true" diskExpiryThreadIntervalSeconds="300"
        diskSpoolBufferSizeMB="100" memoryStoreEvictionPolicy="LRU" />
    -->
</ehcache>


3.4測(cè)試MyBatisCacheTest


@Test
public void queryUserCardAccount() throws IOException {
    userMapper.queryUserCardAccount();
    userMapper.queryUserCardAccount();
    session.close();

    session = build.openSession();
    userMapper = session.getMapper(UserMapper.class);
    userMapper.queryUserCardAccount();
}





3.4測(cè)試結(jié)果

image.png

三. Spring 與 Mybatis 集成
1新建 maven webapp 項(xiàng)目
新建 maven 項(xiàng)目 spring_mybatis
目錄結(jié)構(gòu)如下:
主目錄包:com.shsxt.dao月帝、com.shsxt.mapper躏惋、com.shsxt.service、
com.shsxt.service.impl
測(cè)試包:spring_mybatis

image.png

2引入依賴(lài)包
打開(kāi) pom.xml 開(kāi)始添加依賴(lài)包

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.shsxt</groupId>
  <artifactId>mybatis_spring_jc</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>mybatis_spring_jc</name>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <!-- spring 核心jar -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <!-- spring 測(cè)試jar -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <!-- spring jdbc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <!-- spring事物 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <!-- aspectj切面編程的jar -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.9</version>
    </dependency>


    <!-- c3p0 連接池 -->
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>

    <!-- mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.1</version>
    </dependency>

    <!-- 添加mybatis與Spring整合的核心包 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.0</version>
    </dependency>
    <!-- mysql 驅(qū)動(dòng)包 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.39</version>
    </dependency>

    <!-- 日志打印相關(guān)的jar -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.2</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.2</version>
    </dependency>

    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>4.1.0</version>
    </dependency>

  </dependencies>

  <build>
    <finalName>spring_mybatis</finalName>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
          <include>**/*.tld</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>
</project>

3配置資源文件
a) Spring 文件 spring.xml
b) Mybatis 文件 mybatis.xml
c) 數(shù)據(jù)庫(kù)連接 properties 文件 db.properties
d) 日志輸出文件 log4j.properties
1).spring.xml 文件配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- 掃描com.shsxt 及其所有子包下類(lèi) -->
    <context:component-scan base-package="com.shsxt" />
    <!-- 加載properties 配置文件 -->
    <context:property-placeholder location="classpath:db.properties" />
    <aop:aspectj-autoproxy /><!-- aop -->

    <!-- 配置數(shù)據(jù)源 -->
    <!-- 配置c3p0 數(shù)據(jù)源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!-- 配置事務(wù)管理器 -->
    <bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 設(shè)置事物增強(qiáng) -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" />
            <tx:method name="find*" read-only="true" />
            <tx:method name="query*" read-only="true" />
            <tx:method name="load*" read-only="true" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <!-- aop 切面配置 -->
    <aop:config>
        <aop:pointcut id="servicePointcut" expression="execution(* com.shsxt.service..*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/>
    </aop:config>

    <!-- 配置 sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis.xml" />
        <!--
                 自動(dòng)掃描com/shsxt/crm/mapper目錄下的所有SQL映射的xml文件, 省掉mybatis.xml里的手工配置
                value="classpath:com/shsxt/crm/mapper/*.xml"指的是classpath(類(lèi)路徑)下com.shsxt.crm.mapper包中的所有xml文件
                UserMapper.xml位于com.shsxt.crm.mapper包下嚷辅,這樣UserMapper.xml就可以被自動(dòng)掃描
                 -->
        <property name="mapperLocations" value="classpath:com/shsxt/mapper/*.xml" />
    </bean>

    <!-- 配置掃描器 -->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 掃描com.shsxt.dao這個(gè)包以及它的子包下的所有映射接口類(lèi) -->
        <property name="basePackage" value="com.shsxt.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
</beans>


2).mybatis.xml 文件配置

<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <!-- po 包掃描 -->
    <typeAliases>
        <package name="com.shsxt.po" />
    </typeAliases>

    <plugins>
        <!-- com.github.pagehelper為PageHelper類(lèi)所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql" />
            <!-- 該參數(shù)默認(rèn)為false -->
            <!-- 設(shè)置為true時(shí)簿姨,會(huì)將RowBounds第一個(gè)參數(shù)offset當(dāng)成pageNum頁(yè)碼使用 -->
            <!-- 和startPage中的pageNum效果一樣 -->
            <property name="offsetAsPageNum" value="true" />
            <!-- 該參數(shù)默認(rèn)為false -->
            <!-- 設(shè)置為true時(shí),使用RowBounds分頁(yè)會(huì)進(jìn)行count查詢(xún) -->
            <property name="rowBoundsWithCount" value="true" />
            <!-- 設(shè)置為true時(shí),如果pageSize=0或者RowBounds.limit = 0就會(huì)查詢(xún)出全部的結(jié)果 -->
            <!-- (相當(dāng)于沒(méi)有執(zhí)行分頁(yè)查詢(xún)扁位,但是返回結(jié)果仍然是Page類(lèi)型) -->
            <property name="pageSizeZero" value="true" />
            <!-- 3.3.0版本可用 - 分頁(yè)參數(shù)合理化准潭,默認(rèn)false禁用 -->
            <!-- 啟用合理化時(shí),如果pageNum<1會(huì)查詢(xún)第一頁(yè)域仇,如果pageNum>pages會(huì)查詢(xún)最后一頁(yè) -->
            <!-- 禁用合理化時(shí)刑然,如果pageNum<1或pageNum>pages會(huì)返回空數(shù)據(jù) -->
            <property name="reasonable" value="true" />
            <!-- 3.5.0版本可用 - 為了支持startPage(Object params)方法 -->
            <!-- 增加了一個(gè)`params`參數(shù)來(lái)配置參數(shù)映射,用于從Map或ServletRequest中取值 -->
            <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默認(rèn)值 -->
            <property name="params"
                      value="pageNum=start;pageSize=limit;pageSizeZero=zero;reasonable=heli;count=countsql" />
        </plugin>
    </plugins>

</configuration>

--------+

3).db.properties 文件配置(對(duì)于其它數(shù)據(jù)源屬性配置殉簸, 見(jiàn) c3p0
配置講解闰集, 這里采用默認(rèn)屬性配置)

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456


4).log4j.properties便于控制臺(tái)日志輸出

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n


4.開(kāi)始寫(xiě)實(shí)體類(lèi)PO---User類(lèi)

+----------------------------------------------------------+
package com.shsxt.po;

import java.io.Serializable;

/**
 * Created by xlf on 2019/3/4.
 */
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;
    private String userName;
    private String userPwd;
    private String realName;
    private String nation;
    private Integer cardId;

    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 getUserPwd() {
        return userPwd;
    }

    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }

    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    public String getNation() {
        return nation;
    }

    public void setNation(String nation) {
        this.nation = nation;
    }

    public Integer getCardId() {
        return cardId;
    }

    public void setCardId(Integer cardId) {
        this.cardId = cardId;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", userPwd='" + userPwd + '\'' +
                ", realName='" + realName + '\'' +
                ", nation='" + nation + '\'' +
                ", cardId=" + cardId +
                '}';
    }
}


5.接口與映射文件定義--UserDao接口

package com.shsxt.dao;

import com.shsxt.po.User;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * Created by xlf on 2019/7/11.
 */
@Repository
public interface UserDao {
    public User  queryUserById(Integer id);
    public List<User> queryUserList();
}


6.UserMapper.xml配置(注意:此時(shí)映射文件命名空間定義要符合規(guī)則:接口包名.接口類(lèi)名,否則不按規(guī)則出牌,測(cè)試會(huì)報(bào)錯(cuò)般卑,然后你就蒙圈了N渎场!蝠检!)

<?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.shsxt.dao.UserDao">


    <select id="queryUserById" parameterType="int" resultType="user">
        SELECT * from user where id=#{id}
    </select>


    <select id="queryUserList" resultType="user">
        SELECT * from user
    </select>



</mapper>


7.UserService 接口類(lèi)與實(shí)現(xiàn)類(lèi)定義

此時(shí)直接注入我們的 UserDao 接口即可沐鼠,然后直接調(diào)用
其方法,事已至此叹谁,離成功僅差一步饲梭!

*/
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public User queryUserById(Integer id){
        return userDao.queryUserById(id);
    }

    public PageInfo<User> queryUserList(Integer pageNum, Integer pageSize){
        // 1. 設(shè)置分頁(yè)查詢(xún)參數(shù)
        PageHelper.startPage(pageNum, pageSize);
        // 2. 執(zhí)行原有查詢(xún)
        List<User> userList = userDao.queryUserList();
        // 3. 構(gòu)建分頁(yè)查詢(xún)對(duì)象
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        return pageInfo;
    }

}


**8.junit 測(cè)試
**因?yàn)榕c spring 框架集成,我們采用 spring 框架測(cè)試 spring Test

/**
 * 單元測(cè)試,測(cè)試環(huán)境搭建
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml"})
public class UserServiceTest {
    @Autowired
    private UserService userService;

    /*
        測(cè)試查詢(xún)對(duì)象是否成功
     */
    @Test
    public void queryUserById() throws Exception {
        User user =userService.queryUserById(6);
        System.out.println(user);

    }
}


測(cè)試結(jié)果

image.png

四. mybatis 分頁(yè)插件的配置

開(kāi)源中國(guó)介紹參考地址:http://www.oschina.net/p/mybatis_pagehelper
Github 源碼介紹地址:
[https://github.com/pagehelper/Mybatis-PageHelper]{.underline}

1.修改 pom 文件焰檩, 添加分頁(yè) jar 包依賴(lài)

<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>4.1.0</version>
</dependency>


2.修改 mybatis.xml 文件,引入分頁(yè)插件


<plugins>
    <!-- com.github.pagehelper為PageHelper類(lèi)所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageHelper">
        <property name="dialect" value="mysql" />
        <!-- 該參數(shù)默認(rèn)為false -->
        <!-- 設(shè)置為true時(shí)憔涉,會(huì)將RowBounds第一個(gè)參數(shù)offset當(dāng)成pageNum頁(yè)碼使用 -->
        <!-- 和startPage中的pageNum效果一樣 -->
        <property name="offsetAsPageNum" value="true" />
        <!-- 該參數(shù)默認(rèn)為false -->
        <!-- 設(shè)置為true時(shí),使用RowBounds分頁(yè)會(huì)進(jìn)行count查詢(xún) -->
        <property name="rowBoundsWithCount" value="true" />
        <!-- 設(shè)置為true時(shí)析苫,如果pageSize=0或者RowBounds.limit = 0就會(huì)查詢(xún)出全部的結(jié)果 -->
        <!-- (相當(dāng)于沒(méi)有執(zhí)行分頁(yè)查詢(xún)兜叨,但是返回結(jié)果仍然是Page類(lèi)型) -->
        <property name="pageSizeZero" value="true" />
        <!-- 3.3.0版本可用 - 分頁(yè)參數(shù)合理化,默認(rèn)false禁用 -->
        <!-- 啟用合理化時(shí)衩侥,如果pageNum<1會(huì)查詢(xún)第一頁(yè)国旷,如果pageNum>pages會(huì)查詢(xún)最后一頁(yè) -->
        <!-- 禁用合理化時(shí),如果pageNum<1或pageNum>pages會(huì)返回空數(shù)據(jù) -->
        <property name="reasonable" value="true" />
        <!-- 3.5.0版本可用 - 為了支持startPage(Object params)方法 -->
        <!-- 增加了一個(gè)`params`參數(shù)來(lái)配置參數(shù)映射茫死,用于從Map或ServletRequest中取值 -->
        <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默認(rèn)值 -->
        <property name="params"
                  value="pageNum=start;pageSize=limit;pageSizeZero=zero;reasonable=heli;count=countsql" />
    </plugin>
</plugins>


3.UserDao 接口跪但, UserMapper.xml 添加對(duì)應(yīng)方法與實(shí)現(xiàn)
sql(參考上例方法已寫(xiě)入)

@Repository
public interface UserDao {
    public User  queryUserById(Integer id);  //查詢(xún)用戶(hù),根據(jù)id
    public List<User> queryUserList();
}


UserMapper.xml 添加


<select id="queryUserList" resultType="user">
    SELECT * from user
</select>


4.對(duì)應(yīng) UserService 接口添加分頁(yè)查詢(xún)方法


/* *
測(cè)試分頁(yè)查詢(xún)
 */
public PageInfo<User> queryUserList(Integer pageNUm ,Integer pageSize){
    //1.設(shè)置分頁(yè)查詢(xún)參數(shù)
    PageHelper.startPage(pageNUm,pageSize);
    //2執(zhí)行原有查詢(xún)
    List<User> userList =userDao.queryUserList();
    //3構(gòu)建分頁(yè)查詢(xún)對(duì)象
    PageInfo<User>  pageInfo =new PageInfo<>(userList);
    return pageInfo;
}


5.單元測(cè)試類(lèi)

/**
 * 測(cè)試分頁(yè)查詢(xún)
 */
@Test
public void queryUserList() throws Exception {
    PageInfo<User> pageInfo = userService.queryUserList(2, 5);

    System.out.println("total: "+pageInfo.getTotal());
    System.out.println("pages: "+pageInfo.getPages());
    List<User> userList = pageInfo.getList();
    userList.stream().forEach(System.out::println);
}


6.測(cè)試分頁(yè)效果


image.png

五. Mybatis 代碼自動(dòng)化生成
官網(wǎng)地址: http://generator.sturgeon.mopaas.com/index.html
對(duì)于代碼自動(dòng)化生成,我們借助 maven 插件來(lái)實(shí)現(xiàn) mybatis crud 基本代碼的
生成峦萎。
配置步驟如下:

1.Pom.xml 文件的修改
添加 mybatis 插件配置

<!--mybatis代碼自動(dòng)生成-->
<plugins>
  <plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.2</version>
    <configuration>
      <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
      <verbose>true</verbose>
      <overwrite>true</overwrite>
    </configuration>

  </plugin>
</plugins>


2.generatorConfig.xml 配置
需添加到資源包下 src/mian/resources

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--數(shù)據(jù)庫(kù)驅(qū)動(dòng)-->
    <classPathEntry    location="D:/m2/repository/mysql/mysql-connector-java/5.1.39/mysql-connector-java-5.1.39.jar"/>
    <context id="DB2Tables"    targetRuntime="MyBatis3">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--數(shù)據(jù)庫(kù)鏈接地址賬號(hào)密碼-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis" userId="root" password="shsxt">
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!--生成Model類(lèi)存放位置-->
        <javaModelGenerator targetPackage="com.shsxt.po" targetProject="E:/mycode/mybatis_spring_jc/src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!--生成映射文件存放位置-->
        <sqlMapGenerator targetPackage="com.shsxt.mapper" targetProject="E:/mycode/mybatis_spring_jc/src/main/java">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!--生成Dao類(lèi)存放位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.shsxt.dao" targetProject="E:/mycode/mybatis_spring_jc/src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>


        <table tableName="account" domainObjectName="Account" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>
</generatorConfiguration>


3.配置運(yùn)行命令參數(shù)
window--->preferences-->java-->installed jres--->edit
在彈出的對(duì)話(huà)框中 修改
jre 運(yùn)行參數(shù) -Dmaven.multiModuleProjectDirectory=$**MAVEN_HOME
**MAVEN_HOME 為你配置的環(huán)境變量名

image.png
image.png

以上配置如果配置完成
4.選中項(xiàng)目 run as -->maven build 在出現(xiàn)的對(duì)話(huà)框 Goals 輸入框中
輸入一下命令:
**mybatis-generator:generate
**然后點(diǎn)擊 run 運(yùn)行 如果你之前額配置沒(méi)有錯(cuò)誤屡久,就會(huì)啟動(dòng)插件
自動(dòng)生成你想要的代
碼啦。

結(jié)果如下:

image.png

image.png

六. Mybatis Dao 層爱榔、 Service 層封裝
重復(fù)性的勞動(dòng)涂身,就要通過(guò)封裝來(lái)解決!

image.png

1.Dao 層 BaseMapper 方法定義

package com.shsxt.base;

import org.springframework.dao.DataAccessException;

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

public interface BaseMapper<T> {
    /**
     * 添加記錄不返回主鍵
     * @param entity
     * @return
     * @throws DataAccessException
     */
    public int insert(T entity) throws DataAccessException;
    /**
     * 
     * @param entities
     * @return
     * @throws DataAccessException
     */
    public int insertBatch(List<T> entities) throws DataAccessException;
    /**
     * 查詢(xún)總記錄數(shù)
     * @param map
     * @return
     */
    @SuppressWarnings("rawtypes")
    public int queryCountByParams(Map map) throws DataAccessException;
    /**
     * 查詢(xún)記錄 通過(guò)id
     * @param id
     * @return
     */
    public T queryById(Integer id) throws DataAccessException;

    /**
     * 分頁(yè)查詢(xún)記錄
     * @param baseQuery
     * @return
     */
    public List<T> queryForPage(BaseQuery baseQuery) throws DataAccessException;
    /**
     * 查詢(xún)記錄不帶分頁(yè)情況
     * @param map
     * @return
     */
    @SuppressWarnings("rawtypes")
    public List<T> queryByParams(Map map) throws DataAccessException;

    /**
     * 更新記錄
     * @param entity
     * @return
     */
    public int update(T entity) throws DataAccessException;

    /**
     * 批量更新
     * @param map
     * @return
     * @throws DataAccessException
     */
    public int updateBatch(Map map) throws DataAccessException;

    /**
     * 刪除記錄
     * @param id
     * @return
     */
    public int delete(Integer id) throws DataAccessException;

    /**
     * 批量刪除
     * @param ids
     * @return
     */
    public int deleteBatch(int[] ids) throws DataAccessException;
}


2. Service 層 BaseService 定義與實(shí)現(xiàn)

package com.shsxt.base;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;

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

public abstract class BaseService<T> {
    @Autowired
    public BaseMapper <T> baseMapper;
    
    /**
     * 添加記錄
     * @param entity
     * @return
     * @throws Exception
     */
    public int insert(T entity) throws Exception{
        int result= baseMapper.insert(entity);
        return result;
    }
    
    /**
     * 批量添加記錄
     * @param entities
     * @return
     * @throws Exception
     */
    public int insertBatch(List<T> entities) throws Exception{
        return baseMapper.insertBatch(entities);
    }
    
    
    /**
     * 根據(jù)參數(shù)統(tǒng)計(jì)記錄數(shù)
     * @param map
     * @return
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public int queryCountByParams(Map map)throws Exception{
        return baseMapper.queryCountByParams(map);
    }
    
    
    
    
    /**
     * 查詢(xún)記錄通過(guò)id
     * @param id
     * @return
     * @throws Exception
     */
    public T queryById(Integer id)throws Exception{
        AssertUtil.isNull(id, "記錄id非空!");
        return baseMapper.queryById(id);
    }
    
    
    /**
     * 分頁(yè)查詢(xún)
     * @param baseQuery
     * @return
     * @throws Exception
     */
    public PageInfo<T> queryForPage(BaseQuery baseQuery)throws Exception{
        PageHelper.startPage(baseQuery.getPageNum(),baseQuery.getPageSize());
        List<T> list= baseMapper.queryForPage(baseQuery);       
        PageInfo<T> pageInfo=new PageInfo<T>(list);
        return pageInfo;        
    }
    
    
    
    
    /**
     * 
     * @param map
     * @return
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public List<T> queryByParams(Map map)throws Exception{  
        return baseMapper.queryByParams(map);  
    }
    
    
    
    /**
     * 查詢(xún)記錄
     * @param entity
     * @return
     * @throws Exception
     */
    public int update(T entity)throws Exception{
        return baseMapper.update(entity);
    }
    
    
    /**
     * 批量更新
     * @param map
     * @return
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public int updateBatch(Map map) throws Exception{
        return baseMapper.updateBatch(map);
    }
    
    /**
     * 刪除記錄
     * @param id
     * @return
     * @throws Exception
     */
    public int delete(Integer id) throws Exception{
        // 判斷 空
        AssertUtil.isNull(id, "記錄id非空搓蚪!");
        AssertUtil.isNull(queryById(id), "待刪除的記錄不存在!");
        return  baseMapper.delete(id);
    }
    
    /**
     * 批量刪除
     * @param ids
     * @return
     */
    public int deleteBatch(int[] ids) throws Exception{
        AssertUtil.isNull(ids.length==0,"請(qǐng)至少選擇一項(xiàng)記錄!");
        return  baseMapper.deleteBatch(ids);
    }
}


3. BaseQuery 類(lèi)封裝

package com.shsxt.base;

public class BaseQuery {
    /**
     * 分頁(yè)頁(yè)碼
     */
    private int pageNum=1;
    
    /**
     * 每頁(yè)記錄數(shù)
     */
    private int pageSize=10;

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
}


4. 參數(shù)異常處理AssertUtil

package com.shsxt.base;

public class AssertUtil {
    
    /**
     * 表達(dá)式結(jié)果真時(shí)判斷
     * @param expression
     * @param msg
     */
    public static void isTrue(Boolean expression,String msg){
        if(expression){
            throw new ParamException(msg);
        }   
    }
    public static void isTure(Boolean expression){
        if(expression){
            throw new ParamException("參數(shù)異常");
        }
    }   
    /**
     * 參數(shù)為空時(shí)
     * @param object
     * @param msg
     */
    public static void isNull(Object object,String msg){
        if(object==null){
            throw new ParamException(msg);
        }
    }
    /**
     * 參數(shù)不空時(shí)
     * @param object
     * @param msg
     */
    public static void notNull(Object object,String msg){
        if(object!=null){
            throw new ParamException(msg);
        }
    }
}


5. .異常類(lèi)定義ParamException

package com.shsxt.base;

/**
 * 參數(shù)異常類(lèi)
 * @author Administrator
 *
 */
public class ParamException extends RuntimeException{
    /**
     * 
     */
    private static final long serialVersionUID = -5962296753554846774L;
    
    /**
     * 錯(cuò)誤狀態(tài)碼
     */
    private int errorCode;

    public ParamException() {
    }   
    /**
     * 錯(cuò)誤消息
     * @param msg
     */
    public ParamException(String msg) {
        super(msg);
    }
    public ParamException(int errorCode,String msg){
        super(msg);
        this.errorCode=errorCode;
    }
    public int getErrorCode() {
        return errorCode;     
    }
    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }
}


6. mybatis-generator:generate自動(dòng)生成你想要的代碼

7.更改UserMapper接口繼承BaseMapper<User>

@Repository
public interface UserMapper extends BaseMapper<User> {

}


8.修改UserMapper.xml配置,加入分頁(yè)配置,修改方法名

<?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.shsxt.dao.UserMapper" >
  <resultMap id="BaseResultMap" type="com.shsxt.po.User" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="user_name" property="userName" jdbcType="VARCHAR" />
    <result column="user_pwd" property="userPwd" jdbcType="VARCHAR" />
    <result column="real_name" property="realName" jdbcType="VARCHAR" />
    <result column="nation" property="nation" jdbcType="VARCHAR" />
    <result column="card_id" property="cardId" jdbcType="INTEGER" />
  </resultMap>
  <sql id="Base_Column_List" >
    id, user_name, user_pwd, real_name, nation, card_id
  </sql>
  <select id="queryById" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from user
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="delete" parameterType="java.lang.Integer" >
    delete from user
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.shsxt.po.User" >
    insert into user
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="userName != null" >
        user_name,
      </if>
      <if test="userPwd != null" >
        user_pwd,
      </if>
      <if test="realName != null" >
        real_name,
      </if>
      <if test="nation != null" >
        nation,
      </if>
      <if test="cardId != null" >
        card_id,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="userName != null" >
        #{userName,jdbcType=VARCHAR},
      </if>
      <if test="userPwd != null" >
        #{userPwd,jdbcType=VARCHAR},
      </if>
      <if test="realName != null" >
        #{realName,jdbcType=VARCHAR},
      </if>
      <if test="nation != null" >
        #{nation,jdbcType=VARCHAR},
      </if>
      <if test="cardId != null" >
        #{cardId,jdbcType=INTEGER},
      </if>
    </trim>
  </insert>
  <update id="update" parameterType="com.shsxt.po.User" >
    update user
    <set >
      <if test="userName != null" >
        user_name = #{userName,jdbcType=VARCHAR},
      </if>
      <if test="userPwd != null" >
        user_pwd = #{userPwd,jdbcType=VARCHAR},
      </if>
      <if test="realName != null" >
        real_name = #{realName,jdbcType=VARCHAR},
      </if>
      <if test="nation != null" >
        nation = #{nation,jdbcType=VARCHAR},
      </if>
      <if test="cardId != null" >
        card_id = #{cardId,jdbcType=INTEGER},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>

  <select id="queryForPage" parameterType="com.shsxt.base.BaseQuery" resultMap="BaseResultMap">
    SELECT * from user
  </select>
</mapper>



9.新建UserService extends BaseService<User> ,調(diào)用UserMapper

@Service
public class UserService extends BaseService<User> {

    @Autowired
    private UserMapper userMapper;


}


10.新建測(cè)試類(lèi),測(cè)試查詢(xún)功能,與分頁(yè)功能.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml"})
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void queryUserById() throws Exception {
        User user = userService.queryById(6);
        System.out.println(user);
    }

    @Test
    public void queryUserList() throws Exception {
        BaseQuery baseQuery = new BaseQuery();
        baseQuery.setPageNum(1);
        baseQuery.setPageSize(3);
        PageInfo<User> pageInfo = userService.queryForPage(baseQuery);
        pageInfo.getList().stream().forEach(System.out::println);
    }





結(jié)果:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛤售,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌悴能,老刑警劉巖揣钦,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異漠酿,居然都是意外死亡冯凹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)炒嘲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宇姚,“玉大人,你說(shuō)我怎么就攤上這事夫凸』肜停” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵夭拌,是天一觀的道長(zhǎng)魔熏。 經(jīng)常有香客問(wèn)我,道長(zhǎng)鸽扁,這世上最難降的妖魔是什么蒜绽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮桶现,結(jié)果婚禮上躲雅,老公的妹妹穿的比我還像新娘。我一直安慰自己骡和,他們只是感情好相赁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著即横,像睡著了一般。 火紅的嫁衣襯著肌膚如雪裆赵。 梳的紋絲不亂的頭發(fā)上东囚,一...
    開(kāi)封第一講書(shū)人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音战授,去河邊找鬼页藻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛植兰,可吹牛的內(nèi)容都是我干的份帐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼楣导,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼废境!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤噩凹,失蹤者是張志新(化名)和其女友劉穎巴元,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體驮宴,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逮刨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了堵泽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片修己。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖迎罗,靈堂內(nèi)的尸體忽然破棺而出睬愤,到底是詐尸還是另有隱情,我是刑警寧澤佳谦,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布戴涝,位于F島的核電站,受9級(jí)特大地震影響钻蔑,放射性物質(zhì)發(fā)生泄漏啥刻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一咪笑、第九天 我趴在偏房一處隱蔽的房頂上張望可帽。 院中可真熱鬧,春花似錦窗怒、人聲如沸映跟。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)努隙。三九已至,卻和暖如春辜昵,著一層夾襖步出監(jiān)牢的瞬間荸镊,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工堪置, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留躬存,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓舀锨,卻偏偏與公主長(zhǎng)得像岭洲,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坎匿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

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

  • 對(duì)訂單商品數(shù)據(jù)模型進(jìn)行分析盾剩。 1.高級(jí)映射: 實(shí)現(xiàn)一對(duì)一雷激、一對(duì)多、多對(duì)多查詢(xún)延遲加載 2.查詢(xún)緩存 一級(jí)緩存二級(jí)緩...
    TiHom閱讀 667評(píng)論 1 4
  • 1.mybatis 中 #{}和 ${}的區(qū)別是什么彪腔? 1. #將傳入的數(shù)據(jù)都當(dāng)成一個(gè)字符串侥锦,會(huì)對(duì)自動(dòng)傳入的數(shù)據(jù)加...
    久伴_(kāi)不離閱讀 3,811評(píng)論 0 4
  • Mybatis介紹 MyBatis 本是apache的一個(gè)開(kāi)源項(xiàng)目iBatis, 2010年這個(gè)項(xiàng)目由apache...
    So_ProbuING閱讀 1,106評(píng)論 0 2
  • 建安十九年,吾奉主公劉玄徳之命德挣,率仁義之師征討益州恭垦。前山路崎嶇,夾道水石兇險(xiǎn)格嗅,有坡名落鳳番挺,某號(hào)鳳雛也,落鳳之地屯掖,或...
    牧心的四爺閱讀 354評(píng)論 0 1
  • 一玄柏、補(bǔ)雙世寵妃 又過(guò)了一個(gè)整天看劇的周末。 也許平行時(shí)空里的那個(gè)我是努力認(rèn)真的贴铜,什么時(shí)候時(shí)間軌道會(huì)切換粪摘,空間結(jié)構(gòu)會(huì)...
    姑射仙子閱讀 204評(píng)論 0 0