SpringMVC + Hibernate + MySQL 的簡易網頁搭建(Dao層 實現篇)

首先在搭建一個網站後臺前,須要明確出一個合理的網頁搭建的結構框架,即從DB  ==>  Dao層 ==>Service層 ==>Control層 ==>View層(該層嚴格意義上不屬於後臺)當中,各層的概念和設計思路。前端

 

Dao層(Data Acess Object):所謂的Dao層,主要是網頁的數據持久層的工做,負責與數據庫進行聯絡的一些任務都封裝在此,包括網頁數據當中的增刪改查,DAO層的設計首先是設計DAO的接口的抽象,而後在Spring的配置文件中定義此接口的實現類,以後對於上一層的service層來講,不須要關注此接口的具體實現類是哪一個類,只須要關注這個接口能實現的功能便可,顯得結構很是清晰,DAO層的數據源配置,以及有關數據庫鏈接的參數都在Spring的配置文件中進行配置。   java

 

Service層:主要負責業務模塊的邏輯應用設計。一樣是首先設計接口,再設計其實現的類,接着再Spring的配置文件中配置其實現的關聯。這樣咱們就能夠在應用中調用Service接口來進行業務處理。Service層的業務實現,具體要調用到已定義的DAO層的接口,封裝Service層的業務邏輯有利於通用的業務邏輯的獨立性和重複利用性,程序顯得很是簡潔。mysql

 

Controller層:負責具體的業務模塊流程的控制,在此層裏面要調用Serice層的接口來控制業務流程,而且控制前端相應的操做以後,頁面須要如何跳轉,做出何種反應等。控制的配置也一樣是在Spring的配置文件裏面進行,針對具體的業務流程,會有不一樣的控制器,咱們具體的設計過程當中能夠將流程進行抽象概括,設計出能夠重複利用的子單元流程模塊,這樣不只使程序結構變得清晰,也大大減小了代碼量。web

 

View層:此層與控制層結合比較緊密,須要兩者結合起來協同工發。View層主要負責前臺jsp頁面的表示。spring

 

在本文當中介紹的例子當中,由於不存在太複雜的業務處理邏輯,因此不單獨抽象出Service層進行設計,即在本文當中,Service層和Dao層合併爲一層,負責處理簡單的業務。網頁主要功能是記錄在本網頁當中註冊的用戶之間的債務關係,而且有借債的詳情。做爲Admin的用戶可對其餘用戶數據進行管理。如下是網頁的效果圖:sql

 

首先是工程搭建,在eclipseEE下,建立一個Dynamic web project,以後將所須要用到的Spring和hibernate的jar包複製到 WEB-INF目錄下的lib文件夾當中,而且build the path,本文中採用的是Spring 4.2.5和Hibernate 5.1.0版本:數據庫

1.將Hibernate5.1.0根目錄下的 /lib/required和 /lib/java8目錄下的jar複製到上述WEB-INF目錄下的lib文件夾session

2.將Spring根目錄下的 /libs 下的全部jar包也引入到WEB-INF目錄下的lib文件夾,則開發環境搭建完畢。app

接下來根據咱們的網頁搭建的設計思路,首先須要設計DB的持久化結構,即數據庫的表結構,由於根據需求,咱們知道須要存儲網頁的註冊用戶信息,而且還要存儲各個用戶之間的欠債關係,因此至少須要兩張表格。表結構設計以下:框架

1.數據庫名moneyrecordsys。

2.表格MoneyRecordInfo

3.表格UserInfo

DB的持久化結構設計完成之後,咱們開始根據咱們須要的功能,抽象Dao當中的接口以及接口功能:

1.用戶信息的Dao接口,依據咱們的需求,咱們須要對用戶信息的表進行一下操做,常規的增刪改查,以及根據用戶名進行用戶查詢,根據密碼進行用戶查詢,查詢返回全部用戶等功能(在起初設計的時候,很難一次性想全全部的功能,因此咱們前文提出的設計思路,是一個反覆的過程,即在Dao接口設計完要去完成Control層的實現發現缺少某些功能的時候,還須要返回到Dao層進行添加)

package Fmu.wellhold.dao.ITF;

import java.util.List;

public interface UserInfoDaoITF {

    public void delete(Integer number);
    public List<Object>findAll();
    public Object findByld(Integer number);
    public void insert(Object o);
    public void update(Object o);
    public List findByNamePwd(String id,String pwd);
    public boolean findByName(String id);

}

