這幾年來註解開發越來越流行,Mybatis 也可以使用註解開發方式,這樣我們就可以減少編寫 Mapper 對映 檔案了。本次我們先圍繞一些基本的 CRUD 來學習,再學習複雜對映關係及延遲載入。

3.1 mybatis 的常用註解說明

@Insert

實現新增

@Update

實現更新

@Delete

實現刪除

@Select

實現查詢

@Result

實現結果集封裝

@Results

可以與

@Result

一起使用

封裝多個結果集

@ResultMap

實現引用

@Results

定義的封裝

@One

實現一對一結果集封裝

@Many

實現一對多結果集封裝

@SelectProvider

實現動態

SQL

對映

@CacheNamespace

實現註解二級快取的使用

3.2 使用 Mybatis 註解實現基本 CRUD

單表的 CRUD 操作是最基本的操作,前面我們的學習都是基於 Mybaits 的對映檔案來實現的。

3.2.1 編寫實體類

package

com。itheima。domain

import

java。io。Serializable

import

java。util。Date

/**

* @author 黑馬程式設計師

* @Company http://www。ithiema。com

*/

public

class

User

implements

Serializable

{

private

Integer

id

private

String

username

private

String

address

private

String

sex

private

Date

birthday

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

getAddress

()

{

return

address

}

public

void

setAddress

String

address

{

this

address

=

address

}

public

String

getSex

()

{

return

sex

}

public

void

setSex

String

sex

{

this

sex

=

sex

}

public

Date

getBirthday

()

{

return

birthday

}

public

void

setBirthday

Date

birthday

{

this

birthday

=

birthday

}

@Override

public

String

toString

()

{

return

“User{”

+

“id=”

+

id

+

“, username=‘”

+

username

+

’\‘’

+

“, address=‘”

+

address

+

’\‘’

+

“, sex=‘”

+

sex

+

’\‘’

+

“, birthday=”

+

birthday

+

‘}’

}

}

注意: 此處我們故意和資料庫表的列名不一致。

3.2.2 使用註解方式開發持久層介面

3.2.2 使用註解方式開發持久層介面

Mybatis 註解開發

完整的DAO類

public

interface

IUserDao

{

/**

* 查詢所有使用者

* @return

*/

@Select

“select * from user”

List

<

User

>

findAll

();

/**

* 儲存使用者

* @param user

*/

@Insert

“insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})”

void

saveUser

User

user

);

/**

* 更新使用者

* @param user

*/

@Update

“update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}”

void

updateUser

User

user

);

/**

* 刪除使用者

* @param userId

*/

@Delete

“delete from user where id=#{id} ”

void

deleteUser

Integer

userId

);

/**

* 根據id查詢使用者

* @param userId

* @return

*/

@Select

“select * from user where id=#{id} ”

User

findById

Integer

userId

);

/**

* 根據使用者名稱稱模糊查詢

* @param username

* @return

*/

// @Select(“select * from user where username like #{username} ”)

@Select

“select * from user where username like ‘%${value}%’ ”

List

<

User

>

findUserByName

String

username

);

/**

* 查詢總使用者數量

* @return

*/

@Select

“select count(*) from user ”

int

findTotalUser

();

}

3.2.3 編寫 SqlMapConfig 配置檔案

<?xml version=“1。0” encoding=“UTF-8”?>

<!DOCTYPE configuration

PUBLIC “-//mybatis。org//DTD Config 3。0//EN”

“http://mybatis。org/dtd/mybatis-3-config。dtd”>

<!—— 引入外部配置檔案——>

resource=

“jdbcConfig。properties”

>

<!——配置別名——>

name=

“com。itheima。domain”

>

<!—— 配置環境——>

default=

“mysql”

>

id=

“mysql”

>

type=

“JDBC”

>

type=

“POOLED”

>

name=

“driver”

value=

“${jdbc。driver}”

>

name=

“url”

value=

“${jdbc。url}”

>

name=

“username”

value=

“${jdbc。username}”

>

name=

“password”

value=

“${jdbc。password}”

>

<!—— 指定帶有註解的dao介面所在位置 ——>

class=

“com。itheima。dao。IUserDao”

>

Mybatis 註解開發

3.2.4 編寫測試方法

@Test

public

void

testSave

(){

User

user

=

new

User

();

user

setUsername

“mybatis annotation”

);

user

setAddress

“北京市昌平區”

);

userDao

saveUser

user

);

}

@Test

public

void

testUpdate

(){

User

user

=

new

User

();

user

setId

57

);

user

setUsername

“mybatis annotation update”

);

user

setAddress

“北京市海淀區”

);

user

setSex

“男”

);

user

setBirthday

new

Date

());

userDao

updateUser

user

);

}

@Test

public

void

testDelete

(){

userDao

deleteUser

51

);

}

@Test

public

void

testFindOne

(){

User

user

=

userDao

findById

57

);

System

out

println

user

);

}

@Test

public

void

testFindByName

(){

// List users = userDao。findUserByName(“%mybatis%”);

List

<

User

>

users

=

userDao

findUserByName

“mybatis”

);

