日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

后端学习 - Spring5

發(fā)布時(shí)間:2023/12/4 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 后端学习 - Spring5 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 一 簡介
  • 二 IOC
    • 1 底層原理
    • 2 實(shí)現(xiàn)過程
    • 3 Spring 實(shí)現(xiàn) IOC 的兩個(gè)接口
  • 二 Bean
    • 1 普通 Bean 與 FactoryBean
    • 2 Bean 單例與否的設(shè)置
    • 3 Bean 的生命周期
  • 三 IOC 的 Bean 管理(XML)
    • 1 創(chuàng)建對(duì)象
    • 2 屬性注入 - 使用 set 方法
    • 3 屬性注入 - 通過有參構(gòu)造器實(shí)現(xiàn)
    • 3 注入屬性為 null / 包含特殊符號(hào)
    • 4 注入外部 Bean
    • 5 注入內(nèi)部 Bean
    • 6 注入 array / list / map / set
    • 7 自動(dòng)裝配
    • 8 使用外部文件配置 Bean
  • 四 IOC 的 Bean 管理(注解)
    • 1 Spring 針對(duì)創(chuàng)建 Bean 對(duì)象提供的注解
    • 2 創(chuàng)建對(duì)象的步驟
    • 3 屬性注入 - @Autowared
    • 4 屬性注入 - @Qualifier
    • 5 屬性注入 - @Resource
    • 6 屬性注入 - @Value
    • 7 完全注解開發(fā)
  • 五 AOP 概述
    • 1 動(dòng)態(tài)代理的兩種情況
    • 2 JDK 動(dòng)態(tài)代理實(shí)例
  • 六 AspectJ 的使用(注解)
    • 1 切入點(diǎn)表達(dá)式
    • 2 使用流程
    • 3 相同切入點(diǎn)的抽取
    • 4 完全注解開發(fā)
  • 七 JdbcTemplate
    • 1 配置
    • 2 添加 / 修改 / 刪除 操作
    • 3 查詢值
    • 4 查詢單個(gè)對(duì)象
    • 5 查詢多個(gè)對(duì)象
  • 八 Spring 事務(wù)管理
    • 1 注解聲明式事務(wù)管理的步驟
    • 2 @Transactional 的參數(shù)配置
    • 3 完全注解的 聲明式事務(wù)管理


一 簡介

  • Spring 是輕量級(jí)的開源的 JavaEE 框架
  • Spring 有兩個(gè)核心部分:IOC(Inversion of Control,控制反轉(zhuǎn)) 和 AOP(Aspect Oriented Programming,面向切面編程)
  • IOC 是一種設(shè)計(jì)思想,核心是,將設(shè)計(jì)好的對(duì)象交給容器控制,而不是傳統(tǒng)的在對(duì)象內(nèi)部直接控制。 把創(chuàng)建和查找依賴對(duì)象的控制權(quán)交給了容器,由容器進(jìn)行注入組合對(duì)象,所以對(duì)象與對(duì)象之間是松散的耦合。
  • AOP 是針對(duì)業(yè)務(wù)處理過程中的切面進(jìn)行提取,它所面對(duì)的是處理過程中的某個(gè)步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。簡言之,AOP 可以做到不修改源代碼進(jìn)行功能增強(qiáng)。OOP 面向名詞領(lǐng)域,AOP 面向動(dòng)詞領(lǐng)域。

二 IOC

1 底層原理

  • xml 解析
  • 工廠模式
  • 反射

