Java 45:Spring

好久沒有回來了,今天回來

書接上回


Spring 


Spring 是一個開源的,輕量級的 用來簡化應用開發的框架

簡化開發

對常用的apt 做了封裝和簡化

管理對象

spring 提供一個容器,幫我們創建對象以及建立對象之間的依賴關係

集成其他框架

Spring 可以將其他的一些框架集成進來 比如 集成用於:

任務調度 Quartz

spring 容器

spring 容器是 spring 框架中的一個核心模塊 用於管理對象

啓動spring 容器

1、導包 

spring-webmvc

2、添加配置文件

applicationContext.xml

3、啓動spring容器

ApplicationContext=》接口

ClassPathXmlApplicationContext=》實現類

//接口                  // 實現類                           //spring的配置二文件

ApplicationContext ac = new ClassPathXmlApplicationContext("annotation.xml");


如何創建對象

使用容器創建對象=》 反射

方式1、利用無參構造器

1、給類添加無參構造器(或者默認構造器)

2、使用<bean>元素在applicationContext.xml

<!-- 使用無參構造器創建對象 

id 屬性 bean的名稱 唯一

                     class 屬性:類的全限定名(要求包含包名)

-->

<bean id="stu1" class="day01.Student"></bean>
<bean id="date1" class="java.util.Date"></bean>


3、調用容器的getBean方法來獲取對象

Student sut = (Student)ac.getBean("stu1");
Student sut = ac.getBean("stu1",Student.class);
<bean id="date" class="java.util.Date"></bean>
Date d = ac.getBean("date",Date.class);
System.out.println(d.toString());


方式2、 使用靜態工廠方法

通過調用類的靜態方法來創建對象

1、<!-- 使用靜態工廠方法創建對象 

factory-method屬性: 指定一個靜態方法

spring容器會調用這個靜態方法來創建對象

-->

<bean id="cal1" class="java.util.Calendar" factory-method="getInstance"></bean>


2、

Calendar cal1 = ac.getBean("cal1",Calendar.class);
System.out.println(cal1);


方式3、使用實例工廠方法

通過調用對象的實例方法來創建對象

1、<!-- 使用實例工廠方法創建對象 

factory-bean   屬性 指定一個bean的id

factory-method 屬性 指定一個方法

spring 容器會調用這個bean的對應的方法來創建對象 

-->

<bean id="time1" factory-bean="cal1" factory-method="getTime"></bean>

2、

Date time1 = ac.getBean("time1",Date.class);
System.out.println(time1);

作用域

<!-- scope 屬性 用來配置作用域,

缺省值是 singleton 單例 spring容器 一個bean 只會創建一個實例

prototype 原型 (一個bean 會創建多個實例)-->

<bean id="s1" class="scope.ScopeBean" scope="prototype"></bean>


ApplicationContext ac = new ClassPathXmlApplicationContext("scope.xml");
ScopeBean s1 = ac.getBean("s1",ScopeBean.class);
ScopeBean s2 = ac.getBean("s1",ScopeBean.class);
System.out.println(s1 == s2); flase


生命週期

初始化 

分配資源

銷燬 

釋放資源

public class MessageBean {
public MessageBean() {
System.out.println("MessageBean()");
}
public void init() {
System.out.println("init()");
}
public void sendMsg() {
System.out.println("sendMsg()");
}
public void destroy() {
System.out.println("destroy()");
}
}

<!-- init-method 屬性

用來初始化方法,先創建對象 馬上調用init-method中的方法 初始化

spring 容器創建對象之後,會立刻調用初始化方法

-->

<!-- destroy-method 屬性

用來銷燬對象,銷燬對象前,會先執行這個,關閉spring 時候回銷毀

spring容器在關閉之前 會先銷燬對象, 在銷燬對象之前,會先調用對象的銷燬方法

只有作用域爲單例時,銷燬方法纔會執行,當爲原型的時候  銷燬方法不會執行

scope="prototype"   不會執行 銷燬方法

-->

<bean id="mb1" class="scope.MessageBean" init-method="init" destroy-method="destroy"></bean>


AbstractApplicationContext 接口 是ApplicationContext 的子接口

AbstractApplicationContext 中才有關閉方法

ac.close();

@Test
public void test2() {
AbstractApplicationContext ac = new ClassPathXmlApplicationContext("scope.xml");
MessageBean mb1 = ac.getBean("mb1",MessageBean.class);
mb1.sendMsg();
ac.close();
}


延遲加載


spring 容器啓動後,會檢查xml文件 會將所有作用域爲單例的bean 創建好

<!-- lazy-init 屬性 指定是否延遲加載

值爲true時 表示延遲加載  此時 spring 容器對於作用域爲單例的bean 就不會創建相應的實例了

在調用getBean的時候纔會創建對象

-->

<bean id="mb1" class="scope.MessageBean" init-method="init" destroy-method="destroy" lazy-init="true"></bean>


IOC  控制反轉

Inversion Of Controll

是指的 對象之間的依賴關係是由容器來建立

DI 依賴注入

Dependency Injection 

容器通過調用對象提供的set

方法或者構造器來建立依賴關係

IOC 是目標 DI是手段

類實現接口  用接口

<bean id="b1" class="ioc.B"></bean>

<!-- 

property 元素 表示使用set方法來注入依賴關係

name 屬性指定屬性名   前面加set 首字母變大寫 成 setB() 這個方法了

ref  屬性指定屬性值(是被注入的bean的id)

-->

