Spring 學習筆記02

用spring實現一個論壇基本功能

1 運行環境

Linux:Ubun 14.04 64bitjava

IDE:IntelliJ IDEA 14.03mysql

JDK:1.7.40git

MySQL:5.5.44github

Tomcat:7.0.47web

Maven:3.0.5spring

2 具體步驟

新建一個Webapp工程,名字就叫spring-bbs-demo 項目的目錄結構以下:

├── pom.xml
├── README.MD
├── spring-bbs-demo.iml
└── src
   └── main
       ├── resources
       └── webapp
           ├── index.jsp
           └── WEB-INF
               └── web.xml

在mysql裏建立兩張表,數據庫名爲sampledb

DROP DATABASE IF EXISTS sampledb;
CREATE DATABASE sampledb DEFAULT CHARACTER SET utf8mb4;
USE sampledb;

-- 建立用戶表
CREATE TABLE t_user (
 user_id INT AUTO_INCREMENT NOT NULL COMMENT '用戶id',
 user_name VARCHAR(30) NOT NULL DEFAULT '' COMMENT '用戶名',
 credits INT NOT NULL DEFAULT 0 COMMENT '論壇積分',
 password VARCHAR(32) NOT NULL DEFAULT ''COMMENT '用戶密碼',
 last_visit TIMESTAMP NOT NULL DEFAULT 0 COMMENT '最後訪問時間',
 last_ip VARCHAR(23) NOT NULL DEFAULT '0.0.0.0' COMMENT '最後訪問ip',
 PRIMARY KEY (user_id)
)ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT '用戶表';

-- 建立用戶登錄日誌表
CREATE TABLE t_login_log (
 login_log_id INT AUTO_INCREMENT NOT NULL COMMENT '日誌id',
 user_id INT NOT NULL DEFAULT 0 COMMENT '用戶id',
 ip VARCHAR(23) NOT NULL DEFAULT '0.0.0.0' COMMENT '訪問ip',
 login_datetime TIMESTAMP NOT NULL DEFAULT 0 COMMENT '訪問時間',
 PRIMARY KEY (login_log_id)
)ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT '用戶登錄日誌表';

INSERT INTO t_user (user_name,password) VALUES ('admin','123456');

最終項目目錄結構

├── pom.xml
├── README.MD
├── spring-bbs-demo.iml
└── src
   └── main
       ├── java
       │   └── com
       │       └── springbbs
       │           ├── dao
       │           ├── domain
       │           └── service
       ├── resources
       │   └── sql
       │       └── user_table_init.sql
       └── webapp
           ├── index.jsp
           └── WEB-INF
               └── web.xml

NOTE:java爲代碼根目錄,若是不是,能夠在java文件夾上右擊->Mark Directory As->Resources Root
同理,resources爲資源根目錄,webappweb根目錄,test目錄下的java文件夾爲TestR Resources Root目錄sql

文件及文件夾相關函數

文件 解釋
applicationContext.xml Spring容器配置文件
domain 領域對象(實體類)存放文件夾,每每擁有對應的數據庫表,通常要實現Serializable接口,以便序列化
dao 訪問實體類的接口,通常一個實體類都會有一個dao與之對應,裏面有一些對應的方法
jdbcTemplate Spring對jdbc的簡單封裝,能夠輕鬆完成大部分的數據庫操做而沒必要頻繁的重複對數據庫的打開,獲取鏈接,查詢,關閉等操做
jdbcTemplate#query() query(String sql,Object[] args,RowCallbackHandler rch).第一個參數不解釋了;第二個是佔位符(?)對應的參數數據;第三個是查詢結果的處理回調接口,該回調接口有一個方法processRow(ResultSet resultSet)負責將查詢結果從ResultSet裝載到相似於實例類對象的實例中。通常都是使用匿名內部類的方式來調用RowCallbackHandler接口

NOTE:在DAO文件中寫的sql語句比較長,多行銜接要注意空格,否則會連在一塊兒,具體小技巧是每一行最後加個空格。數據庫

Spring中配置

以上兩個DAO實現類中並無打開/和釋放Connection,到底如何訪問數據庫呢?答案是jdbcspring封裝起來了,JdbcTemplate須要一個dataSource,從數據源中獲取或返回鏈接。因此在UserDaoLoginLogDao中都提供了一個帶@Autowired註解的jdbcTemplate對象。 因此咱們須要先申明一個數據源,而後再定義一個JdbcTemplate Bean,經過Spring的容器上下文自動綁定機制進行Bean的注入。配置文件在Resources文件夾下,名字叫applicationContext.xml,內容以下:express

<?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:p="http://www.springframework.org/schema/p"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

   <!-- 1 加載配置文件 -->
   <context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>
   <!--2 掃描類包,將標註Spring註解的類自動轉化成Bean,同時完成Bean的注入-->
   <context:component-scan base-package="com.springbbs.dao"/>

   <!--3 定義一個使用DBCP實現的數據源-->
   <!--若是加載不了配置文件,此處手動改成對應的值-->
   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
         destroy-method="close"
         p:driverClassName="${jdbc.driver}"
         p:url="${jdbc.url}"
         p:username="${jdbc.username}"
         p:password="${jdbc.password}"/>

   <!--4 定義jdbc模板Bean-->
   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
         p:dataSource-ref="dataSource"/>
</beans>

配置說明