2 實(shí)現(xiàn)過程

  • 配置 xml 文件的 bean 標(biāo)簽,使用 id 屬性標(biāo)注對(duì)象名,使用 class 屬性標(biāo)注類所在的位置,在 bean 標(biāo)簽內(nèi)部使用 property 標(biāo)簽綁定依賴關(guān)系
  • <bean id="studentDAO" class="dao.StudentInfoDAO"><property name="..." value="..."> </bean>
  • 使用工廠類,利用反射機(jī)制,創(chuàng)建對(duì)象
  • class MyFactory {public DAO getDAO () {String classValue = // 經(jīng)過一些方法得到"dao.StudentInfoDAO"; // 解析xml,獲取bean標(biāo)簽的class屬性值Class clazz = Class.forName(classValue); // 獲取指定類的 Class 對(duì)象return (StudentInfoDAO)clazz.newInstance(); // 根據(jù) Class 對(duì)象創(chuàng)建實(shí)例} }

    經(jīng)過上述過程,各類間進(jìn)一步解耦。例如,此時(shí) xml 配置中,class 屬性變動(dòng)不會(huì)對(duì)其創(chuàng)建造成影響。

    3 Spring 實(shí)現(xiàn) IOC 的兩個(gè)接口

  • BeanFactory:Spring 內(nèi)部的使用接口,不提供給開發(fā)人員進(jìn)行使用。加載配置文件時(shí)候不會(huì)創(chuàng)建對(duì)象,在獲取對(duì)象(使用)才去創(chuàng)建對(duì)象
  • ApplicationContext:BeanFactory 接口的子接口,功能更強(qiáng)大,加載配置文件時(shí)候就會(huì)把在配置文件對(duì)象進(jìn)行創(chuàng)建。 把創(chuàng)建資源的過程放在服務(wù)器啟動(dòng)時(shí)。有兩個(gè)實(shí)現(xiàn)類:FileSystemXmlApplicationContext (傳入 xml 文件的絕對(duì)路徑)和 ClassPathXmlApplicationContext (傳入 xml 文件的相對(duì)路徑,以 src 作為起始目錄)

  • 二 Bean

    1 普通 Bean 與 FactoryBean

    • 普通 Bean 的定義類型和返回類型相同,而 FactoryBean 的定義類型和返回類型可以不同
    • 要?jiǎng)?chuàng)建 FactoryBean,需要實(shí)現(xiàn)接口 FactoryBean<T>
    <bean id="myBean" class="com.atguigu.spring5.factorybean.MyBean"></bean> public class MyBean implements FactoryBean<Course> { // 返回類型是Course@Overridepublic Course getObject() throws Exception {Course course = new Course();course.setCname("abc");return course;}@Overridepublic Class<?> getObjectType() {return null;}@Overridepublic boolean isSingleton() {return false;} }

    2 Bean 單例與否的設(shè)置

    • 默認(rèn) Bean 是單例對(duì)象
    • 通過 Bean 標(biāo)簽的 scope="singleton" / "prototype" 選擇單例與否
    • 設(shè)置 scope = "singleton" ,加載 spring 配置文件時(shí)候就會(huì)創(chuàng)建單實(shí)例對(duì)象;設(shè)置 scope = "prototype" ,在調(diào)用 getBean 方法時(shí)候創(chuàng)建多實(shí)例對(duì)象

    3 Bean 的生命周期

    (1)通過構(gòu)造器創(chuàng)建 bean 實(shí)例(無參構(gòu)造)
    (2)為 bean 的屬性設(shè)置值和對(duì)其他 bean 引用(調(diào)用 set 方法)
    (3)把 bean 實(shí)例傳遞 bean 后置處理器的方法 postProcessBeforeInitialization(可選)
    (4)調(diào)用 bean 的初始化的方法(需要配置初始化的方法)
    (5)把 bean 實(shí)例傳遞 bean 后置處理器的方法 postProcessAfterInitialization(可選)
    (6)bean 可以使用(獲取到了對(duì)象)
    (7)當(dāng)容器關(guān)閉時(shí)候,調(diào)用 bean 的銷毀的方法(需要配置銷毀的方法)

    后置處理器在配置后,會(huì)對(duì)所有的 Bean 生效

    不含后置處理器的 Bean 生命周期演示:

    public class Orders {private String oname;// 無參構(gòu)造public Orders() {System.out.println("第一步 執(zhí)行無參構(gòu)造創(chuàng)建 bean 實(shí)例");}public void setOname(String oname) {this.oname = oname;System.out.println("第二步 調(diào)用 set 方法設(shè)置屬性值");}// 初始化的方法public void initMethod() {System.out.println("第三步 執(zhí)行初始化的方法");}// 銷毀的方法public void destroyMethod() {System.out.println("第五步 執(zhí)行銷毀的方法");} }

    三 IOC 的 Bean 管理(XML)

    Bean 管理包含兩個(gè)步驟:創(chuàng)建對(duì)象、注入屬性

    1 創(chuàng)建對(duì)象

    創(chuàng)建對(duì)象時(shí)候,默認(rèn)是執(zhí)行無參數(shù)構(gòu)造方法完成對(duì)象創(chuàng)建。

    <bean id="custom_instance_name" class="pojo.MyClass"></bean>

    • id:唯一標(biāo)識(shí),相當(dāng)于對(duì)象名
    • class:類全路徑

    2 屬性注入 - 使用 set 方法

  • 在 Bean 中實(shí)現(xiàn)要注入屬性的 set 方法
  • public class Book {//創(chuàng)建屬性private String bname;private String bauthor;//創(chuàng)建屬性對(duì)應(yīng)的 set 方法public void setBname(String bname) {this.bname = bname;}public void setBauthor(String bauthor) {this.bauthor = bauthor;} }
  • 在 xml 文件中配置要注入的屬性名,以及屬性值
  • <bean id="book" class="com.atguigu.spring5.Book"><!--name:類里面屬性名稱 value:向?qū)傩宰⑷氲闹?-><property name="bname" value="易筋經(jīng)"></property><property name="bauthor" value="達(dá)摩老祖"></property> </bean>

    3 屬性注入 - 通過有參構(gòu)造器實(shí)現(xiàn)

  • 創(chuàng)建類,定義屬性,創(chuàng)建有參構(gòu)造器
  • public class Orders {//屬性private String oname;private String address;//有參構(gòu)造public Orders(String oname,String address) {this.oname = oname;this.address = address;}
  • 在 xml 文件中配置,constructor-arg 指定了調(diào)用有參數(shù)的構(gòu)造器
  • <bean id="orders" class="com.atguigu.spring5.Orders"><!--constructor-arg 指定了調(diào)用有參數(shù)的構(gòu)造器!--><!--也可以使用index屬性代替name屬性--><constructor-arg name="oname" value="電腦"></constructor-arg><constructor-arg name="address" value="China"></constructor-arg> </bean>

    3 注入屬性為 null / 包含特殊符號(hào)

    <bean id="book" class="com.atguigu.spring5.Book"><property name="address"><null/></property><property name="tel"><value><![CDATA[...]]></value></property> </bean>

    4 注入外部 Bean

    • 示例使用 set 方法進(jìn)行注入,要求 userService 實(shí)現(xiàn)了其 dao 屬性的 set 方法
    • name 是類里面屬性名稱,ref 是創(chuàng)建 userDao 對(duì)象 bean 標(biāo)簽 id 值
    <bean id="userService" class="com.atguigu.spring5.service.UserService"><!--注入 userDao 對(duì)象name 屬性:類里面屬性名稱ref 屬性:創(chuàng)建 userDao 對(duì)象 bean 標(biāo)簽 id 值--><property name="userDao" ref="userDaoImpl"></property> </bean><bean id="userDaoImpl" class="com.atguigu.spring5.dao.UserDaoImpl"></bean>

    5 注入內(nèi)部 Bean

    • 示例使用 set 方法進(jìn)行注入
    • 如果注入的類型是 Bean,則將 value 標(biāo)簽替換為 ref 標(biāo)簽
    <!--內(nèi)部 bean--> <bean id="emp" class="com.atguigu.spring5.bean.Emp"><!--設(shè)置對(duì)象類型屬性--><property name="dept"><bean id="dept" class="com.atguigu.spring5.bean.Dept"><property name="dname" value="安保部"></property></bean></property> </bean>

    6 注入 array / list / map / set

    • 示例使用 set 方法進(jìn)行注入
    <bean id="stu" class="com.atguigu.spring5.collectiontype.Stu"><!--數(shù)組類型屬性注入--><property name="courses"><array><value>java 課程</value><value>數(shù)據(jù)庫課程</value></array></property><!--list 類型屬性注入--><property name="list"><list><value>張三</value><value>小三</value></list></property><!--map 類型屬性注入--><property name="maps"><map><entry key="JAVA" value="java"></entry><entry key="PHP" value="php"></entry></map></property><!--set 類型屬性注入--><property name="sets"><set><value>MySQL</value><value>Redis</value></set></property> </bean><bean ...><!--注入 list 集合類型,值是對(duì)象--><property name="courseList"><list><ref bean="course1"></ref><ref bean="course2"></ref></list></property> </bean>

    7 自動(dòng)裝配

    • 在 bean 標(biāo)簽后設(shè)置屬性 autoware
    • 可選參數(shù) byName(根據(jù)屬性的名稱,自動(dòng)裝配和屬性名相同的 id 的 bean 對(duì)象);byType(根據(jù)屬性類型,自動(dòng)裝配 bean 對(duì)象)

    8 使用外部文件配置 Bean

    以 Druid 數(shù)據(jù)庫連接池的配置為例。

    <!--引入 context 名稱空間--> .......<!--引入外部屬性文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--配置連接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${prop.driverClass}"></property><property name="url" value="${prop.url}"></property><property name="username" value="${prop.userName}"></property><property name="password" value="${prop.password}"></property> </bean>

    四 IOC 的 Bean 管理(注解)

    使用注解的目的是簡化 xml 配置

    1 Spring 針對(duì)創(chuàng)建 Bean 對(duì)象提供的注解

    • @Component
    • @Service
    • @Controller
    • @Repository

    以上注解的功能相同,只是用于標(biāo)識(shí)不同層

    2 創(chuàng)建對(duì)象的步驟

  • 加入依賴包
  • 更改 xml 的名稱空間(略),開啟組件掃描(如果掃描多個(gè)包,在一個(gè)雙引號(hào)中用逗號(hào)隔開)
    <context:component-scan base-package="com.atguigu"></context:component-scan>
  • 創(chuàng)建類并使用對(duì)應(yīng)的注解
  • // value的默認(rèn)值是 userService @Component(value = "userService") //相當(dāng)于xml方式的 <bean id="userService" class=".."/> public class UserService {public void add() {System.out.println("service add.......");} }

    3 屬性注入 - @Autowared

    • 根據(jù)屬性類型進(jìn)行自動(dòng)裝配
    • 創(chuàng)建 service 和 dao 對(duì)象,在 service 和 dao 類添加對(duì)應(yīng)的創(chuàng)建對(duì)象注解;在 service 注入 dao 對(duì)象,在 service 類添加 dao 類型屬性,在屬性上使用注解
    • 不需要為注入屬性添加 set 方法
    @Service // 等同于 @Service(value="userService") 等同于 <bean id="userService" class="..."> public class UserService {@Autowiredprivate UserDao userDao;public void add() {System.out.println("service add.......");userDao.add();}

    4 屬性注入 - @Qualifier

    • 根據(jù)名稱注入
    • 和上面的 @Autowired 一起使用,用于區(qū)別相同類型的不同 Bean
    @Service public class UserService {@Autowired // 根據(jù)類型進(jìn)行注入@Qualifier(value = "userDaoImpl1") // 根據(jù)名稱進(jìn)行注入private UserDao userDao;public void add() {System.out.println("service add.......");userDao.add();}

    5 屬性注入 - @Resource

    • 可以實(shí)現(xiàn)類型注入、名稱注入
    • 類型注入不需要加參數(shù),名稱注入使用 name 參數(shù)指定

    6 屬性注入 - @Value

    • 上述三種注入的是對(duì)象屬性,而 @Value 可以注入普通類型
    @Value(value = "abc") private String name;

    7 完全注解開發(fā)

    • 使用 @Configuration 注解的類,代替配置文件
    • 使用 @ComponentScan(basePackages = {"..."}) 完成組件掃描
    @Configuration @ComponentScan(basePackages = {"com.atguigu"}) public class SpringConfig {}
    • 使用時(shí)加載配置類:ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    @Test public void testService2() {// 加載配置類ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);// 后續(xù)操作相同UserService userService = context.getBean("userService", UserService.class);// ... }

    五 AOP 概述

    Aspect Oriented Programming,面向切面編程,本質(zhì)是動(dòng)態(tài)代理

    • 連接點(diǎn):類中可以被增強(qiáng)的方法
    • 切入點(diǎn):實(shí)際增強(qiáng)的方法
    • 通知(增強(qiáng)):實(shí)際增強(qiáng)的邏輯部分,包含 前置通知 / 后置通知 / 環(huán)繞通知 / 異常通知(增強(qiáng)發(fā)生異常時(shí)的邏輯) / 最終通知(增強(qiáng)部分類似于 finally)
    • 切面:通知應(yīng)用到切入點(diǎn)的過程

    1 動(dòng)態(tài)代理的兩種情況

  • 需要代理的類具有接口,使用 JDK 動(dòng)態(tài)代理,創(chuàng)建接口實(shí)現(xiàn)類代理對(duì)象(向代理類中傳入接口的實(shí)現(xiàn)類)
  • 需要代理的類不具有接口,使用 GCLIB 動(dòng)態(tài)代理,創(chuàng)建其子類的代理對(duì)象
  • 2 JDK 動(dòng)態(tài)代理實(shí)例

  • 接口與接口的實(shí)現(xiàn)
  • interface Human{String getBelief();void eat(String food); }class SuperMan implements Human{@Overridepublic String getBelief() {return "I believe I can fly!";}@Overridepublic void eat(String food) {System.out.println("我喜歡吃" + food);} }
  • 動(dòng)態(tài)代理類:動(dòng)態(tài)代理對(duì)象調(diào)用原生方法的時(shí)候,最終實(shí)際上調(diào)用到的是 invoke() 方法,然后 invoke() 方法調(diào)用了被代理對(duì)象的原生方法。
  • import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class DebugInvocationHandler implements InvocationHandler {// 代理類中的真實(shí)對(duì)象private final Object target;public DebugInvocationHandler(Object target) {this.target = target;}/*** 動(dòng)態(tài)代理的核心部分!!!* proxy :動(dòng)態(tài)生成的代理類* method : 與代理類對(duì)象調(diào)用的方法相對(duì)應(yīng)* args : 當(dāng)前 method 方法的參數(shù)**/public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {//額外操作...Object result = method.invoke(self.target, args); //調(diào)用的是method的invoke方法//額外操作...return result;} }
  • 獲取代理對(duì)象的工廠類:輸入需要被代理的對(duì)象,輸出其代理。即:根據(jù)對(duì)象實(shí)例建立代理實(shí)例。
  • public class JdkProxyFactory {public static Object getProxy(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(), // 目標(biāo)類的類加載target.getClass().getInterfaces(), // 代理需要實(shí)現(xiàn)的接口,可指定多個(gè)new DebugInvocationHandler(target) // 代理對(duì)象對(duì)應(yīng)的自定義 InvocationHandler);} }
  • 實(shí)際使用:一個(gè)代理,到處使用
  • public static void main(String[] args) {//被代理的類型1SuperMan superMan = new SuperMan();Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan); // 強(qiáng)轉(zhuǎn)為對(duì)應(yīng)接口的類型// invoke() 方法: 當(dāng)我們的動(dòng)態(tài)代理對(duì)象調(diào)用原生方法的時(shí)候,最終實(shí)際上調(diào)用到的是 invoke() 方法,然后 invoke() 方法代替我們?nèi)フ{(diào)用了被代理對(duì)象的原生方法。String belief = proxyInstance.getBelief();proxyInstance.eat("四川麻辣燙");//被代理的類型2NikeClothFactory nikeClothFactory = new NikeClothFactory();ClothFactory proxyClothFactory = (ClothFactory); ProxyFactory.getProxyInstance(nikeClothFactory);proxyClothFactory.produceCloth();}

    六 AspectJ 的使用(注解)

    AspectJ 不是 Spring 的組成部分,獨(dú)立 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使用,進(jìn)行 AOP 操作

    1 切入點(diǎn)表達(dá)式

    • 用于設(shè)置增強(qiáng)方法(在代理類中的注解的 value 屬性

    • 語法規(guī)則:execution([權(quán)限修飾符(可選)] [返回類型(可為*)] [類全路徑] [方法名稱]([參數(shù)列表]) )

      舉例 1:對(duì) com.atguigu.dao.BookDao 類里面的 add 進(jìn)行增強(qiáng)
      execution(* com.atguigu.dao.BookDao.add(…))

      舉例 2:對(duì) com.atguigu.dao.BookDao 類里面的所有的方法進(jìn)行增強(qiáng)
      execution(* com.atguigu.dao.BookDao.* (…))

    2 使用流程

  • 引入依賴(略)
  • 配置 xml,更改名稱空間,開啟組件掃描、代理對(duì)象生成
  • <beans>...<!--開啟組件掃描--><context:component-scan base-package="pojo"></context:component-scan><!--生成代理對(duì)象--><aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
  • 被代理類、原方法、代理類、增強(qiáng)方法注解。用 @Aspect 注解代理類
    • 被代理類與原方法
    @Component(value = "myClass") public class MyClass {public void add() {System.out.println("原來的add方法");} }
    • 代理類與增強(qiáng)方法
    @Component(value = "enhanceClass") @Aspect public class EnhanceClass {@Before(value = "execution(* pojo.MyClass.add(..))")public void before() {System.out.println("前置通知");}@AfterReturning(value = "execution(* pojo.MyClass.add(..))")public void afterReturning() {System.out.println("后置通知,正常返回時(shí)才執(zhí)行");}@After(value = "execution(* pojo.MyClass.add(..))")public void after() {System.out.println("最終通知,無論是否正常返回都執(zhí)行");}@AfterThrowing(value = "execution(* pojo.MyClass.add(..))")public void afterThrowing() {System.out.println("異常通知");}@Around(value = "execution(* pojo.MyClass.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("環(huán)繞通知:前");proceedingJoinPoint.proceed();System.out.println("環(huán)繞通知:后");} }
    • 測試過程與結(jié)果
    @Testpublic void testAspect() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("myclass.xml");MyClass myClass = applicationContext.getBean("myClass", MyClass.class);myClass.add();}/* 執(zhí)行結(jié)果:環(huán)繞通知:前前置通知未增強(qiáng)的方法環(huán)繞通知:后最終通知,無論是否正常返回都執(zhí)行后置通知,正常返回時(shí)才執(zhí)行 */

    3 相同切入點(diǎn)的抽取

    對(duì)空方法使用注解 @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    相同切入點(diǎn)的注解的 value 屬性值為 “空方法調(diào)用”

    @Component(value = "enhanceClass") @Aspect public class EnhanceClass {@Pointcut(value="execution(* pojo.MyClass.add(..))")public void myPointCut() {}@Before(value = "myPointCut")public void before() {System.out.println("前置通知");} }

    4 完全注解開發(fā)

    創(chuàng)建配置類代替 xml

    @Configuration @ComponentScan(basePackages = {"pojo"}) @EnableAspectJAutoProxy(proxyTargetClass = true) public class ConfigAop {}

    七 JdbcTemplate

    1 配置

  • 引入依賴
  • 使用 xml 配置 Druid 數(shù)據(jù)庫連接池,創(chuàng)建 JdbcTemplate,并注入數(shù)據(jù)庫連接池
  • <!-- 數(shù)據(jù)庫連接池 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"><property name="url" value="jdbc:mysql://localhost:3306/test" /><property name="username" value="root" /><property name="password" value="123" /><property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /></bean><!--創(chuàng)建jdbctemplate,注入數(shù)據(jù)庫連接池--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean>
  • 創(chuàng)建 Service 類,注入 DAO;創(chuàng)建 DAO,注入 JdbcTemplate
    在 xml 中配置組件掃描 <context:component-scan base-package="jdbc"></context:component-scan>
  • /*Service 類*/ @Service(value = "userService") public class UserService {@Autowiredprivate UserDAO userDAO;// 提供的服務(wù),調(diào)用對(duì)應(yīng)的 DAO... }/*DAO 類*/ @Component(value = "userDAO") public class UserDAOImpl implements UserDAO {@Autowiredprivate JdbcTemplate jdbcTemplate;// 單精度的表操作實(shí)現(xiàn)... }

    2 添加 / 修改 / 刪除 操作

    在 DAO 中調(diào)用 jdbcTemplate 的 update 方法

    @Component(value = "userDAO") public class UserDAOImpl implements UserDAO {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic void add(User user) {String sql = "insert into user values (?, ?, ?, ?, ?)";Object[] args = {user.getId(), user.getName(), user.getPwd(), user.getAddr(), user.getTel()};int update = this.jdbcTemplate.update(sql, args); // 調(diào)用 jdbcTemplate.update 進(jìn)行添加System.out.println(update);} }

    測試方法:

    @Testpublic void testAddOneItem() {User user = new User(10, "伍佰", "500", "老城路101", "554433");ApplicationContext applicationContext = new ClassPathXmlApplicationContext("myclass.xml");UserService userService = applicationContext.getBean("userService", UserService.class);userService.addUser(user);}
    • 如果要實(shí)現(xiàn)批量操作,調(diào)用 jdbcTemplate 的 batchUpdate
    • batchUpdate傳入的參數(shù)1為 sql,參數(shù)2為List<Object[]> 類型,其中的每個(gè)元素 Object[] 代表一條語句的參數(shù)

    3 查詢值

    在 DAO 中調(diào)用 jdbcTemplate 的 queryForObject 方法

    @Component(value = "userDAO") public class UserDAOImpl implements UserDAO {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic int selectCount() {String sql = "select count(*) from user";return this.jdbcTemplate.queryForObject(sql, Integer.class);} }

    4 查詢單個(gè)對(duì)象

    • 在 DAO 中調(diào)用 jdbcTemplate 的 queryForObject 方法
    • 需要傳入 BeanPropertyRowMapper 對(duì)象,其作用是將 SQL 查詢返回值封裝為指定對(duì)象
    • 默認(rèn)情況下需要表屬性名和類屬性名一致
    @Component(value = "userDAO") public class UserDAOImpl implements UserDAO {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic User selectById(int id) {String sql = "select * from user where id = ?";User user = this.jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);return user;} }

    5 查詢多個(gè)對(duì)象

    類似于查詢單個(gè)對(duì)象,調(diào)用的是 query 方法

    @Component(value = "userDAO") public class UserDAOImpl implements UserDAO {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic List<User> selectAll() {String sql = "select * from user";List<User> userList = this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));return userList;} }

    八 Spring 事務(wù)管理

    • 底層使用了 AOP 原理
    • 事務(wù)方法:更改數(shù)據(jù)庫內(nèi)容的方法(增刪改)
    • 在 Web - Service - DAO 三層結(jié)構(gòu)中,推薦把事務(wù)注解放在 Service 層
    • Spring 提供了一個(gè)事務(wù)管理器接口 PlatformTransactionManager ,這個(gè)接口針對(duì)不同的框架提供不同的實(shí)現(xiàn)類

    1 注解聲明式事務(wù)管理的步驟

  • 更改 Spring 配置文件:創(chuàng)建事務(wù)管理器、注入數(shù)據(jù)源,引入名稱空間 tx,同時(shí)開啟事務(wù)注解
  • <!--創(chuàng)建事務(wù)管理器,注入數(shù)據(jù)庫連接池--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!--開啟事務(wù)注解--><tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
  • @Transactional 可以用于類(注解類中的所有方法),也可以用于方法
  • 2 @Transactional 的參數(shù)配置

  • propagation(事務(wù)傳播行為):多事務(wù)方法進(jìn)行調(diào)用,這個(gè)過程中事務(wù)是如何進(jìn)行管理的
  • isolation(隔離級(jí)別):可選屬性 讀未提交 / 讀提交 / 可重復(fù)讀 / 串行化
  • timeout(超時(shí)時(shí)間):超時(shí)后自動(dòng)回滾,以秒為單位,默認(rèn)-1
  • readOnly(是否只讀):默認(rèn)為 flase,如果設(shè)置為 true 則只能查詢
  • rollbackFor(回滾):指定出現(xiàn)哪些異常進(jìn)行回滾
  • noRollbackFor(不回滾):指定出現(xiàn)哪些異常不執(zhí)行回滾
  • 3 完全注解的 聲明式事務(wù)管理

    @Configuration //配置類 @ComponentScan(basePackages = "com.atguigu") //組件掃描 @EnableTransactionManagement //開啟事務(wù) public class TxConfig {//創(chuàng)建數(shù)據(jù)庫連接池@Beanpublic DruidDataSource getDruidDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///user_db");dataSource.setUsername("root");dataSource.setPassword("root");return dataSource;}//創(chuàng)建JdbcTemplate對(duì)象@Beanpublic JdbcTemplate getJdbcTemplate(DataSource dataSource) {//到ioc容器中根據(jù)類型找到dataSourceJdbcTemplate jdbcTemplate = new JdbcTemplate();//注入dataSourcejdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}//創(chuàng)建事務(wù)管理器@Beanpublic DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();transactionManager.setDataSource(dataSource);return transactionManager;} }

    總結(jié)

    以上是生活随笔為你收集整理的后端学习 - Spring5的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。