for

User

user

users

){

System

out

println

user

);

}

}

@Test

public

void

testFindTotal

(){

int

total

=

userDao

findTotalUser

();

System

out

println

total

);

}

3.3 使用註解實現複雜關係對映開發

實現複雜關係對映之前我們可以在對映檔案中透過配置來實現,在使用註解開發時我們需要借 助

@Results 註解,@Result 註解,@One 註解,@Many 註解。

3.3.1 複雜關係對映的註解說明

@

Results

註解

代替的是標籤

<

resultMap

>

該註解中可以使用單個

@

Result

註解

也可以使用

@

Result

集合

@

Results

{

@

Result

(),@

Result

()

}

@

Results

(@

Result

())

@

Resutl

註解

代替了

<

id

>

標籤和

<

result

>

標籤

@

Result

屬性介紹

id

是否是主鍵欄位

column

資料庫的列名

property

需要裝配的屬性名

one

需要使用的

@

One

註解

(@

Result

one

=

@

One

)()))

many

需要使用的

@

Many

註解

(@

Result

many

=

@

many

)()))

@

One

註解

一對一

代替了

<

assocation

>

標籤

是多表查詢的關鍵

在註解中用來指定子查詢返回單一物件

@

One

註解屬性介紹

select

指定用來多表查詢的

sqlmapper

fetchType

會覆蓋全域性的配置引數

lazyLoadingEnabled

。。

使用格式

@

Result

column

=

“ ”

property

=

“”

one

=

@

One

select

=

“”

))

@

Many

註解

多對一

代替了

<

Collection

>

標籤

是是多表查詢的關鍵

在註解中用來指定子查詢返回物件集合

注意

聚集元素用來處理

一對多

的關係

需要指定對映的

Java

實體類的屬性

屬性的

javaType

一般為

ArrayList

但是註解中可以不定義

使用格式

@

Result

property

=

“”

column

=

“”

many

=

@

Many

select

=

“”

))

3.3.2 使用註解實現一對一複雜關係對映及延遲載入

需求: 載入賬戶資訊時並且載入該賬戶的使用者資訊,根據情況可實現延遲載入。(註解方式實現)

3.3.2.1 新增 User 實體類及 Account 實體類

public

class

User

implements

Serializable

{

private

Integer

userId

private

String

userName

private

String

userAddress

private

String

userSex

private

Date

userBirthday

//一對多關係對映:一個使用者對應多個賬戶

private

List

<

Account

>

accounts

public

List

<

Account

>

getAccounts

()

{

return

accounts

}

public

void

setAccounts

List

<

Account

>

accounts

{

this

accounts

=

accounts

}

public

Integer

getUserId

()

{

return

userId

}

public

void

setUserId

Integer

userId

{

this

userId

=

userId

}

public

String

getUserName

()

{

return

userName

}

public

void

setUserName

String

userName

{

this

userName

=

userName

}

public

String

getUserAddress

()

{

return

userAddress

}

public

void

setUserAddress

String

userAddress

{

this

userAddress

=

userAddress

}

public

String

getUserSex

()

{

return

userSex

}

public

void

setUserSex

String

userSex

{

this

userSex

=

userSex

}

public

Date

getUserBirthday

()

{

return

userBirthday

}

public

void

setUserBirthday

Date

userBirthday

{

this

userBirthday

=

userBirthday

}

@Override

public

String

toString

()

{

return

“User{”

+

“userId=”

+

userId

+

“, userName=‘”

+

userName

+

’\‘’

+

“, userAddress=‘”

+

userAddress

+

’\‘’

+

“, userSex=‘”

+

userSex

+

’\‘’

+

“, userBirthday=”

+

userBirthday

+

‘}’

}

}

public

class

Account

implements

Serializable

{

private

Integer

id

private

Integer

uid

private

Double

money

//多對一(mybatis中稱之為一對一)的對映:一個賬戶只能屬於一個使用者

private

User

user

public

User

getUser

()

{

return

user

}

public

void

setUser

User

user

{

this

user

=

user

}

public

Integer

getId

()

{

return

id

}

public

void

setId

Integer

id

{

this

id

=

id

}

public

Integer

getUid

()

{

return

uid

}

public

void

setUid

Integer

uid

{

this

uid

=

uid

}

public

Double

getMoney

()

{

return

money

}

public

void

setMoney

Double

money

{

this

money

=

money

}

@Override

public

String

toString

()

{

return

“Account{”

+

“id=”

+

id

+

“, uid=”

+

uid

+

“, money=”

+

money

+

‘}’

}

}

3.3.2.2 新增賬戶的持久層介面並使用註解配置

public

interface

IAccountDao

{

/**

* 查詢所有賬戶,並且獲取每個賬戶所屬的使用者資訊

* @return

*/

@Select

“select * from account”

@Results

id

=

“accountMap”

value

=

{

@Result

id

=

true

column

=

“id”

property

=

“id”

),

@Result

column

=

“uid”

property

=

“uid”

),

@Result

column

=

“money”