jdbc.properties文件爲mysql配置文件,內容以下:apache

jdbc.driver=com.mysql.jdbc.Driver j
dbc.url=jdbc:mysql://localhost:3306/sampledb
jdbc.username=yourName
jdbc.password=yourPassword

在配置文件中加載mysql配置文件,在定義數據源時須要使用到配置文件中的信息

業務層

在這個登錄實例中,僅有一個業務類,即UserService,它負責將持久層的UserDaoLoginDao組織起來完成用戶/密碼認證、登錄日誌記錄等操做。loginSucess將兩個DAO組織起來共同完成一個事務性工做:更新兩個表,雖然沒有事務操做的影子,可是經過Spring事務配置便可。 關於幾個註解的解釋:

註解 做用
@Service UserService標註爲一個服務層的Bean
@Autowired 注入userDaologinLogDao這兩個DAO層的Bean

在Spring中裝配Service

咱們必須告訴Spring哪些業務類須要工做於事務環境下及事務的規則等內容,以便Spring根據這些信息自動爲目標業務類添加事務管理功能。對applicationContext.xml更改:

<?xml version="1.0" encoding="UTF-8"?>
<!--1 引入aop及tx命名空間所對應的Schema文件-->
<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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

   <!-- 加載配置文件 -->
   <context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>

   <!--掃描類包,將標註Spring註解的類自動轉化成Bean,同時完成Bean的注入-->
   <context:component-scan base-package="com.springbbs.dao"/>

   <!--掃描service類包,應用Spring的註解配置-->
   <context:component-scan base-package="com.springbbs.service"/>

   <!--配置事務管理器-->
   <bean id="transactionManager"
         class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
         p:dataSource-ref="dataSource"/>

   <!--經過AOP配置提供事務加強,讓service包下全部的Bean的全部方法擁有事務-->
   <aop:config proxy-target-class="true">
       <aop:pointcut id="serviceMethod" expression="execution(* com.springbbs.service..*(..))"/>
       <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/>
   </aop:config>

   <tx:advice id="txAdvice" transaction-manager="transactionManager">
       <tx:attributes>
           <tx:method name="*"/>
       </tx:attributes>
   </tx:advice>
   <!--定義一個使用DBCP實現的數據源-->
   <!--若是加載不了配置文件,此處手動改成對應的值-->
   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
         destroy-method="close"
         p:driverClassName="${jdbc.driver}"
         p:url="${jdbc.url}"
         p:username="${jdbc.username}"
         p:password="${jdbc.password}"/>

   <!--定義jdbc模板Bean-->
   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
         p:dataSource-ref="dataSource"/>
</beans>

NOTE: 配置文件解釋

命名空間

<!--添加`aop`和`tx`命名空間,這樣就能夠在`xml`配置文件中使用這兩個空間下的標籤了-->
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

Service註解掃描目錄

<context:component-scan base-package="com.springbbs.service"/>

事務管理器

<bean id="transactionManager"
         class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
         p:dataSource-ref="dataSource"/>

aop事務加強

關於aop(面向切片的編程後面會細講,目前能夠理解爲攔截和代理便可),execution(* com.springbbs.service.. *(..))的意思就是任意返回值的service包及子包下的任何參數的任何方法都切入進行事務管理。 ```xml

單元測試

jar包依賴

<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <scope>test</scope>
</dependency>

建立單元測試的方法:光標放在在須要測試的類名字上(本例中是UserService),按住Ctrl+Shift+TJunit4單元測試,勾選3個方法便可。 測試類UserServiceTest代碼以下:

package com.springbbs.service;

import com.springbbs.domain.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Date;

@RunWith(SpringJUnit4ClassRunner.class)     // 基於JUnit4的Spring測試框架
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})     //啓動Spring容器
public class UserServiceTest {

   @Autowired
   private UserService userService;

   @Test
   public void testHasMatchUser() throws Exception {
       boolean b1 = userService.hasMatchUser("admin", "123456");
       boolean b2 = userService.hasMatchUser("admin", "1111");

       Assert.assertEquals(true, b1);
       Assert.assertEquals(false, b2);
   }

   @Test
   public void testFindUserByUserName() throws Exception {
       User user = userService.findUserByUserName("admin");
       Assert.assertEquals("admin", user.getUserName());
   }

   @Test
   public void testLoginSucess() throws Exception {
       User user = userService.findUserByUserName("admin");
       user.setLastIp("127.0.0.1");
       user.setLastVistit(new Date());
       userService.loginSucess(user);
   }
}

NOTE:Spring測試框架能夠和Junit4整合,經過Junit4@RunWith註解指定SpringJUnit4ClassRunner.class的測試運行器,該運行器是Spring提供的,能夠將Spring容器和Junit4測試框架整合。@ContextConfiguration也是Spring提供的註解,它用於制定Spring的配置文件。 這裏須要注意的是,由於個人resources文件夾被指定爲資源根目錄,因此使用的 classpath路徑來加載,即最終在類的根目錄下。 在UserServiceTest上右鍵->Run UserServiceTest便可運行單元測試。最後取數據庫中查詢登錄日誌能夠發現成功插入一條記錄。

 

項目代碼地址:https://github.com/sjq597/JavaPracticeCode/tree/Spring 分支

tag:https://github.com/sjq597/JavaPracticeCode/tree/spring-bbs-v1.0

相關文章
相關標籤/搜索