首先在搭建一个网站后台前,须要明确出一个合理的网页搭建的结构框架,即从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&characterEncoding=UTF-8</value> <value>jdbc:mysql://123.206.82.174:3306/moneyrecordsys?useUnicode=true&characterEncoding=UTF-8</value> <value>jdbc:mysql://123.56.23.127:3306/moneyrecordsys?useUnicode=true&characterEncoding=UTF-8</value> --> <value>jdbc:mysql://123.56.23.127:3306/moneyrecordsys?useUnicode=true&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层就已经搭建完成。