<bean id="a1" class="ioc.A">
<property name="b" ref="b1"></property>
</bean>
package ioc;
public class B {
public B() {
System.out.println("B");
}
public void f1() {
System.out.println("B-f1()");
}
}
package ioc;
public class A {
private B b;
private C c;
public A() {
System.out.println("A");
}
public void execute() {
System.out.println("execute");
b.f1();
c.f1();
}
public void setB(B b) {
System.out.println("setB()");
this.b = b;
}
public void setC(C c) {
System.out.println("setc()");
this.c=c;
}
}
package ioc;
public class C {
public C() {
System.out.println("C");
}
public void f1() {
System.out.println("C-f1()");
}
}
 <bean id="b1" class="ioc.B"></bean>
<bean id="c1" class="ioc.C"></bean>
 <bean id="a1" class="ioc.A">
 <property name="b" ref="b1"></property>
 <property name="c" ref="c1"></property>
 </bean>
@Test
public void test5() {
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
A a = ac.getBean("a1",A.class);
a.execute();
}


set方式注入

1、提供相應的set方法

2、配置<property>

3、

package ioc;
public class B implements IB{
public B() {
System.out.println("B");
}
public void f1() {
System.out.println("B-f1()");
}
}
package ioc;
public class A {
private IB b;
public A() {
System.out.println("A");
}
public void execute() {
System.out.println("execute");
b.f1();
}
public void setB(IB b) {
System.out.println("setB()");
this.b = b;
}
}
package ioc;
public class C implements IB{
public C() {
System.out.println("C");
}
public void f1() {
System.out.println("C-f1()");
}
}
package ioc;
public interface IB {
public void f1();
}
 <bean id="b1" class="ioc.B"></bean>
<bean id="c1" class="ioc.C"></bean>
 <bean id="a1" class="ioc.A">
 <property name="b" ref="c1"></property>
 </bean>
@Test
public void test5() {
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
A a = ac.getBean("a1",A.class);
a.execute();
}
<bean id="b1" class="ioc.B"></bean>
<bean id="c1" class="ioc.C"></bean>
 <bean id="a1" class="ioc.A">
 <property name="b" ref="c1"></property>

name 就是 setB    單詞首字母大寫 加set 

ref 就是bean 的id

 </bean>

這個使用了接口

接口IB   有一個方法  f1()

兩個 B 和 C 類  實現了 IB 接口

在A類中使用了IB接口  那麼 B 類 和C 類都可以傳入 IB 接口中  

那麼就實現了  代碼不變 在xml中變 property 的 ref 值  也就是  注入的 bean ID 就可以  .就可以換實現方式了.

構造器方式注入(很少使用)

1、添加相應的構造器

2、配置constructor-arg 元素

<bean id="b" class="ioc2.B"></bean>

<!-- 構造器方式的注入

constructor-arg 用來配置構造器方式的注入,

index 屬性 用來指定出納室的下標 從0開始  (有參構造器的參數)

ref 屬性 就是要注入的id值

-->

<bean id="a" class="ioc2.A">
<constructor-arg index="0" ref="b"></constructor-arg>
</bean>
public class B {
public B() {
System.out.println("B");
}
public void f1() {
System.out.println("B-f1");
}
}
public class A {
private B b;
public A() {
System.out.println("A");
}
public A(B b) {
System.out.println("A->B");
this.b=b;
}
public void execute() {
System.out.println("A-execute");
b.f1();
}
}
@Test
public void test7(){
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc2.xml");
A a1 = ac.getBean("a",A.class);
a1.execute();
}


自動裝配(自動注入)

自動裝配是指的spring 容器依據某種規則 自動建立對象之間的依賴關係

默認情況下 容器不會自動裝配

可以通過指定 autowire屬性來 告訴容器進行自動裝配 容器仍然需要通過調用set 方法和構造器來完成依賴關係的建立

<bean id="wt" class="ioc2.Waiter"></bean>

 

 <!-- autowire 屬性 自動裝配

 byName  容器依據屬性名查找對應的bean 然後調用對應的set 方法來完成注入

 如果 找不到對應的bean  注入null

 不可能找到多個符合條件的bean

 byType 

  -->

 <bean id="rest" class="ioc2.Restaurant" autowire="byName"/>
</beans>


<!-- autowire 屬性 自動裝配

 byName  容器依據屬性名查找對應的bean (bean的id值)然後調用對應的set 方法來完成注入

 如果 找不到對應的bean  注入null

 不可能找到多個符合條件的bean

 byType  容器依據屬性類型來查找對應的bean (bean的class值)然後調用對應的set方法來完成注入

 如果找不到對應bean 注入null

 有可能找到多個符合條件的bean 此時會出錯

 constructor   

 與byType 類似 不同的是調用對應的構造器來完成注入

-->

優先使用 byName

package ioc;
public class Waiter {
public Waiter() {
System.out.println("Waiter()");
}  
}
package ioc;
public class Restaurant {
private Waiter wt;
public void setWt(Waiter wt) {
this.wt = wt;
}
public Restaurant() {
System.out.println("Restaurant()");
}
@Override
public String toString() {
return "Restaurant [wt=" + wt + "]";
}
}
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util-2.0.xsd
       ">   
  <bean id="wt" class="ioc.Waiter"></bean>
  <bean id="rest" class="ioc.Restaurant" autowire="byName"></bean>
</beans>


private Waiter wt;   屬性名爲wt 那 autowire byName 就會在 xml配置文件中找一個 bean id 爲 wt 的 類用 set 方式注入

若沒有找到就注入 null


注入基本類型的值  注入類的時候用 ref  注入基本類型用value

value 

<bean id="vb1" class="value.ValueBean">
<property name="name" value="張三"></property>
<property name="age" value="18"></property>
</bean>
package value;
public class ValueBean {
private String name;
private int age;
public ValueBean() {
System.out.println("ValueBean()");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "ValueBean [name=" + name + ", age=" + age + "]";
}
}
@Test
public void test9() {
ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
ValueBean vb = ac.getBean("vb1",ValueBean.class);
System.out.println(vb.toString());
}


