天天看點

DAO模式簡介

DAO(Data Access Object,資料通路對象),主要的功能是用于進行資料操作的,在程式的标準開發架構中屬于資料層的操作。

資料開發結構:

DAO模式簡介

資源層是資料庫的操作層,裡面可以進行各種資料庫的存儲,但是這些資料存儲的時候肯定是依靠SQL語句,資料層通過一個專門的資料庫元件完成對資料庫的操作

業務層是整個項目的核心

DAO組成

DatabaseConnection:專門負責資料庫打開與關閉操作的類

VO:主要由屬性,setter, getter方法組成,VO類中的屬性與表中的字段相對應,每一個VO類的對象都表示表中的每一條記錄;

DAO:主要定義操作的接口,定義一系列資料庫的原子性操作,例如增删改查等;

Impl: DAO接口的真實實作類,主要完成具體資料庫操作,但不負責資料庫的打開和關閉;

Proxy:代理實作類,主要完成資料庫的打開和關閉并且調用真實實作類對象的操作;

Factory: 工廠類,通過工廠類取得一個DAO的執行個體化對象。

對于包的命名:

在使用DAO時對包有嚴格的命名

資料庫連接配接: xxx.dbc.DatabaseConnection

DAO接口: xxx.dao.IXxxDAO

DAO接口真實實作類:xxx.dao.impl.XxxDAOImpl

DAO接口代理實作類:xxx.dao.proxy.XxxDAOProxy

VO類: xxx.vo.Xxx, VO命名要與表的命名一緻

工廠類:xxx.factory.DAOFactory.

DAO模式簡介

實施DAO模式 (Implementing DAO pattern)

使用上述元件,讓我們嘗試實作DAO模式。 我們将在這裡使用3個元件:

1.從一層轉移到另一層的book模型。

2.bookdao接口提供了靈活的設計和要實作的API。

3.BookDaoImpl具體類,它是bookdao接口的實作

DAO模式的優勢

使用DAO模式有很多優點。 讓我們在這裡聲明其中一些:

在更改持久性機制時,服務層甚至不必知道資料來自何處。 例如,如果您正在考慮從使用MySQL過渡到MongoDB,則所有更改僅需要在DAO層中完成。

DAO模式強調應用程式不同元件之間的低耦合。 是以,View層不依賴于DAO層,而僅Service層依賴于DAO層,即使依賴于接口,也不依賴于具體的實作。

由于持久性邏輯是完全獨立的,是以為單個元件編寫單元測試要容易得多。 例如,如果将JUnit和Mockito用于測試架構,則可以輕松模拟應用程式的各個元件。

當我們以DAO模式使用接口時,它還強調了“使用接口代替實作”的風格,這是一種出色的OOPs程式設計風格。

什麼情況下産生模式

當我們的業務和資料都要處理的時候,但是業務和資料都是不同的實作方式,但是它們之間又有聯系,是以這裡就産生了解耦概念。單獨封裝一個類來處理資料的代碼

當處理業務和資料的代碼在一起的時候,會出現以下情況:

1.維護困難因為每該一次資料都會影響業務代碼。

2.代碼複用比較低

3.編寫業務層代碼的人員必須要懂各種資料儲存方式

MyBatis開發Dao模式過程

Mybatis架構根據接口定義建立接口的動态代理對象,代理對象的方法體同上邊Dao接口實作類方法。

使用mapper代理的方法來開發dao時,程式員隻需要幹兩件事即可:

1、編寫mapper.xml映射檔案 2、編寫mapper接口(相當于dao接口)

Mapper接口開發需要遵循以下四個規範(建議初學者結合下圖了解): 1、Mapper.xml檔案中的namespace與mapper接口的類路徑相同。 2、Mapper接口方法名和Mapper.xml中定義的每個statement的id相同 3、Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同 4、Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同

Mapper接口開發四個規範屬實有點費勁,我就在掘金上廢了點勁找到了圖,友善了解:

DAO模式簡介

原始Dao開發方式

原始Dao開發方法需要程式員編寫Dao接口和Dao實作類。

  1. 編寫映射檔案

    編寫映射檔案如下:(也可以使用入門程式完成的映射檔案)

<?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">;

<!-- namespace:命名空間,用于隔離sql,還有一個很重要的作用,後面會講 -->

<mapper namespace="test">

<!-- 根據id查詢使用者 -->

<select id="queryUserById" parameterType="int"

resultType="com.gx.mybatis.pojo.User">

select * from user where id = #{id}

</select>

<!-- 根據username模糊查詢使用者 -->

<select id="queryUserByUsername" parameterType="string"

select * from user where username like '%${value}%'

<!-- 儲存使用者 -->

<insert id="saveUser" parameterType="com.gx.mybatis.pojo.User">

<selectKey keyProperty="id" keyColumn="id" order="AFTER"

resultType="int">

SELECT 1576193

</selectKey>

insert into user(username,birthday,sex,address)

values(#{username},#{birthday},#{sex},#{address})

</insert>

</mapper>

  1. 編寫Dao接口

    先進行DAO的接口開發,編碼如下:

public interface UserDao {

/**

  • 根據id查詢使用者
  • @param id
  • @return

    */

User queryUserById(int id);

  • 根據使用者名模糊查詢使用者
  • @param username

List<User> queryUserByUsername(String username);

  • 儲存使用者
  • @param user

void saveUser(User user);

}

3.編寫Dao實作類

編寫的Dao實作類如下

public class UserDaoImpl implements UserDao {

private SqlSessionFactory sqlSessionFactory;

public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {

super();

this.sqlSessionFactory = sqlSessionFactory;

@Override

public User queryUserById(int id) {

// 建立SqlSession

SqlSession sqlSession = this.sqlSessionFactory.openSession();

// 執行查詢邏輯

User user = sqlSession.selectOne("queryUserById", id);

// 釋放資源

sqlSession.close();

return user;

public List<User> queryUserByUsername(String username) {

List<User> list = sqlSession.selectList("queryUserByUsername", username);

return list;

public void saveUser(User user) {

// 執行儲存邏輯

sqlSession.insert("saveUser", user);

// 送出事務

sqlSession.commit();

4.編寫Dao測試

建立一個JUnit的測試類,對UserDao進行測試(充當main方法),測試代碼如下:

public class UserDaoTest {

@Before

public void init() throws Exception {

// 建立SqlSessionFactoryBuilder

SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

// 加載SqlMapConfig.xml配置檔案

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 建立SqlsessionFactory

this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);

@Test

public void testQueryUserById() {

// 建立DAO

UserDao userDao = new UserDaoImpl(this.sqlSessionFactory);

// 執行查詢

User user = userDao.queryUserById(1);

System.out.println(user);

public void testQueryUserByUsername() {

List<User> list = userDao.queryUserByUsername("五");

for (User user : list) {

public void testSaveUser() {

// 建立儲存對象

User user = new User();

user.setUsername("孫尚香腸");

user.setBirthday(new Date());

user.setSex("1");

user.setAddress("蜀國");

// 執行儲存

userDao.saveUser(user);

Mapper動态代理方式

1.定義Mapper.xml(映射檔案)

定義mapper映射檔案UserMapper.xml 将UserMapper.xml放在config下mapper目錄下,效果如下:

DAO模式簡介

2、編寫UserMapper.xml配置檔案内容:

<!-- namespace:命名空間,用于隔離sql -->

<!-- 還有一個很重要的作用,使用動态代理開發DAO,1. namespace必須和Mapper接口類路徑一緻 -->

<mapper namespace="com.gx.mybatis.mapper.UserMapper">

<!-- 根據使用者id查詢使用者 -->

<!-- 2. id必須和Mapper接口方法名一緻 -->

<!-- 3. parameterType必須和接口方法參數類型一緻 -->

<!-- 4. resultType必須和接口方法傳回值類型一緻 -->

<!-- 根據使用者名查詢使用者 -->

select 1576193

insert into user(username,birthday,sex,address) values

(#{username},#{birthday},#{sex},#{address});

3.編寫UserMapper(接口檔案)

建立UserMapper接口代碼如下:

public interface UserMapper {

  • 根據id查詢
  • 根據使用者名查詢使用者

4.加載UserMapper.xml檔案

修改SqlMapConfig.xml檔案,添加以下所示的内容:

<!-- 加載映射檔案 -->

<mappers>

<mapper resource="sqlmap/User.xml" />

<mapper resource="mapper/UserMapper.xml" />

</mappers>

5.編寫測試

編寫的測試方法如下:

public class UserMapperTest {

// 擷取sqlSession,和spring整合後由spring管理

// 從sqlSession中擷取Mapper接口的代理對象

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 執行查詢方法

User user = userMapper.queryUserById(1);

// 和spring整合後由spring管理

List<User> list = userMapper.queryUserByUsername("五");

user.setUsername("劉備胎");

user.setSex("2");

user.setAddress("鼠國");

userMapper.saveUser(user);