OA項目:SSH + JBPM框架(本項目使用註解方式開發) html
============================================ java
OA 辦公自動化系統 mysql
BBS 論壇系統 web
CRM 客戶關係管理系統 spring
CMS 內容管理系統 sql
1、什麼是OA 數據庫
輔助辦公、提升辦公效率的軟件系統。 apache
2、具體有哪些功能 數組
具體有哪些功能有用戶的需求肯定。 緩存
=============================================
1、軟件開發流程
1,需求分析
2,設計
3,編碼
4,測試
5,交付、運維
2、每一個環節具體作什麼事情
1,需求分析
需求分析文檔
效果頁面
2,設計
概要設計文檔
詳細設計文檔
3,編碼 <━━━━━━━━━┓
按照設計文檔實現功能 ┃
4,測試 ┃
測試工具、測試人員 ━━━━┫ 代碼管理工具(版本管理工具) / SVN / CVS / ...
功能測試報告 ┃
性能測試報告 ┃
5,交付、運維 ┃
發現BUG ━━━━━━━━━┛
增長新功能
3、咱們在哪一個環節
部分設計
主要編碼
部分測試
寫文檔
=============================================
1、咱們要實現的功能:
1,系統管理
2,系統權限
3,內部論壇
4,JBPM + 審批流轉
2、時間計劃
0,準備 + 基礎功能 1天
1,系統管理 2天
2,系統權限 2天
3,內部論壇 3天
4,JBPM + 審批流轉 2天 + 2天
3、總體設計
1,三層架構
View Struts2
Service JBPM
Dao Hibernate
2,所用技術
Struts2.1 + Spring2.5 + Hibernate3.x + jQuery1.x + JBPM4.4
3,開發環境
MyEclipse 8.6 ( Eclipse / Intellj idea / NetBeans / ... )
(我用的是EclipseMars Milestone 2 (4.5.0M2))
MySQL ( Oracle / SqlServer / DB2 / ... )
IE6 ( Chrome / IE9/ IE10 / Firefox / ... )
4,代碼規範
命名
註釋
空行
格式化代碼快捷鍵:Ctrl + Shift + F
原型 + 重構
5,約定
編碼使用utf-8
主鍵使用long型
第一天工做:搭建環境+基礎功能
步驟:
1、建立數據庫"itcastoa":
(注意編碼爲utf-8)
mysql> create database itcastoa default character set utf8;
mysql> show create database itcastoa;
2、建立Web工程
1,把默認的編碼設爲utf-8
java類
jsp文件
xml文件
2,添加框架環境(jar包、配置文件)
Junit4
JSTL
Struts2
Hibernate
Spring
其餘框架用到時再搭建(如JBPM)
除此之外,還要在web.xml中添加Struts2的核心過濾器,代碼詳見後文web.xml.
3,整合SSH(以及測試)
a, 整合Spring與Hibernate
目的:
讓Spring管理單例的SessionFactory
讓Spring管理事務(採用基於註解的方式)
步驟:
ApplicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 自動裝配與掃描bean --> <context:component-scan base-package="cn.itcast.oa"></context:component-scan>
<!-- 導入外部的jdbc.properties配置文件 --> <context:property-placeholder location="classpath:jdbc.properties"/>
<!-- ===========配置數據庫鏈接池=========== --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 數據庫鏈接信息 --> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="driverClass" value="${driverClass}"></property> <property name="user" value="${username}"></property> <property name="password" value="${password}"></property>
<!-- =========== 鏈接池的管理配置 =========== --> <!--初始化時獲取三個鏈接,取值應在minPoolSize與maxPoolSize之間。Default: 3 --> <property name="initialPoolSize" value="3"></property> <!--鏈接池中保留的最小鏈接數。Default: 3 --> <property name="minPoolSize" value="3"></property> <!--鏈接池中保留的最大鏈接數。Default: 15 --> <property name="maxPoolSize" value="5"></property> <!--當鏈接池中的鏈接耗盡的時候c3p0一次同時獲取的鏈接數。Default: 3 --> <property name="acquireIncrement" value="3"></property> <!-- 控制數據源內加載的PreparedStatements數量。若是maxStatements與maxStatementsPerConnection均爲0,則緩存被關閉。Default: 0 --> <property name="maxStatements" value="8"></property> <!--maxStatementsPerConnection定義了鏈接池內單個鏈接所擁有的最大緩存statements數。Default: 0 --> <property name="maxStatementsPerConnection" value="5"></property> <!--最大空閒時間,1800秒內未使用則鏈接被丟棄。若爲0則永不丟棄。Default: 0 --> <property name="maxIdleTime" value="1800"></property> </bean>
<!-- 配置SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> </bean>
<!-- 配置聲明式事務管理(採用基於註解的方式) --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <tx:annotation-driven transaction-manager="txManager"/>
</beans> |
Hibernate,cfg.xml:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration> <session-factory> <!-- 數據鏈接信息 <property name="hibernate.connection.url">jdbc:mysql:///itcastoa</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> --> <!-- 數據庫方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 其餘配置 --> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property>
<!-- 載入映射配置文件 --> <mapping resource="cn/itcast/oa/domain/User.hbm.xml"/>
</session-factory> </hibernate-configuration> |
Jdbc.properties:
jdbcUrl = jdbc:mysql:///itcastoa driverClass = com.mysql.jdbc.Driver username = root password = root |
Log4j.propertier:(後文講解如何配置)
# # Hibernate, Relational Persistence for Idiomatic Java # # License: GNU Lesser General Public License (LGPL), version 2.1 or later. # See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. #
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file hibernate.log ### #log4j.appender.file=org.apache.log4j.FileAppender #log4j.appender.file.File=hibernate.log #log4j.appender.file.layout=org.apache.log4j.PatternLayout #log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
# 默認的日誌顯示級別,表示指定級別和更高的級別都顯示 log4j.rootLogger=warn, stdout
# 指定cn.itcast.oa包中的日誌的顯示級別是debug log4j.logger.cn.itcast.oa=debug
### log HQL query parser activity #log4j.logger.org.hibernate.hql.ast.AST=debug
### log just the SQL #log4j.logger.org.hibernate.SQL=debug
### log JDBC bind parameters ### #log4j.logger.org.hibernate.type=info #log4j.logger.org.hibernate.type=debug
### log schema export/update ### #log4j.logger.org.hibernate.tool.hbm2ddl=debug
### log HQL parse trees #log4j.logger.org.hibernate.hql=debug
### log cache activity ### #log4j.logger.org.hibernate.cache=debug
### log transaction activity #log4j.logger.org.hibernate.transaction=debug
### log JDBC resource acquisition #log4j.logger.org.hibernate.jdbc=debug
### enable the following line if you want to track down connection ### ### leakages when using DriverManagerConnectionProvider ### #log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace |
測試階段:
Tips:測試最好一步步作,不要急於求成.
1,測試SessionFactory是否已經交由Spring管理:
新建一個包(裝測試類),在該包下新建一個測試類TestSpring.java,如圖:
TestSpring.java:
package cn.itcast.oa.test;
import org.hibernate.SessionFactory; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring {
private ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//測試SessionFactory @Test public void testSessionFactory() throws Exception{ SessionFactory sf = (SessionFactory) ac.getBean("sessionFactory"); System.out.println(sf.openSession()); } } |
運行測試,如果能在控制檯輸出session對象,則證實SessionFactory已經交由Spring管理.
2,測試Spring的事務管理(採用基於註解的方式):
1),新建domain包,建立一個簡單的JavaBean,寫好相應的映射文件,將映射文件載入hibernate.cfg.xml中,如圖:
User.java:
package cn.itcast.oa.domain; public class User { private Long id;
public Long getId() { return id; } public void setId(Long id) { this.id = id; } } |
User.hbm.xml:(在此規定了數據庫中相應的表名和字段名)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.itcast.oa.domain"> <class name="User" table="itcast_user"> <id name="id"> <generator class="native"></generator> </id>
</class> </hibernate-mapping> |
Hibernate.cfg.xml:
2),在測試包下新建TestService.java,如圖:
TestService.java:
package cn.itcast.oa.test;
import javax.annotation.Resource;
import org.hibernate.SessionFactory; import org.hibernate.classic.Session; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;
import cn.itcast.oa.domain.User;
@Service public class TestService {
@Resource private SessionFactory sessionFactory;
@Transactional public void saveTwoUsers(){ Session session = sessionFactory.getCurrentSession();
session.save(new User()); //int a = 1/0; //這行會拋異常 session.save(new User()); }
} |
解析:想要測試事務管理(要在方法名上加上註解@Transactional),就不能本身建立session(sessionFactory.OpenSession()),而是要獲取當前管理的session對象(sessionFactory.getCurrentSession()),而且這個sessionFactory也必須是經過獲取當前已經存在的sessionFactory而獲得,因此要注入(@Resource),要想注入就必須將對象放入容器中(@Service)交由Spring管理.
3),添加測試代碼
TestSpring.java:
package cn.itcast.oa.test;
import org.hibernate.SessionFactory; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring {
private ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//測試SessionFactory @Test public void testSessionFactory() throws Exception{ SessionFactory sf = (SessionFactory) ac.getBean("sessionFactory"); System.out.println(sf.openSession()); }
//測試事務管理 @Test public void testTx() throws Exception{ TestService testService = (TestService) ac.getBean("testService"); testService.saveTwoUsers(); } } |
測試方法:在TestService中去掉異常,執行TestSpring中的testTx()方法,此時控制檯出現兩條插入語句,表中正常添加兩條數據,表中數據狀況如圖(由於以前測試過好屢次,因此數據不是從1開始)
此時加上異常,若Spring已成功管理事務(要麼兩條事務都提交成功,要麼都失敗),則程序在執行第一條session.save(new User())遇到異常以後,事務會回滾,控制檯輸出一條插入語句,表中沒有任何數據被插入,但表中一個id=13的位置已經被佔用了.表中數據狀況如圖:
此時再去掉異常, 再進行測試,控制檯出現兩條插入語句,表中正常添加兩條數據,表中數據狀況如圖:
至此證實事務已經交由Spring管理.
如果兩個測試(SessionFactory和事務管理)都成功了,則Spring和Hibernate整個完畢.
b, 整合Spring與Struts2
目的:
讓Spring管理Action的實例(多例)。
這樣就能夠方便的注入依賴的對象了。
步驟:
1,Spring在Web應用中使用時要配置一個監聽器
爲了建立ApplicationContext對象
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 配置Spring的用於初始化ApplicationContext對象的監聽器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext*.xml</param-value> </context-param>
<!-- 配置Struts2的核心的過濾器 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> |
2,添加struts2-spring-plugin.jar
爲了讓Struts2從Spring的容器中拿Action對象
測試階段:
1),測試Struts2環境是否添加成功:
在測試包下添加TestAction.java,如圖:
在action中寫測試代碼,在strurs.xml中配置action,最後寫結果頁面
TestAction:
package cn.itcast.oa.test; import javax.annotation.Resource;
import org.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionSupport;
public class TestAction extends ActionSupport{
private TestService testService;
public String execute() throws Exception { System.out.println("------>TestAction.execute()"); return "success"; }
} |
Tip:syso:打印語句,syst:輸出該方法.
Struts.xml:
<package name="default" namespace="/" extends="struts-default">
<!-- 配置測試用的action --> <action name="Test" class="cn.itcast.oa.test.TestAction"> <result name="success">/test.jsp</result> </action>
</package> |
新建一個測試頁面,如圖:
該頁面只有一句話:Struts2的環境添加成功!
測試方法:啓動服務器,訪問http://localhost:8080/ItcastOA/Test.do,如果成功則控制檯會輸出該方法,頁面顯示Struts2的環境添加成功!
2),測試Strurs2與Spring的整合狀況:
TestAction:
package cn.itcast.oa.test; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionSupport;
@Controller public class TestAction extends ActionSupport{
@Resource private TestService testService;
public String execute() throws Exception { System.out.println("------>TestAction.execute()"); System.out.println("------>testService = "+testService);
return "success"; }
} |
此時Test.jsp上有兩句話:
Struts2的環境添加成功!<br/>
Struts2與Spring整合成功!
測試方法:啓動服務器,訪問http://localhost:8080/ItcastOA/Test.do,若控制檯輸出該方法和testService對象(在action中也能拿到service對象了),頁面顯示那兩句話,則證實Struts2和Spring整合成功.
2),測試Strurs2與Spring與Hibernate的整合狀況:
TestAction:
package cn.itcast.oa.test; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionSupport;
@Controller public class TestAction extends ActionSupport{
@Resource private TestService testService;
public String execute() throws Exception { System.out.println("------>TestAction.execute()"); System.out.println("------>testService = "+testService); testService.saveTwoUsers();
return "success"; } } |
此時Test.jsp上有三句話:
Struts2的環境添加成功!<br/>
Struts2與Spring整合成功! <br/>
Struts2與Spring與Hibernate整合成功!
測試方法:啓動服務器,訪問http://localhost:8080/ItcastOA/Test.do,用剛纔測試事務的方法來進行測試.觀察數據庫表中數據,控制檯輸出和頁面顯示,若結果相似,則代表SSH環境搭建成功.
Tips:當只改變方法體(代碼塊,即只修改方法中的內容)時,不須要重啓服務器,刷新頁面便可.若改變了類的結構,如方法名, 類名,類的字段,就須要重啓服務器了.
快捷鍵:ctr + o 按一次,顯示當前類包含的的全部字段,方法等,
再按一次會附加顯示繼承過來的全部字段,方法等.
4,基本配置:
日誌的配置步驟:
1),導入3個jar包
2),將hibernate-release-5.0.7.Final.zip\hibernate-release-5.0.7.Final\project\etc路徑下的log4j.properties複製到src目錄下,並作以下修改:
Log4j.properties:
# # Hibernate, Relational Persistence for Idiomatic Java # # License: GNU Lesser General Public License (LGPL), version 2.1 or later. # See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. #
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file hibernate.log ### #log4j.appender.file=org.apache.log4j.FileAppender #log4j.appender.file.File=hibernate.log #log4j.appender.file.layout=org.apache.log4j.PatternLayout #log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
# 默認的日誌顯示級別,表示指定級別和更高的級別都顯示 log4j.rootLogger=warn, stdout
# 指定cn.itcast.oa包中的日誌的顯示級別是debug log4j.logger.cn.itcast.oa=debug
### log HQL query parser activity #log4j.logger.org.hibernate.hql.ast.AST=debug
### log just the SQL #log4j.logger.org.hibernate.SQL=debug
### log JDBC bind parameters ### #log4j.logger.org.hibernate.type=info #log4j.logger.org.hibernate.type=debug
### log schema export/update ### #log4j.logger.org.hibernate.tool.hbm2ddl=debug
### log HQL parse trees #log4j.logger.org.hibernate.hql=debug
### log cache activity ### #log4j.logger.org.hibernate.cache=debug
### log transaction activity #log4j.logger.org.hibernate.transaction=debug
### log JDBC resource acquisition #log4j.logger.org.hibernate.jdbc=debug
### enable the following line if you want to track down connection ### ### leakages when using DriverManagerConnectionProvider ### #log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace |
3),測試:
在測試包下新建TestLog.java
TestLog.java:
package cn.itcast.oa.test;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestLog {
private Log log = LogFactory.getLog(TestLog.class);
// private Logger log = LoggerFactory.getLogger(TestLog.class);
@Test public void test() throws Exception { log.debug("這是debug級別"); // 調試 log.info("這是info級別"); // 信息 log.warn("這是warn級別"); // 警告 log.error("這是error級別"); // 錯誤 log.fatal("這是fatal級別"); // 嚴重錯誤
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); } } |
測試方法:修改log4j.properties中的兩個顯示級別,運行測試,觀察控制檯輸出.
5,資源分類
三,設計BaseDao和BaseDaoImpl:
新建一個base包,建立BaseDao接口,BaseDaoImpl實現類以及測試類,如圖:
代碼慢慢寫,先寫BaseDao,通用的方法有6個:1增1刪1改3查(經過id查,經過ids數組查多個,查全部).
再寫BaseDaoImpl實現類.寫方法的具體實現.其中會遇到兩個問題:1,獲取session2,T的具體類型未知. 將他們逐一解決即可.
在此:也能夠經過Hibernate模板類獲取session,但那個方式太過依賴模板類,且須要繼承模板類,單繼承…不能多繼承…
BaseDao.java:
package cn.itcast.oa.base; import java.util.List; import cn.itcast.oa.domain.User;
public interface BaseDao<T> {
/** * 保存實體 */ void save(T entity);
/** * 刪除實體 */ void delete(Long id);
/** * 更新實體 */ void update(T entity);
/** * 根據id查詢 */ T getById(Long id);
/** * 根據id數組查詢多個 */ List<T> getByIds(Long[] ids);
/** * 查詢全部 */ List<T> findAll(); } |
BaseDaoImpl.java:
package cn.itcast.oa.base; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import javax.annotation.Resource; import org.hibernate.Session; import org.hibernate.SessionFactory;
@SuppressWarnings("unchecked") public abstract class BaseDaoImpl<T> implements BaseDao<T> {
@Resource private SessionFactory sessionFactory; protected Class<T> clazz = null;
public BaseDaoImpl() { //經過反射獲取T的真實類型 this是子類 ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
System.out.println("---> clazz = " + clazz); }
/** * 獲取session */ protected Session getSession() { return sessionFactory.getCurrentSession(); }
/** * 保存實體 */ public void save(T entity) { getSession().save(entity); }
/** * 更新實體 */ public void update(T entity) { getSession().update(entity); }
/** * 刪除實體 */ public void delete(Long id) { if (id == null) { return; }
Object entity = getById(id); if (entity != null) { getSession().delete(entity); } }
/** * 根據id查詢 */ public T getById(Long id) { return (T) getSession().get(clazz, id); }
/** * 根據id數組查詢多個 */ public List<T> getByIds(Long[] ids) { // 注意空格 sql語句:from與類名之間有一空格不能省略 方法鏈的調用 return getSession().createQuery(// "from " + clazz.getSimpleName() + "where id in (:ids)")// .setParameterList("ids", ids)//注意:必定要使用setParameterList()方法 .list(); }
/** * 查詢全部 */ public List<T> findAll() { // 注意空格 return getSession().createQuery("from " + clazz.getSimpleName()).list(); } } |
BaseDaoTest:
package cn.itcast.oa.base; import org.junit.Test;
import cn.itcast.oa.dao.RoleDao; import cn.itcast.oa.dao.UserDao; import cn.itcast.oa.dao.impl.RoleDaoImpl; import cn.itcast.oa.dao.impl.UserDaoImpl; import cn.itcast.oa.domain.Role; import cn.itcast.oa.domain.User;
public class BaseDaoTest {
@Test public void testGetById() { UserDao userDao = new UserDaoImpl(); RoleDao roleDao = new RoleDaoImpl();
User user = userDao.getById(1L); Role role = roleDao.getById(1L); } } |
此測試代碼是爲了測試是否能經過反射獲取到T的真實類型.
運行測試代碼,觀察控制檯是否有相應的T類型輸出.(在此爲User和Role)
設計好BaseDao和BaseDaoImpl以後,未來全部的DaoImpl都要繼承BaseDaoImpl,傳遞T的具體類型,另外必定要將DaoImpl放入容器中(即在類上加註解@Repository),(本身獨有的方法再在本身的接口中聲明)
Dao,DaoImpl,BaseDao,BaseDaoImpl之間的關係可用下圖舉例說明:
再好比:
UserDao:
package cn.itcast.oa.dao; import java.util.List; import cn.itcast.oa.base.BaseDao; import cn.itcast.oa.domain.User;
public interface UserDao extends BaseDao<User>{ User getByNameAndPasswd(); } |
UserDaoImpl:
package cn.itcast.oa.dao.impl;
import java.util.List;
import org.springframework.stereotype.Repository;
import cn.itcast.oa.base.BaseDaoImpl; import cn.itcast.oa.dao.UserDao; import cn.itcast.oa.domain.User;
@Repository public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{
public User getByNameAndPasswd() { return null; } } |
Tip:小技巧(巧用//)
當代碼過長時,能夠利用多個//調格式,這樣在ctrl+shift+f格式化代碼以後,以前調好的多行代碼也不會再擠到一行上了.
好比下面的代碼是方法鏈的調用,在手動將代碼分紅幾行以後(沒加//),格式化代碼,他們又會擠到一行上.如果巧妙加上//就不會出現這樣狀況.
getSession().createQuery(//
"from " + clazz.getSimpleName() + "where id in (:ids)")//
.setParameterList("ids", ids)//注意:必定要使用setParameterList()方法
.list();