注入集合類型的值

sprint 支持 List Set Map Properties

 

List

<bean id="vb1" class="value.ValueBean">
<property name="name" value="張三"></property>
<property name="age" value="18"></property>
<property name="city" >
<list>
<value>北京</value>
<value>上海</value>
<value>廣州</value>
</list>
</property>
</bean>


Set

<bean id="vb1" class="value.ValueBean">
<property name="name" value="張三"></property>
<property name="age" value="18"></property>
<property name="city" >
<list>
<value>北京</value>
<value>上海</value>
<value>廣州</value>
</list>
</property>
<property name="interest">
<set>
<value>吃</value>
<value>喝</value>
<value>玩</value>
<value>樂</value>
</set>
</property>
</bean>


Map

 <bean id="vb1" class="value.ValueBean">
<property name="name" value="張三"></property>
<property name="age" value="18"></property>
<property name="city" >
<list>
<value>北京</value>
<value>上海</value>
<value>廣州</value>
</list>
</property>
<property name="interest">
<set>
<value>吃</value>
<value>喝</value>
<value>玩</value>
<value>樂</value>
</set>
</property>
<property name="score">
<map>
<entry key="English" value="60"></entry>
<entry key="math" value="100"></entry>
</map>
</property>
</bean>

Properties

<bean id="vb1" class="value.ValueBean">
<property name="name" value="張三"></property>
<property name="age" value="18"></property>
<property name="city" >
<list>
<value>北京</value>
<value>上海</value>
<value>廣州</value>
</list>
</property>
<property name="interest">
<set>
<value>吃</value>
<value>喝</value>
<value>玩</value>
<value>樂</value>
</set>
</property>
<property name="score">
<map>
<entry key="English" value="60"></entry>
<entry key="math" value="100"></entry>
</map>
</property>
<property name="db">
<props >
<prop key="username" >root</prop>
<prop key="password" >1234</prop>
</props>
</property>
</bean>
package value;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class ValueBean {
private String name;
private int age;
private List<String> city;
private Set<String> interest;
private Map<String,Double> score; 
private Properties db;
public ValueBean() {
System.out.println("ValueBean()");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setCity(List<String> city) {
this.city = city;
}
public void setInterest(Set<String> interest) {
this.interest = interest;
}
public void setScore(Map<String, Double> score) {
this.score = score;
}
public void setDb(Properties db) {
this.db = db;
}
@Override
public String toString() {
return "ValueBean [name=" + name + ", age=" + age + ", city=" + city + ", interest=" + interest + ", score="
+ score + ", db=" + db + "]";
}
}
@Test
public void test9() {
ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
ValueBean vb = ac.getBean("vb1",ValueBean.class);
System.out.println(vb.toString());
}

集合類型的值配置成一個bean 方便 複用

但是要引用 util 標籤

xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation 中添加:
   http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util-2.0.xsd

<!-- 將集合類型的值配置成一個bean -->

<util:list id="cityBean">
<value>北京</value>
<value>上海</value>
<value>廣州</value>
</util:list>
<util:set id="interestBean">
<value>琴</value>
<value>棋</value>
<value>書</value>
<value>畫</value>
</util:set>
<util:map id="scoreBean">
<entry key="english" value="80"></entry>
<entry key="math" value="60"></entry>
</util:map>
<util:properties id="dbBean">
<prop key="username">root</prop>
<prop key="password">123456</prop>
</util:properties>
<bean id="vb2" class="value.ValueBean">
<!-- 引用方式注入集合類型的值 -->
<property name="city" ref="cityBean"></property>
<property name="interest" ref="interestBean"></property>
<property name="score" ref="scoreBean"></property>
<property name="db" ref="dbBean"></property>
</bean>
package value;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class ValueBean {
private String name;
private int age;
private List<String> city;
private Set<String> interest;
private Map<String,Double> score; 
private Properties db;
public ValueBean() {
System.out.println("ValueBean()");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setCity(List<String> city) {
this.city = city;
}
public void setInterest(Set<String> interest) {
this.interest = interest;
}
public void setScore(Map<String, Double> score) {
this.score = score;
}
public void setDb(Properties db) {
this.db = db;
}
@Override
public String toString() {
return "ValueBean [name=" + name + ", age=" + age + ", city=" + city + ", interest=" + interest + ", score="
+ score + ", db=" + db + "]";
}
}
@Test
public void test10() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
    ValueBean vb = ac.getBean("vb2",ValueBean.class);
    System.out.println(vb.toString());
}

spring 讀取properties 文件的配置

src/main/resources/config.properties=>>pagesize=10

<!-- 讀取properties 文件的內容

classpath 按照類路徑來搜索 從 resources 文件夾下開始找

spring 容器會依據路徑找到對應的properties文件 然後讀取文件的內容到Properties對象

-->

<util:properties id="config" location="classpath:config.properties"></util:properties>

@Test

public void test11() {

ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");

System.out.println(ac.getBean("config"));

}

使用spring 表達式

#{bean的id.屬性名(要有get方法)}

#{msg.name}  ==》讀取基本類型

#{msg.interest[0]} ==> 讀取list(不能讀set  set沒有下標)

#{msg.score.english} =>讀取map 如果是用的中文做map的key ==>#{msg.score['英語']}

#{config.pagesize}=>讀取<util:properties id="config" location="classpath:config.properties"></util:properties>

<?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:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" 

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd

       ">


<bean id="vb1" class="value.ValueBean">

<property name="name" value="張三"></property>

<property name="age" value="18"></property>

<property name="city">

<list>

<value>北京</value>

<value>上海</value>

<value>廣州</value>

</list>

</property>


<property name="interest">

<set>

<value>吃</value>

<value>喝</value>

<value>玩</value>

<value>樂</value>

</set>

</property>


<property name="score">

<map>

<entry key="English" value="60"></entry>

<entry key="math" value="100"></entry>

</map>

</property>


<property name="db">

<props>

<prop key="username">root</prop>

<prop key="password">1234</prop>

</props>

</property>

</bean>

<!-- 將集合類型的值配置成一個bean -->

<util:list id="cityBean">

<value>北京</value>

<value>上海</value>

<value>廣州</value>

</util:list>

<util:set id="interestBean">

<value>琴</value>

<value>棋</value>

<value>書</value>

<value>畫</value>

</util:set>

<util:map id="scoreBean">

<entry key="english" value="80"></entry>

<entry key="math" value="60"></entry>

</util:map>

<util:properties id="dbBean">

<prop key="username">root</prop>

<prop key="password">123456</prop>

</util:properties>

<bean id="vb2" class="value.ValueBean">

<!-- 引用方式注入集合類型的值 -->

<property name="city" ref="cityBean"></property>

<property name="interest" ref="interestBean"></property>

<property name="score" ref="scoreBean"></property>

<property name="db" ref="dbBean"></property>

</bean>

<!-- 讀取properties 文件的內容

classpath 按照類路徑來搜索

spring 容器會依據路徑找到對應的properties文件 然後讀取文件的內容到Properties對象

-->

<util:properties id="config" location="classpath:config.properties"></util:properties>

<bean id="sp1" class="value.SpelBean">

<property name="name" value="#{vb1.name}"></property>

<property name="city" value="#{vb1.city[1]}"></property>

<property name="score" value="#{vb1.score.English}"></property>

<property name="pageSize" value="#{config.pagesize}"></property>

</bean>

</beans>

package value;


public class SpelBean {

private String name;

private String city;

private double score;

private String pageSize;

public SpelBean() {

System.out.println("SpelBean()");

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getCity() {

return city;

}

public void setCity(String city) {

this.city = city;

}

public double getScore() {

return score;

}

public void setScore(double score) {

this.score = score;

}

public String getPageSize() {

return pageSize;

}

public void setPageSize(String pageSize) {

this.pageSize = pageSize;

}

@Override

public String toString() {

return "SpelBean [name=" + name + ", city=" + city + ", score=" + score + ", pageSize=" + pageSize + "]";

}


}

Properties文件:

pagesize=10


@Test

public void test12() {

ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");

SpelBean sp = ac.getBean("sp1",SpelBean.class);

System.out.println(sp);

}

SpelBean [name=張三, city=上海, score=60.0, pageSize=10]

使用註解簡化配置

組件掃描

spring 容器會掃描該包及其子包下面的所有類 

如果類前面有特定的註解@Component 

則 spring 容器會將其納入容器進行管理(相當於在配置文件中,配置了一個bean元素)

註解的類型:

@Component  通用註解

@Named 通用註解

@Repository持久層組件註解

@Service業務組件註解

@Controller 控制層註解

@Scope("prototype") => 指定作用域  原型

@Scope("singleton") =>單例

@PostConstruct =》 指定初始化方法(放在方法的上面)  需要 導包(在tomcat中有)javax.annotation.PostConstruct;

@PreDestroy =》 指定銷燬方法(放在方法的上面)  需要導包javax.annotation.PreDestroy;

@Lazy(true) =》 延遲加載

指定依賴注入關係

@Autowired 

@Qualifier

處理構造器注入和Setter注入

當採用set 方式注入時,可以將@Autowired 添加到set 方法前面,

如果不使用@Qualifier則容器會使用byType 的方式來注入 有可能出錯,

所以建議使用@Qualifier註解 明確指定要注入的bean的id

public class Resturant {

private Waiter wt;

@Autowired

public void setWt(@Qualifier("wt") Waiter wt) {

System.out.println("setWt()");

this.wt = wt;

}

}

還可以寫在屬性前面  這樣set方法都不用寫了,通過反射來完成的

@Autowired

@Qualifier("wt")

private Waiter wt;

當採用構造器注入時,可以將該註解添加到對應的構造器前面即可

@Inject

@Named

和@Autowired用一樣,需要導包,用法和@Autowired @Qualifier一樣是 是sun 公司開發的

@Resource

需要導包 javax  tomcat 中有

只能處理Setter 但是大部分都是用Setter 注入

Setter 使用@Resource

添加到set方法前面,使用name屬性指定要注入的bean 的id   (如果不指定,會按照byType的方法注入)

也可以將該註解添加到屬性前面

構造器使用@Autowired

package ioc;


import javax.annotation.Resource;


public class Bar {

private Waiter wt;


public Bar() {

System.out.println("Bar()");

}


public Waiter getWt() {

return wt;

}

@Resource(name = "wt")

public void setWt(Waiter wt) {

this.wt = wt;

}


@Override

public String toString() {

return "Bar [wt=" + wt + "]";

}


}

步驟 

1、在類中添加註解

@Component  bean的id缺省值 是類名首字母小寫之後的名字

@Component(sb1) bean 的id 爲 sb1

2、在配置文件中,添加組件掃描的配置

java 類中添加註解

xml 中

     <!-- 配置組件掃描 

     base-p ackage屬性: 指定要掃描的包名

     spring 容器會掃描該包及其子包下面的所有類 

如果類前面有特定的註解@Component 

則 spring 容器會將其納入容器進行管理(相當於這裏配置了一個bean元素)

base-package="annotation"  =》annotation 等於 類所在的包名  包括他的子包

     -->

     <context:component-scan base-package="annotation"></context:component-scan>  

      

import org.springframework.stereotype.Component;


@Component("sb1")

public class SomeBean {


public SomeBean() {

System.out.println("SomeBean()");

}

}


@Value 註解的類型: 

可以使用該註解來注入基本類型的值

可以使用該註解來使用spring 表達式

該註解可以添加到屬性前或者添加到對象的set 方法前

package ann;


import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;


@Component("mg")

public class Manager {

@Value("#{config.pageSize}")

private String pageSize;

@Value("李四")

private String name;

public Manager() {

System.out.println("Manager()");

}

@Override

public String toString() {

return "Manager [pageSize=" + pageSize + ", name=" + name + "]";

}

}


config.properties

pageSize=10

annotation.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:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd">

 

  <context:component-scan base-package="ann"></context:component-scan>

  <util:properties id="config" location="classpath:config.properties"></util:properties>

</beans>

@Test

@Test

public void test02() {

ApplicationContext ac  = new ClassPathXmlApplicationContext("annotation.xml");

Manager mg = ac.getBean("mg",Manager.class);

System.out.println(mg);

}

Srping MVC

是一個mvc 框架,用來簡化基於mvc 架構的web 應用開發

五大組件

DispatcherServlet==》前端控制器

接受請求,依據HandlerMapping 的配置調用相應的模型來處理 spring mvc 提供的需要配置

HandlerMapping

DispatcherServlet的祕書  包含了請求路徑與模型的對關係 spring mvc 提供的需要配置

Controller   處理器  自己寫

負責處理業務邏輯

ModelAndView

封裝了處理結果   處理結果除了數據之外,還可能有視圖名

ViewResolver  視圖解析器  spring mvc 提供的需要配置

DispatcherServlet依據ViewResolver的解析

調用真正的視圖對象來生產相應的頁面

DispatcherServlet的祕書

jsp

freemarker

velocity

五大組件的關係

DispatcherServlet 收到請求之後 依據HandlerMapping 的配置 調用相應的Controller來處理

Controller將處理結果封裝成ModelAndView對象然後返回給DispatcherServlet 

DispatcherServlet 依據ViewResolver的解析調用相應的視圖對象(比如某個jsp)來生產相應的頁面

ModelAndView 有兩個構造器

1、ModelAndView(String viewName)

viewName 是視圖名

2、ModelAndView(String viewName,Map data)

viewName 是視圖名

data 用於封裝處理結果數據

1、導包

2、添加spring配置文件

3、配置DispatcherServlet

4、寫Controller

5、寫jsp

6、在spring 配置文件中,添加配置 HandlerMapping、Controller、ViewResolver

1、導包 spring-webmvc

2、添加springmvc.xml spring 配置文件

<?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:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd

       ">

</beans>

3、

<!-- DispatcherServlet 在初始化方法裏面,會讀取該初始化參數的值,

來獲取spring配置文件的位置,

然後啓動spring容器

-->

<servlet>

<!-- servlet 名字 -->

<servlet-name>springmvc</servlet-name>

<!-- DispatcherServlet 固定的 -->

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<!-- 添加參數 DispatcherServlet 在初始化方法裏面 會讀取該初始化參數的值來

獲取spring配置文件的位置,然後啓動spring 容器

-->

<init-param>

<!-- 固定的 -->

<param-name>contextConfigLocation</param-name>

<param-value>classpath:springmvc.xml</param-value>

</init-param>

<!-- 啓動 -->

<load-on-startup>1</load-on-startup>

</servlet>

  

<servlet-mapping>

<servlet-name>springmvc</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>


4、

package controller;


import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.Controller;


public class HelloController implements Controller{


public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

System.out.println("handlerequest");

return new ModelAndView("hello");

}


}

5、

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>SteveZong</title>

</head>

<body>

<h1>Hello Spring MVC</h1>

</body>

</html>

6、

<!-- 配置HandlerMapping -->

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="mappings">

<props>

<prop key="/hello.do">helloController</prop>

</props>

</property>

</bean>

<!-- 配置處理器 -->

<bean id="helloController" class="controller.HelloController"></bean>

<!--

配置 ViewResolver

視圖名 hello通過以上配置可以映射到 /WEB-INF/hello.jsp

prefix 是 前綴

suffix 是 後綴

 -->

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/WEB-INF/"></property>

<property name="suffix" value=".jsp"></property>

</bean>


使用註解來開發基於springmvc的web應用

1、導包

2、添加spring 配置文件

3、配置 DispatcherServlet

4、寫Controller

5、寫jsp

6、在spring配置文件中,添加

a、組件掃描

b、mvc註解掃描

c、視圖解析器



1、導包 spring-webmvc


2、添加springmvc.xml spring 配置文件

DispatcherServlet在初始化方法裏面會讀取該初始化參數的值來獲取spring 配置文件的位置然後啓動spring容器

<?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:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" 

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd

       http://www.springframework.org/schema/mvc

       http://www.springframework.org/schema/mvc/spring-mvc.xsd

       ">

</beans>


3、

<servlet>

 <servlet-name>springmvc</servlet-name>

 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

 <init-param>

  <param-name>contextConfigLocation</param-name>

  <param-value>classpath:spring-webmvc.xml</param-value>

 </init-param>

 <load-on-startup>1</load-on-startup>

</servlet>

  

<servlet-mapping>

  <servlet-name>springmvc</servlet-name>

  <url-pattern>*.do</url-pattern>

</servlet-mapping>

  

4、

package springmvc002;


import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;


/**

 *不用實現Controller接口 

 *可以在處理器類當中,添加多個方法

 *每一個方法處理一種類型的請求

 *方法名 不做要求,返回類型可以是ModelAndView 也可以是String

 *@Controller 將該處理器納入容器進行管理(spring 配置文件中不用再配置該處理器了)

 *使用 @RequestMapping 告訴前端控制器DispatcherServlet 請求路徑與處理器的方法的對應關係 (spring 配置文件不用配置HandlerMapping)

 */

//  http://ip:port/springmvc002/hello.do

@Controller

public class HelloController {

@RequestMapping("/hello.do")

public String hello() {

return "hello";

}

}



//+++++++++++++++++++++++++++++++++++++++

//http://ip:port/springmvc002/demo/hello.do

@Controller

@RequestMapping("/demo")

public class HelloController {

@RequestMapping("/hello.do")

public String hello() {

return "hello";

}

}

//+++++++++++++++++++++++++++++++++++++++


5

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

</head>

<body>

<h1>Hello,SpringMVC</h1>

</body>

</html>


6、

<?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:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" 

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd

       http://www.springframework.org/schema/mvc

       http://www.springframework.org/schema/mvc/spring-mvc.xsd

       ">

<!-- 配置組件掃描 -->

<context:component-scan base-package="springmvc002"></context:component-scan>

<!-- 配置mvc註解掃描 -->

<mvc:annotation-driven/>

<!-- 配置視圖解析器 -->

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/WEB-INF/"></property>

<property name="suffix" value=".jsp"></property>

</bean>

</beans>

 

讀取請求參數值

通過request對象將request 對象作爲方法的入參即可

@RequestMapping("login.do")

//通過request對象 讀取請求參數值

public String login(HttpServletRequest  request) {

String adminCode = request.getParameter("adminCode");

System.out.println(adminCode);

return "index";

}

@RequestMapping("login2.do")

//使用 註解 @RequestParam

//參數名和 jsp中的name 一樣 可以不用註解(java 反射可能不能拿到形參) 但是最好還是要添加

//參數名和 jsp中name 不一樣,需要用註解

//用法,將註解添加到形參的前面

public String login2(String adminCode, @RequestParam("password")String pw) {

System.out.println(adminCode);

System.out.println(pw);

return "index";

}

使用javabean 封裝請求參數值

先寫一個java bean

在形參的地方放 javaBean

javaBean 的屬性名和 請求參數名一致,並且提供set get 方法

package springmvc002;

import java.io.Serializable;

public class AdminParam  implements Serializable{

private String adminCode;

private String password;

public String getAdminCode() {

return adminCode;

}

public void setAdminCode(String adminCode) {

this.adminCode = adminCode;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

}


@RequestMapping("login3.do")

//將請求參數封裝成一個javabean

public String login3(AdminParam ap) {

System.out.println(ap.getAdminCode());

System.out.println(ap.getPassword());

return "index";

}

向頁面傳值  優先使用生命週期短的

使用reqeust

@RequestMapping("login4.do")

//使用request 將數據綁定到request 上 然後轉發到某個jsp     springmvc默認使用轉發

public String login4(AdminParam ap,HttpServletRequest request) {

System.out.println("login4()");

String adminCode = ap.getAdminCode();

System.out.println(adminCode);

//將數據綁定到request

request.setAttribute("adminCode", adminCode);

//springmvc 默認使用轉發

return "index";

}

使用 ModelAndView 將數據 先封裝到ModelAndView 對象裏面,然後將該對象作爲方法的返回值

@RequestMapping("login5.do")

//使用ModelAndView

public ModelAndView login5(AdminParam ap) {

String adminCode = ap.getAdminCode();

System.out.println(adminCode);

//構造ModelAndView對象

Map<String,Object> data = new HashMap<String,Object>();

//相當於request.setAttribute("adminCode",adminCode);

// 所以key 相當於 

data.put("adminCode",adminCode);

ModelAndView  mav = new ModelAndView("index",data);

return mav;

}

使用ModelMap 將這個對象 作爲方法的參數,然後將數據綁定到該對象

@RequestMapping("login6.do")

public String login6(AdminParam ap , ModelMap mm) {

String adminCode = ap.getAdminCode();

System.out.println(adminCode);

//相當於request.setAttribute("adminCode",adminCode);

mm.addAttribute("adminCode", adminCode);

return "index";

}

使用session 將數據綁定到session中 session 作爲方法的參數  直接使用 session 前端控制器會分析請求

@RequestMapping("login7.do")

public String login7(AdminParam ap, HttpSession session) {

String adminCode = ap.getAdminCode();

session.setAttribute("adminCode", adminCode);

return "index";

}

重定向 

302

如果方法的返回值是String 

在重定向地址前添加"redirect:"

return "redirect:toIndex.do";

@RequestMapping("login8.do")

public String login8() {

System.out.println("login8()");

return "redirect:toIndex.do";

}

@RequestMapping("toIndex.do")

public String toIndex() {

System.out.println("toIndex.do");

return "index";

}

如果方法的返回值是ModelAndView

@RequestMapping("login9.do")

public ModelAndView login9() {

System.out.println("login9()");

RedirectView rv = new RedirectView("toIndex.do");

return new  ModelAndView(rv);

}

反射

是JAVA API 是Java 提供的現成的類

是Java 提供的動態執行機制 動態加載類,動態創建對象 動態訪問實現,動態條用方法

靜態與動態

靜態:事先約定的規則 執行期間按照固定規則執行

動態:事先沒有約定,在執行期間動態確定執行規則

JAVA 中的靜態執行:編譯或已經就確定執行規則(執行次序) 在運行期間按照變異結果順序執行

JAVA 中的動態執行:運行期間才能確定加載哪些類,創建哪些對象,執行哪些方法

動態加載類

Java 提供了動態加載類的API

Class cls = Class.forName(類名);

System.out.println(cls);

動態創建對象

語法

Object obj = cls.newInstance();

System.out.println(obj);

cls.newInstance();

習性cls引用的類信息中的無參構造器,動態創建實例,如果類沒有無參構造器,拋出異常

反射可以調用有參構造器

動態獲取類的方法信息

//動態獲取類的方法信息,從 cls 帶來的類信息中獲取全部的方法信息

Method[] ary = cls.getDeclaredMethods();

for(Method method:ary) {

System.out.println(method);

}

method 是從類中獲取的

method.invoke(執行方法的對象,傳遞的參數)

method.invoke(對象,參數1,參數2,參數3...)

必須在對象上執行一個非靜態方法,調用方法適合必須有對象

在invoke方法執行適合必須傳遞包含當前方法的對象

Class cls = Class.forName(className);

//Object obj = cls.newInstance();

Method[] methods = cls.getMethods();

Object obj = cls.newInstance();

for(Method sub:methods) {

if(sub.getName().startsWith("test")) {

System.out.println(sub.getName());

sub.invoke(obj);

sub.invoke(obj,arg[1],arg[~],arg[n]);

}

}

invoke 方法有返回值,返回被調用方法執行的結果,對象後面參數是執行方法適合傳遞的參數

*** invoke 可以調用私有方法


//動態加載類

Scanner in = new Scanner(System.in);

String className = in.nextLine();

Class cls = Class.forName(className);

//找到demo方法

//Class提供了根據方法簽名找到指定方法信息的API

String name="demo";

//類型列表 Class[]

//String.class 字符串類型

//int.class int類型

//根據方法簽名在cls查找方法信息

Class[] types = {String.class,int.class};

Method method = cls.getDeclaredMethod(name, types);

System.out.println(method.getName());

//執行私有方法

//打開方法執行權限,違反封裝

method.setAccessible(true);

Object obj  = cls.newInstance();

method.invoke(obj, "tom",22);

System.out.println(obj);

反射用途

eclipse 中解析類的結構使用了反射

Junit識別被測試方法

Spring 管理Bean對象 注入Bean屬性

註解的解析

強行執行私有方法 訪問私有屬性

MVC

系統分層

  UI  BLL     DAL

表示層業務層持久層

表示層:數據展現和控制邏輯 (請求分發)

業務層:業務邏輯的處理

持久層:數據庫訪問

v c合併:

表示層:數據展現和控制邏輯 (請求分發)

m分兩層:

業務層:業務邏輯的處理

持久層:數據庫訪問

表示層 調用 業務層 調用  持久層

  (接口)(接口)

上一層通過接口調用下一層提供的服務

比如 

業務層調用持久層提供的接口

下一層發生改變 不影響上一層

方便代碼的維護

junit

@Before

修飾的方法會在測試方法運行之前執行

可以把啓動容器的方法 寫在這個裏面

然後在類中添加一個屬性ApplicationContext

DataSource

連接池的接口

dbcp c3p0 都支持

中文亂碼解決方法

在web.xml  中 添加一個filter 過濾器

然後用spring  提供好的一個類org.springframework.web.filter.CharacterEncodingFilter

配置一下就可以了

spring-web-3.2.8.RELEASE.jar

包中

<filter>

<filter-name>pageEncoding</filter-name>

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>pageEncoding</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

爲何會有亂碼

表單提交時,瀏覽器會對鍾文傑進行編碼   (會只用打開表示所在頁面時的字符集來編碼 比如utf-8)

但是服務器默認使用iso-8859-1來解碼 所以就會有亂碼

springmvc 提供了一個過濾器 CharacterEncodingFilter  表單提交要採用post方法提交

客戶端的編碼與過濾器的編碼要一樣

spring 攔截器

spring 提供的一個特殊的組件 當DispatcherServlet 收到請求之後,如果有攔截器,會先調用攔截器,然後調用相應的處理器Controller

過濾器  屬於Servlet規範

攔截器屬於spring框架

可以配置多個

1、寫一個java 類 實現HandlerInterceptor接口

2、實現具體的攔截處理邏輯,比如 session驗證,日誌記錄,權限管理

3、配置攔截器

1、寫java類

package interceptors;


import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;


public class SomeInterceptor implements HandlerInterceptor{

/**

* 進入controller

* DispatcherServlet 收到請求之後 會先調用preHandle  方法, 如何方法返回true 通過 繼續向後調用,false 不再向後調用

* arg2 描述處理器方法的一個對象  一般都用不到

*/

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

System.out.println("preHandle");

return true;

}

/**

* 處理器ontroller的方法已經 處理完 正要 返回ModelAdnView對象給DispatcherServlet 執行postHandle 可以在在這個方法裏面修改處理結果

*/

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

System.out.println("postHandle");

}

/**

* 最後執行的方法 只有當preHandle 方法返回值爲true時,該方法纔會執行

* ex是處理器梭拋出的異常,可以寫一個攔截器用來處理這些異常

*/

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

throws Exception {

System.out.println("afterCompletion");

}


}