property

=

“money”

),

@Result

property

=

“user”

column

=

“uid”

one

=

@One

select

=

“com。itheima。dao。IUserDao。findById”

fetchType

=

FetchType

EAGER

))

})

List

<

Account

>

findAll

();

/**

* 根據使用者id查詢賬戶資訊

* @param userId

* @return

*/

@Select

“select * from account where uid = #{userId}”

List

<

Account

>

findAccountByUid

Integer

userId

);

}

3.3.2.3 新增使用者的持久層介面並使用註解配置

@CacheNamespace

blocking

=

true

public

interface

IUserDao

{

/**

* 查詢所有使用者

* @return

*/

@Select

“select * from user”

@Results

id

=

“userMap”

value

={

@Result

id

=

true

column

=

“id”

property

=

“userId”

),

@Result

column

=

“username”

property

=

“userName”

),

@Result

column

=

“address”

property

=

“userAddress”

),

@Result

column

=

“sex”

property

=

“userSex”

),

@Result

column

=

“birthday”

property

=

“userBirthday”

),

@Result

property

=

“accounts”

column

=

“id”

many

=

@Many

select

=

“com。itheima。dao。IAccountDao。findAccountByUid”

fetchType

=

FetchType

LAZY

))

})

List

<

User

>

findAll

();

/**

* 根據id查詢使用者

* @param userId

* @return

*/

@Select

“select * from user where id=#{id} ”

@ResultMap

“userMap”

User

findById

Integer

userId

);

/**

* 根據使用者名稱稱模糊查詢

* @param username

* @return

*/

@Select

“select * from user where username like #{username} ”

@ResultMap

“userMap”

List

<

User

>

findUserByName

String

username

);

}

3.3.2.4 測試一對一關聯及延遲載入

@Test

public

void

testFindAll

(){

List

<

Account

>

accounts

=

accountDao

findAll

();

/*

for(Account account : accounts){

System。out。println(“——每個賬戶的資訊——-”);

System。out。println(account);

System。out。println(account。getUser());

}

*/

}

3.3.3 使用註解實現一對多複雜關係對映

需求: 查詢使用者資訊時,也要查詢他的賬戶列表。使用註解方式實現。 分析: 一個使用者具有多個賬戶資訊,所以形成了使用者(User)與賬戶(Account)之間的一對多關係。

3.3.3.1 User 實體類加入 List<Account>

//一對多關係對映:一個使用者對應多個賬戶

private

List

<

Account

>

accounts

public

List

<

Account

>

getAccounts

()

{

return

accounts

}

public

void

setAccounts

List

<

Account

>

accounts

{

this

accounts

=

accounts

}

3.3.3.2 編寫使用者的持久層介面並使用註解配置

@CacheNamespace

blocking

=

true

public

interface

IUserDao

{

/**

* 查詢所有使用者

* @return

*/

@Select

“select * from user”

@Results

id

=

“userMap”

value

={

@Result

id

=

true

column

=

“id”

property

=

“userId”

),

@Result

column

=

“username”

property

=

“userName”

),

@Result

column

=

“address”

property

=

“userAddress”

),

@Result

column

=

“sex”

property

=

“userSex”

),

@Result

column

=

“birthday”

property

=

“userBirthday”

),

@Result

property

=

“accounts”

column

=

“id”

many

=

@Many

select

=

“com。itheima。dao。IAccountDao。findAccountByUid”

fetchType

=

FetchType

LAZY

))

})

List

<

User

>

findAll

();

/**

* 根據id查詢使用者

* @param userId

* @return

*/

@Select

“select * from user where id=#{id} ”

@ResultMap

“userMap”

User

findById

Integer

userId

);

/**

* 根據使用者名稱稱模糊查詢

* @param username

* @return

*/

@Select

“select * from user where username like #{username} ”

@ResultMap

“userMap”

List

<

User

>

findUserByName

String

username

);

}

@Many

相當於

<

collection

>

的配置

select

屬性

代表將要執行的

sql

語句

fetchType

屬性

代表載入方式

一般如果要延遲載入都設定為

LAZY

的值

3.3.3.3 編寫賬戶的持久層介面並使用註解配置

/**

* 根據使用者id查詢賬戶資訊

* @param userId

* @return

*/

@Select

“select * from account where uid = #{userId}”

List

<

Account

>

findAccountByUid

Integer

userId

);

3.3.3.4 新增測試方法

/**

* 測試查詢所有 */

@Test

public

void

testFindAll

()

{

List

<

User

>

users

=

userDao

findAll

();

//

for

User

user

users

{

System

out

println

“——-每個使用者的內容——-”

);

System

out

println

user

);

//

System

out

println

user

getAccounts

());

// }

}

3.4 mybatis 基於註解的二級快取

3.4.1 在 SqlMapConfig 中開啟二級快取支援

<!—— 配置二級快取 ——>

<!—— 開啟二級快取的支援 ——>

name=

“cacheEnabled”

value=

“true”

/>

3.4.2 在持久層介面中使用註解配置二級快取

Mybatis 註解開發