10.3.2 实现DAO组件

10.3.2 实现DAO组件

为了实现DAO模式,系统至少需要具有如下三个部分:

  • DAO接口
  • DAO接口的实现类
  • DAO工厂

对于采用Spring框架的应用而言,无须额外提供DAO工厂,因为Spring容器本身就是DAO工厂。此外,开发者需要提供DAO接口和DAO实现类。每个DAO组件都应该提供标准的新增加载更新删除等方法,此外还需提供数量不等的查询方法
如下是AuctionUserDao接口的源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package org.crazyit.auction.dao;

import org.crazyit.auction.domain.AuctionUser;
import org.crazyit.common.dao.BaseDao;

public interface AuctionUserDao extends BaseDao<AuctionUser> {
/**
* 根据用户名,密码查找用户
*
* @param username 查询所需的用户名
* @param pass 查询所需的密码
* @return 指定用户名、密码对应的用户
*/
AuctionUser findByNameAndPass(String username, String pass);

/**
* 根据物品id、出价查询用户
*
* @param itemId 物品id;
* @param price 出价的价格
* @return 指定物品、指定竞价对应的用户
*/
AuctionUser findByItemAndPrice(Integer itemId, Double price);
}

从表面上看,在该AuctionUserDao 接口中只定义了2 个方法,但由于该接口继承了BaseDao<AuctionUser>,因此该接口其实也包含了增加、修改,根据主键加载、删除等通用的DAO 方法。在该接口中额外定义的findUserByNameAndPass()方法,可根据用户名、密码查询AuctionUser,由于本系统在映射AuctionUserusername属性时指定了unique="true",因此根据usernamepass查询时不会返回List,最多只会返回一个AuctionUser实例。
定义了AuctionUserDao接口之后,下面就可以为该接口提供实现类了,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package org.crazyit.auction.dao.impl;

import java.util.List;
import org.crazyit.auction.dao.AuctionUserDao;
import org.crazyit.auction.domain.AuctionUser;
import org.crazyit.common.dao.impl.BaseDaoHibernate4;

public class AuctionUserDaoHibernate extends BaseDaoHibernate4<AuctionUser>
implements
AuctionUserDao
{

/**
* 根据用户名,密码查找用户
*
* @param username
* 查询所需的用户名
* @param pass
* 查询所需的密码
* @return 指定用户名、密码对应的用户
*/
public AuctionUser findByNameAndPass(String username, String pass)
{
// 执行HQL查询
// 1号方法
List<AuctionUser> ul = (List<AuctionUser>) find(
"from AuctionUser au where au.username=?0 and au.userpass=?1",
username, pass);
// 返回查询得到的第一个AuctionUser对象
if (ul != null && ul.size() == 1)
{
return (AuctionUser) ul.get(0);
}
return null;
}

/**
* 根据物品id、出价查询用户
*
* @param itemId
* 物品id;
* @param price
* 竞价的价格
* @return 指定物品、指定竞价对应的用户
*/
public AuctionUser findByItemAndPrice(Integer itemId, Double price)
{
// 执行HQL查询
List<AuctionUser> userList = (List<AuctionUser>) find(
"select user from AuctionUser user inner join user.bids bid"
+ " where bid.bidItem.id=?0 and bid.bidPrice=?1",
itemId, price);
// 返回查询得到的第一个Bid对象关联的AuctionUser对象
if (userList != null && userList.size() == 1)
{
return userList.get(0);
}
return null;
}
}

AuctionUserDaoHibernate类中的方法稍稍复杂一些,该方法用于根据用户名、密码查找用户。
ItemDaoAuctionUserDao稍微复杂一点,下面是ItemDao接口的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package org.crazyit.auction.dao;

import java.util.List;
import org.crazyit.auction.domain.Item;
import org.crazyit.common.dao.BaseDao;

public interface ItemDao extends BaseDao<Item>
{
/**
* 根据产品分类,获取当前拍卖的全部商品
*
* @param kindId
* 种类id;
* @return 该类的全部产品
*/
List<Item> findByKind(Integer kindId);

/**
* 根据所有者查找处于拍卖中的物品
*
* @param useId
* 所有者Id;
* @return 指定用户处于拍卖中的全部物品
*/
List<Item> findByOwner(Integer userId);

/**
* 根据赢取者查找物品
*
* @param userId
* 赢取者Id;
* @return 指定用户赢取的全部物品
*/
List<Item> findByWiner(Integer userId);

/**
* 根据物品状态查找物品
*
* @param stateId
* 状态Id;
* @return 该状态下的全部物品
*/
List<Item> findByState(Integer stateId);
}

同样,让ItemDaoHibernate继承BaseDaoHibernate4就能用简单的代码来实现该DAO组件的全部方法了,下面是ItemDaoHibernate类的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package org.crazyit.auction.dao.impl;

import java.util.List;
import org.crazyit.auction.dao.ItemDao;
import org.crazyit.auction.domain.Item;
import org.crazyit.common.dao.impl.BaseDaoHibernate4;

public class ItemDaoHibernate extends BaseDaoHibernate4<Item> implements ItemDao
{
/**
* 根据产品分类,获取当前拍卖的全部商品
*
* @param kindId
* 种类id;
* @return 该类的全部产品
*/
public List<Item> findByKind(Integer kindId)
{
return find("from Item as i where i.kind.id=?0 and i.itemState.id=1",
kindId);
}

/**
* 根据所有者查找处于拍卖中的物品
*
* @param useId
* 所有者Id;
* @return 指定用户处于拍卖中的全部物品
*/
public List<Item> findByOwner(Integer userId)
{
return (List<Item>) find(
"from Item as i where i.owner.id=?0 and i.itemState.id=1",
userId);
}

/**
* 根据赢取者查找物品
*
* @param userId
* 赢取者Id;
* @return 指定用户赢取的全部物品
*/
public List<Item> findByWiner(Integer userId)
{
return find(
"from Item as i where i.winer.id =?0" + " and i.itemState.id=2",
userId);
}

/**
* 根据物品状态查找物品
*
* @param stateId
* 状态Id;
* @return 该状态下的全部物品
*/
public List<Item> findByState(Integer stateId)
{
return find("from Item as i where i.itemState.id = ?0", stateId);
}
}

AuctionUserDaoHiberante类相似,ItemDaoHibernate类也非常简单,几乎所有方法都只要一行代码即可实现。
借助于Spring+Hibernate的简化结构,开发者可以非常简便地实现所有DAO组件。系统中的KindDaoBidDaoStateDao类都非常简单,故这里不再给出它们的实现。