2.債務信息的Dao接口,與用戶信息的Dao接口設計思路雷同,此處再也不進行贅述

package Fmu.wellhold.dao.ITF;

import java.util.List;

public interface MoneyRecordInfoDaoITF {

    public void delete(Integer number);
    public List<Object>findAll();
    public Object findByld(Integer number);
    public void insert(Object o);
    public void update(Object o);
    
}

以後是對Dao層接口的實現,在實現接口以前,咱們須要在Spring的配置文件當中,配置hibernate與數據庫的聯通,此處鏈接池咱們使用的是C3P0(注意引C3P0相應的jar包)。首先在Spring的配置數據庫鏈接池

 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
        <property name="driverClass">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="jdbcUrl">
            <!-- 
            <value>jdbc:mysql://localhost:3306/moneyrecordsys?useUnicode=true&amp;characterEncoding=UTF-8</value> 
            <value>jdbc:mysql://123.206.82.174:3306/moneyrecordsys?useUnicode=true&amp;characterEncoding=UTF-8</value>
            <value>jdbc:mysql://123.56.23.127:3306/moneyrecordsys?useUnicode=true&amp;characterEncoding=UTF-8</value>
            -->
            <value>jdbc:mysql://123.56.23.127:3306/moneyrecordsys?useUnicode=true&amp;characterEncoding=UTF-8</value> 
            
        </property>
                <property name="user">
            <value>root</value>
        </property>
        <property name="password">
            <value>root</value>
        </property>
        <!--鏈接池中保留的最小鏈接數。-->
        <property name="minPoolSize" value="10"/>
        <!--鏈接池中保留的最大鏈接數。Default: 15 -->
        <property name="maxPoolSize" value="100"/>
        <!--最大空閒時間,1800秒內未使用則鏈接被丟棄。若爲0則永不丟棄。Default: 0 -->
        <property name="maxIdleTime" value="1800"/>
        <!--當鏈接池中的鏈接耗盡的時候c3p0一次同時獲取的鏈接數。Default: 3 -->
        <property name="acquireIncrement" value="3"/>
        <property name="maxStatements" value="1000"/>
        <property name="initialPoolSize" value="10"/>
        <!--每60秒檢查全部鏈接池中的空閒鏈接。Default: 0 -->
        <property name="idleConnectionTestPeriod" value="60"/>
        <!--定義在從數據庫獲取新鏈接失敗後重復嘗試的次數。Default: 30 -->
        <property name="acquireRetryAttempts" value="30"/>
        <property name="breakAfterAcquireFailure" value="true"/>
        <property name="testConnectionOnCheckout" value="false"/>
    </bean>

