Day01搭建環境+抽取dao(整合SSH+設計BaseDao和BaseDaoImpl)

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>

        

        <!-- =========== 鏈接池的管理配置 =========== -->

        <!--初始化時獲取三個鏈接,取值應在minPoolSizemaxPoolSize之間。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數量。若是maxStatementsmaxStatementsPerConnection均爲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();

相關文章
相關標籤/搜索