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é)果.
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é)果
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ú)法去重.
**
* 接收多表聯(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é)果
二氧腰、 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)
只有一次查詢(xún)
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);
}
}
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ō)明:\
- 映射語(yǔ)句文件中的所有 select 語(yǔ)句將會(huì)被緩存泡态。\
- 映射語(yǔ)句文件中的所有 insert椎镣,update 和 delete 語(yǔ)句會(huì)刷新緩存。\
- 緩存會(huì)使用 Least Recently Used(LRU兽赁,最近最少使用的)算法來(lái)收回状答。\
- 緩存會(huì)根據(jù)指定的時(shí)間間隔來(lái)刷新.\
- 緩存會(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();
}
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é)果
三. 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
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é)果
四. 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è)效果
五. 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)境變量名
以上配置如果配置完成
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é)果如下:
六. Mybatis Dao 層爱榔、 Service 層封裝
重復(fù)性的勞動(dòng)涂身,就要通過(guò)封裝來(lái)解決!
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é)果: