1. 程式人生 > >框架學習(1)——service層,dao層和service實現類進行資料庫操作

框架學習(1)——service層,dao層和service實現類進行資料庫操作

最近也是比較忙,也只能忙裡偷閒地抓緊時間接著學習一下技術,自從上次學習了maven之後,越來越對框架產生了興趣,下了好多的spring視屏,聽著老師的建議,最近也萌生了看別人的程式碼進行學習的想法,然後就上了知乎搜了搜優秀的java框架,發現了一個比較感興趣的,符合最近在學習的方面的專案。

不多說,開始主題

  • 訪問資料庫的傳統方法
    傳統訪問資料庫的方法非常面向過程,分為以下幾步
    – 例項化connection
    – 例項化statement
    – 通過statement的引數sql語句訪問資料庫,返回資料進行處理
程式碼:
import java.sql.Statement;
import java.util.Properties; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; public class DBAccess { public static void main(String[] args) throws SQLException, FileNotFoundException, IOException { DBAccess access = new
DBAccess(); access.test(); } private void test() throws SQLException, FileNotFoundException, IOException { String url = "jdbc:postgresql://localhost:5432/rylynn"; Properties p = new Properties(); p.load(new FileInputStream("reg.txt")); Connection connection = DriverManager.getConnection(url,p); //建立connection
Statement statement = connection.createStatement(); //建立satatement statement.execute("insert into abo values((001),'hnb')"); //執行sql語句 ResultSet resultSet = statement.executeQuery("select number from abo where number < 2"); while(resultSet.next()) { int id = resultSet.getInt(1); // String name = resultSet.getString(1); System.out.println("ID:" + id); } statement.close(); connection.close(); } }

傳統資料庫訪問模式缺點顯而易見:
一就是各個模組間的耦合太緊,statement要依賴connection,connection還依賴於資料庫的種類。
二就是如果我改變的資料庫的種類,或者要提供不同的資料庫服務,那麼我就要提供大量的重複程式碼。

面向抽象的程式設計思想告訴我們要面向介面程式設計,這種程式設計模式的好處就是,各個模組之間分工明確,而且互不干擾,首先介紹一下各個層次之間分工。

  • dao層:dao層叫資料訪問層,全稱為data access object,屬於一種比較底層,比較基礎的操作,具體到對於某個表、某個實體的增刪改查
  • service層:service層叫服務層,被稱為服務,肯定是相比之下比較高層次的一層結構,相當於將幾種操作封裝起來,至於為什麼service層要使用介面來定義有以下幾點好處:
    • 在java中介面是多繼承的,而類是單繼承的,如果你需要一個類實現多個service,你用介面可以實現,用類定義service就沒那麼靈活
    • 要提供不同的資料庫的服務時,我們只需要面對介面用不同的類實現即可,而不用重複地定義類
    • 程式設計規範問題,介面化的程式設計為的就是將實現封裝起來,然呼叫者只關心介面不關心實現,也就是“高內聚,低耦合”的思想。
  • service實現類:也顧名思義,service實現類實現了service介面,進行具體的業務操作。

這裡用C0de8ug公開在github上面的專案的程式碼來說明

dao層、service層以及service實現類的結構:

這裡寫圖片描述

專案中使用了mybatis框架進行資料庫的操作
以對於user的操作為例進行說明:
userdao:

public interface UserDao {

    public List<User> findAll();

    public User findById(String id);

    public void update(User user);

    public void add(User user);

    public void delete(String id);

    public User findByIdAndPassword(@Param("id") String username, @Param("password") String password);

    public void updatePassword(@Param("userId") String id, @Param("password") String password);

    User findByUsername(String username);}

在介面中對方法進行了定義,在UserDao.xml中給出了sql語句實現
在UserDao中,就對user這個實體的增刪補查各類基本的操作進行了宣告,並用mybatis框架進行實現。

下面給出部分UserDao.xml的程式碼

<select id="findAll" resultMap="user_map">
        SELECT * FROM user WHERE user_id != 'admin'
    </select>

    <select id="findById" parameterType="String" resultMap="user_map">
        SELECT * FROM user WHERE user_id = #{value}
    </select>

    <update id="update" parameterType="User">
        UPDATE user SET password = #{password} ,authority = #{authority} WHERE user_id = #{userId}
    </update>

    <update id="updatePassword" parameterType="map">
        UPDATE user SET password = #{password} WHERE user_id = #{userId}
    </update>

    <insert id="add" parameterType="User">
        INSERT INTO user(user_id,password,salt,role_ids,locked) VALUES(#{userId},#{password},#{salt},#{roleIdsStr},#{locked})
    </insert>

    <select id="findByIdAndPassword" parameterType="map" resultMap="user_map">
        SELECT * FROM user WHERE user_id = #{id} AND password = #{password}
    </select>

下面來看看service層的程式碼

import com.giit.www.entity.User;
import com.giit.www.entity.custom.UserVo;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Set;

/**
 * Created by c0de8ug on 16-2-9.
 */
public interface UserBiz {
    public List<UserVo> findAll() throws InvocationTargetException, IllegalAccessException;

    public User findById(String id);

    public void update(User user);

    public void add(User user);

    public void delete(String id);

    public void changePassword(String userId, String newPassword);


    public User findByUsername(String username);

    public Set<String> findRoles(String username);

    public Set<String> findPermissions(String username);
}

顯然,service層裡面的方法相較於dao層中的方法進行了一層包裝,例如通過id查詢使用者,通過使用者名稱查詢使用者,是在基礎的操作上又增加了一層包裝的,實現的是相對高階的操作。最後將這些操作在serviceimpl類中實現,程式碼比較多,這裡還是隻給出了部分程式碼,

import com.giit.www.college.dao.StaffDao;
import com.giit.www.entity.Role;
import com.giit.www.entity.Staff;
import com.giit.www.entity.User;
import com.giit.www.entity.custom.UserVo;
import com.giit.www.system.dao.RoleDao;
import com.giit.www.system.dao.UserDao;
import com.giit.www.system.service.RoleBiz;
import com.giit.www.system.service.UserBiz;
import com.giit.www.util.PasswordHelper;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * Created by c0de8ug on 16-2-9.
 */

@Service
public class UserBizImpl implements UserBiz {

    @Resource
    UserDao userDao;

    @Resource
    RoleDao roleDao;

    @Resource
    StaffDao staffDao;

    @Resource
    private PasswordHelper passwordHelper;
    @Resource(name = "roleBizImpl")
    private RoleBiz roleBiz;

    @Override
    public List<UserVo> findAll() throws InvocationTargetException, IllegalAccessException {
        List<UserVo> userVoList = new ArrayList<>();
        List userList = userDao.findAll();


        Iterator iterator = userList.iterator();

        while (iterator.hasNext()) {
            StringBuilder s = new StringBuilder();
            User user = (User) iterator.next();
            List<Long> roleIds = user.getRoleIds();

            UserVo userVo = new UserVo();
            BeanUtils.copyProperties(userVo, user);

            if (roleIds != null) {
                int i = 0;
                int size = roleIds.size();
                for (; i < size - 1; i++) {
                    Role role = roleDao.findOne(roleIds.get(i));

                    s.append(role.getDescription());
                    s.append(",");
                }
                Role role = roleDao.findOne(roleIds.get(i));
                s.append(role.getDescription());
                userVo.setRoleIdsStr(s.toString());
            }


            userVoList.add(userVo);

        }

        return userVoList;
    }

由此看到,這樣進行分層,訪問資料庫和進行service之間的分工明確,如果我需要對service的需求修改,無需改變dao層的程式碼,只要在實現上改變即可,如果我有訪問資料庫的新需求,那我也只要在dao層的程式碼中增添即可。