3、<!-- 攔截路徑是多層的 用 /** -->

<mvc:interceptors>

<mvc:interceptor>

<mvc:mapping path="/*"/>

<bean class="interceptors.SomeInterceptor"></bean>

</mvc:interceptor>

</mvc:interceptors>

Spring MVC 處理異常方式有三種

1使用SpringMVC提供的簡單異常處理器

SimpleMappingExceptionResolver

異常毅力頁面獲取異常對象名exception 適合全局處理簡單異常

<!-- 配置簡單異常處理器 -->

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

<property name="exceptionMappings">

<props>

<prop key="java.lang.NumberFormatException">error</prop>

</props>

</property>

</bean>

2實現HandlerExceptionResolver接口

自定義異常處理器

3使用@ExceptionHandler註解實現異常處理

1、在處理器類當中,添加一個異常處理方法 該方法必須使用@ExceptionHandler修飾

2、在該方法裏面依據異常類型,分別進行不同的處理

3、添加異常處理頁面

//一個異常處理方法

//ex 是其他方法所拋出的異常

@ExceptionHandler

public String exHandle(HttpServletRequest request,Exception ex) {

System.out.println("exHadnle()");

//依據異常類型的不同,分別進行 相應的處理

if(ex instanceof NumberFormatException) {

request.setAttribute("error", "親,請輸入正確的數字");

}else if(ex instanceof StringIndexOutOfBoundsException) {

request.setAttribute("error", "數組下標越界");

}else {

request.setAttribute("error", "系統異常,請稍後重試");

}

return "error";

}

Spring JDBC


spring 對jdbc的封裝,使用springjdbc 訪問數據庫可以不用寫一寫重複性的代碼,比如獲取連接 關閉連接等

使用

1、導包

spring-webmvc 3.2.8

spring-jdbc   3.2.8

mysql-connector 5.1.44

dbcp 1.4

2、添加spring 配置文件

3、配置JdbcTemplate

JdbcTemplate 提供了一些方法,  來訪問數據庫

4調用JdbcTemplate 提供的方法來訪問數據庫

通過將JdbcTemplate注入到DAO。

JdbcTempate

1、導包

2、添加spirng 配置文件


<util:properties id="dbInfo">

<prop key="user">zongxuan</prop>

<prop key="password">zongxuan</prop>

<prop key="url">jdbc:mysql://172.29.12.158:3306/test?useUnicode=true&amp;characterEncoding=utf8

</prop>

<prop key="driver">com.mysql.jdbc.Driver</prop>

<prop key="initialSize">10</prop>

<prop key="maxActive">500</prop>

</util:properties>


<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close">

<property name="driverClassName" value="#{dbInfo.driver}"></property>

<property name="url" value="#{dbInfo.url}"></property>

<property name="username" value="#{dbInfo.user}"></property>

<property name="password" value="#{dbInfo.password}"></property>

<property name="initialSize" value="#{dbInfo.initialSize}"></property>

<property name="maxActive" value="#{dbInfo.maxActive}"></property>

</bean>

3、配置JdbcTemplate

<!-- 配置 JdbcTempate -->


<bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate">

<!-- 注入連接池 -->

<property name="dataSource" ref="ds"></property>

</bean>


4(插入)

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.stereotype.Repository;


import entity.Emp;


@Repository("empDAO")

public class EmpDAOImpl  implements EmpDAO{


@Resource(name="jt")

private JdbcTemplate template;

public void save(Emp emp) {

//sql   然後使用 Object 數組賦值. 調用 update方法

String sql = "INSERT INTO emp2 (name,age) VALUES (?,?)";

Object[] params = new Object[] {emp.getName(),emp.getAge()};

template.update(sql,params);

}

}

4、(查詢)

package dao;


import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;


import javax.annotation.Resource;


import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.stereotype.Repository;


import entity.Emp;


@Repository("empDAO")

public class EmpDAOImpl  implements EmpDAO{


@Resource(name="jt")

private JdbcTemplate template;

public void save(Emp emp) {

String sql = "INSERT INTO emp2 (name,age) VALUES (?,?)";

Object[] params = new Object[] {emp.getName(),emp.getAge()};

template.update(sql,params);

}


public List<Emp> findAll() {

List<Emp> emps = new ArrayList<Emp>();

String sql = "SELECT * FROM emp2";

emps = template.query(sql, new EmpRowMapper());

return emps;

}

//告訴JdbcTemplate 如何將ResultSet 中的一條記錄轉換成對應的Entity對象

class EmpRowMapper implements RowMapper<Emp>{

//rs 要處理的結果集, index 當前正在處理的記錄的下標

public Emp mapRow(ResultSet rs, int index) throws SQLException {

Emp emp = new Emp();

emp.setId(rs.getInt("id"));

emp.setName(rs.getString("name"));

emp.setAge(rs.getDouble("age"));

return emp;

}

}


}

4(查詢 By 條件)

package dao;


import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;


import javax.annotation.Resource;


import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.stereotype.Repository;


import entity.Emp;


@Repository("empDAO")

public class EmpDAOImpl  implements EmpDAO{


@Resource(name="jt")

private JdbcTemplate template;

public void save(Emp emp) {

String sql = "INSERT INTO emp2 (name,age) VALUES (?,?)";

Object[] params = new Object[] {emp.getName(),emp.getAge()};

template.update(sql,params);

}


public List<Emp> findAll() {

List<Emp> emps = new ArrayList<Emp>();

String sql = "SELECT * FROM emp2";

emps = template.query(sql, new EmpRowMapper());

return emps;

}

//告訴JdbcTemplate 如何將ResultSet 中的一條記錄轉換成對應的Entity對象

class EmpRowMapper implements RowMapper<Emp>{

//rs 要處理的結果集, index 當前正在處理的記錄的下標

public Emp mapRow(ResultSet rs, int index) throws SQLException {

Emp emp = new Emp();

emp.setId(rs.getInt("id"));

emp.setName(rs.getString("name"));

emp.setAge(rs.getDouble("age"));

return emp;

}

}


public Emp findById(int id) {

Emp emp = null;

String sql = "SELECT * FROM emp2 WHERE id=?";

Object[] args = new Object[] {id};

emp  = template.queryForObject(sql, args,new EmpRowMapper());

return emp;

}


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章