配置好鏈接池以後,咱們須要創建hibernate POJO類到數據的hbm映射配置文件。此處補充一個定義POJO類(POJO(Plain Ordinary Java Object)若是項目中使用了Hibernate框架,有一個關聯的xml文件,使對象與數據庫中的表對應,對象的屬性與表中的字段相對應。

package Fmu.wellhold.dao.pojo;

import java.io.Serializable;
import java.util.Date;

public class MoneyRecordInfo implements Serializable{

    private Integer number;
    private Integer money;
    private Date date;
    private String owner;
    private String debtor;
    private String remarks;
    
    public MoneyRecordInfo()
    {
        
    }
    
    public MoneyRecordInfo(Integer number, Integer money, Date date, String owner, String debtor, String remarks) {
        super();
        this.number = number;
        this.money = money;
        this.date = date;
        this.owner = owner;
        this.debtor = debtor;
        this.remarks = remarks;
    }

    @Override
    public String toString() {
        return "MoneyRecordInfo [number=" + number + ", money=" + money + ", date=" + date + ", owner=" + owner
                + ", debtor=" + debtor + ", remarks=" + remarks + "]";
    }

    public Integer getNumber() {
        return number;
    }
    public void setNumber(Integer number) {
        this.number = number;
    }
    public Integer getMoney() {
        return money;
    }
    public void setMoney(Integer money) {
        this.money = money;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public String getOwner() {
        return owner;
    }
    public void setOwner(String owner) {
        this.owner = owner;
    }
    public String getDebtor() {
        return debtor;
    }
    public void setDebtor(String debtor) {
        this.debtor = debtor;
    }
    public String getRemarks() {
        return remarks;
    }
    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }
    
}
package Fmu.wellhold.dao.pojo;

import java.io.Serializable;
import java.util.Date;

public class UserInfo implements Serializable{
    
    private Integer number;
    private String id;
    private String name;
    private String Sex;
    private Date birthday;
    private String come;
    private String pwd;
    private String remark;
    
    public UserInfo(){}

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return Sex;
    }

    public void setSex(String sex) {
        Sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getCome() {
        return come;
    }

    public void setCome(String come) {
        this.come = come;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }



    public UserInfo(Integer number, String id, String name, String sex, Date birthday, String come, String pwd,
            String remark) {
        super();
        this.number = number;
        this.id = id;
        this.name = name;
        Sex = sex;
        this.birthday = birthday;
        this.come = come;
        this.pwd = pwd;
        this.remark = remark;
    }
    
    @Override
    public String toString() {
        return "UserInfo [number=" + number + ", id=" + id + ", name=" + name + ", Sex=" + Sex + ", birthday="
                + birthday + ", come=" + come + ", pwd=" + pwd + ", remark=" + remark + "]";
    }

}

有了pojo類做爲數據庫條目到java的對象以後,須要創建相應的映射,即hbm.xml(此處如不熟悉什麼的hbm.xml概念的同窗,能夠自行查閱Hibernate的使用手冊)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping package="Fmu.wellhold.dao.pojo">
    <class name="UserInfo" table="UserInfo">
    <!-- 選擇pojo類 -->
        <id name="number" type="java.lang.Integer">
            <column name="number"/>
            <generator class="native"/>
        </id>
        <!-- 配置序號,即主鍵的 -->
        
        <!-- 配置其餘項 -->
        <property name="id" type="java.lang.String">
            <column name="id">
                <comment>登錄名稱</comment>
            </column>
        </property>
        
        <property name="name" type="java.lang.String">
            <column name="name">
                <comment>姓名</comment>
            </column>
        </property>
        
        
        <property name="sex" type="java.lang.String">
            <column name="sex">
                <comment>性別</comment>
            </column>
        </property>
                
        <property name="birthday" type="java.util.Date">
            <column name="birthday">
                <comment>生日</comment>
            </column>
        </property>
                
        <property name="come" type="java.lang.String">
            <column name="come">
                <comment>報道時間</comment>
            </column>
        </property>
                
        <property name="pwd" type="java.lang.String">
            <column name="pwd">
                <comment>密碼</comment>
            </column>
        </property>
                
        
        <property name="remark" type="java.lang.String">
            <column name="remark">
                <comment>我的介紹</comment>
            </column>
        </property>
        
    </class>
    
    
    
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping package="Fmu.wellhold.dao.pojo">
    <class name="MoneyRecordInfo" table="MoneyRecordInfo">
    
        <id name="number" type="java.lang.Integer">
            <column name="number"/>
            <generator class="native"/>
        </id>
    
        <property name="date" type="java.util.Date">
            <column name="date">
                <comment>欠款日期</comment>
            </column>
        </property>
        
        <property name="owner" type="java.lang.String">
            <column name="owner">
                <comment>出錢人</comment>
            </column>
        </property>
        
        <property name="debtor" type="java.lang.String">
            <column name="debtor">
                <comment>欠債人</comment>
            </column>
        </property>
        
        <property name="money" type="java.lang.Integer">
            <column name="money">
                <comment>金額</comment>
            </column>
        </property>
        
        <property name="remarks" type="java.lang.String">
            <column name="remarks">
                <comment>備註</comment>
            </column>
        </property>
    
    </class>
    

    
</hibernate-mapping>

由於hibernate是經過對Session這個接口去對數據庫進行增刪改查的操做的,創建好數據庫到對象的映射以後,還須要在Spring的配置文件中,配置hibernate的sessionFactory:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>Fmu/wellhold/hbm/UserInfo.hbm.xml</value>
                <value>Fmu/wellhold/hbm/MoneyRecordInfo.hbm.xml</value>
                <!-- 能夠直接索引到代碼目錄 -->
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.format_sql">false</prop>
            </props>            
        </property>
    </bean>

以後在註冊一個對於基於該session的事務管理器,便可開始咱們的後臺Dao層的接口實現工做

    <bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <!-- 開啓TX的註釋模式,加載註釋驅動 -->
    <tx:annotation-driven transaction-manager="txManager"/>

首先實現債務信息接口功能:

package Fmu.wellhold.dao.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import Fmu.wellhold.dao.ITF.MoneyRecordInfoDaoITF;
import Fmu.wellhold.dao.pojo.MoneyRecordInfo;

@Transactional
@Service("moneyRecordInfoService")
public class MoneyRecordInfoService implements MoneyRecordInfoDaoITF {

    @Resource private SessionFactory sessionFactory;
    
    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public void delete(Integer number) {
        MoneyRecordInfo moneyRecordInfo = (MoneyRecordInfo)sessionFactory.getCurrentSession().get(MoneyRecordInfo.class, number);
        sessionFactory.getCurrentSession().delete(moneyRecordInfo);        
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public List<Object> findAll() {
        List list = new ArrayList<>();
        list=sessionFactory.getCurrentSession().createQuery("from MoneyRecordInfo").list();
        return list;
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public Object findByld(Integer number) {
        MoneyRecordInfo moneyRecordInfo = (MoneyRecordInfo)sessionFactory.getCurrentSession().get(MoneyRecordInfo.class, number);
        return moneyRecordInfo;
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public void insert(Object o) {
        System.out.println("o:"+o.toString());
        sessionFactory.getCurrentSession().save(o);

    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public void update(Object o) {
        System.out.println("update"+o.toString());
        sessionFactory.getCurrentSession().update(o);

    }

}

以後是用戶信息的接口代碼:

package Fmu.wellhold.dao.service;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import Fmu.wellhold.dao.ITF.UserInfoDaoITF;
import Fmu.wellhold.dao.pojo.UserInfo;

@Transactional
@Service("UserInfoService")
public class UserInfoService implements UserInfoDaoITF {

    @Resource private SessionFactory sessionFactory;
    
    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public void delete(Integer number) {
        UserInfo user = (UserInfo)sessionFactory.getCurrentSession().get(UserInfo.class,number);
        sessionFactory.getCurrentSession().delete(user);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED,readOnly=true)
    public List<Object> findAll() {
        List list = sessionFactory.getCurrentSession().createQuery("from UserInfo").list();
        return list;
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED,readOnly=true)
    public Object findByld(Integer number) {
        UserInfo user=(UserInfo)sessionFactory.getCurrentSession().get(UserInfo.class, number);
        return user;
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public void insert(Object o) {
        sessionFactory.getCurrentSession().save(o);

    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public void update(Object o) {
        sessionFactory.getCurrentSession().update(o);

    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED,readOnly=true)
    public List findByNamePwd(String id1, String pwd) {
        List list = sessionFactory.getCurrentSession().createQuery("FROM UserInfo WHERE id='"+id1+"' AND pwd='"+pwd+"'").list();
        return list;
    }

    @Override
    public boolean findByName(String id) {
        List list = sessionFactory.getCurrentSession().createQuery("FROM UserInfo WHERE id="+id+"").list();
        if(list.isEmpty())return true;
        
        return false;
    }

}

將兩個實現類註冊到Spring的配置文件當中,利用@Service註解的方式,只須要在Spring的配置文件beans.xml當中添加如下聲明便可:

    <!-- 開啓Spring註釋功能,掃描下包當中是否含有註釋項 -->
    <context:annotation-config/>
    <context:component-scan base-package="Fmu.wellhold.controller"/>
    <context:component-scan base-package="Fmu.wellhold.dao.service"/>

至此,咱們的Dao層(本例中Service層與Dao層不進行區分)就已經實現完成,能夠經過一個測試例進行測試

package Fmu.wellhold.controller;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import Fmu.wellhold.dao.ITF.MoneyRecordInfoDaoITF;
import Fmu.wellhold.dao.ITF.UserInfoDaoITF;

public class BackGroundTest {
    
    private static UserInfoDaoITF userInfoDaoITF;
    private static MoneyRecordInfoDaoITF moneyRecordInfoDaoITF;

    public static void main(String[] args) {
    
        ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
    
        System.out.println(">>>>    測試SpringMVC後臺功能");
        userInfoDaoITF=(UserInfoDaoITF)ctx.getBean("UserInfoService");
        moneyRecordInfoDaoITF=(MoneyRecordInfoDaoITF)ctx.getBean("moneyRecordInfoService");
        System.out.println(userInfoDaoITF.findByld(1));
        System.out.println(moneyRecordInfoDaoITF.findAll().size());
        
    }

}

若是能返回正確數據,說明咱們DAO層就已經搭建完成。

相關文章
相關標籤/搜索