Spring 笔记

IOC

set 注入属性

bean

public class Book {
	 //创建属性
	 private String bname;
	 private String bauthor;
	 //创建属性对应的 set 方法
	 public void setBname(String bname) {
		this.bname = bname;
	 }
	 
	 public void setBauthor(String bauthor) {
		this.bauthor = bauthor;
	 }
}

Spring xml配置文件

<bean id="book" class="com.atguigu.spring5.Book">
	 <property name="bname" value="易筋经"></property>
	 <property name="bauthor" value="达摩老祖"></property>
</bean>

有参构造注入

bean

public class Orders {
	 //属性
	 private String oname;
	 private String address;
	 //有参数构造
	 public Orders(String oname,String address) {
	 this.oname = oname;
	 this.address = address;
	 }
}

Spring XML 配置文件

constructor-arg 也可以使用 index(从0开始

<bean id="orders" class="com.atguigu.spring5.Orders">
	<constructor-arg name="oname" value="电脑"></constructor-arg>
	<constructor-arg name="address" value="China"></constructor-arg>
</bean>

p 名称空间注入

<bean id="book" class="com.atguigu.spring5.Book" p:bname="九阳神功" p:bauthor="无名氏"></bean>

XML 注入 null 或 特殊字符

null值

<property name="address">
	<null/>
</property>

特殊字符

<!--属性值包含特殊符号
 1 把<>进行转义 &lt; &gt;
 2 把带特殊符号内容写到 CDATA
-->
<property name="address">
	<value><![CDATA[<<南京>>]]></value>
</property>

注入属性-bean

外部 bean

<bean id="userService" class="com.atguigu.spring5.service.UserService">
	<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.atguigu.spring5.dao.UserDaoImpl"></bean>

内部 bean

<bean id="emp" class="com.atguigu.spring5.bean.Emp">
	<property name="dept">
		<bean id="dept" class="com.atguigu.spring5.bean.Dept">
			<property name="dname" value="安保部"></property>
		</bean>
	</property>
</bean>

注入属性-集合

<bean id="stu" class="com.atguigu.spring5.collectiontype.Stu">

    <!--数组类型属性注入-->
    <property name="courses">
        <array>
            <value>java</value>
            <value>数据库 de</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 id="course1" class="com.atguigu.spring5.collectiontype.Course">
    <property name="cname" value="Spring5 框架"></property>
</bean>
<bean id="course2" class="com.atguigu.spring5.collectiontype.Course">
<property name="cname" value="MyBatis 框架"></property>
</bean>

        <!--注入 list 集合类型,值是对象-->
<property name="courseList">
<list>
    <ref bean="course1"></ref>
    <ref bean="course2"></ref>
</list>
</property>

集合的提取和注入

<util:list id="bookList">
    <value>易筋经</value>
    <value>九阴真经</value>
    <value>九阳神功</value>
</util:list>
        <!--2 提取 list 集合类型属性注入使用-->
<bean id="book" class="com.atguigu.spring5.collectiontype.Book">
<property name="list" ref="bookList"></property>
</bean>

工厂bean

实现 FactoryBean<T> 接口

设置bean 为多实例

默认是单实例,设置多实例方法为:

更改 scope 参数

<bean id="user" class="cc.acdongla.UserImpl" scope="prototype"></bean>

单实例和多实例区别

1. singleton 单实例,prototype 多实例
2. 单实例在加载配置文件时创建对象,多实例在调用 getbean() 方法时创建对象

自动装配

bean 标签属性 autowire,配置自动装配

autowire 属性常用两个值:
    byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
    byType 根据属性类型注入

引入properties文件配置数据库连接池

${属性名} (等号左边)

<!--引入外部属性文件-->
<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>

基于注解方式实现属性注入

@Autowired:根据属性类型进行自动装配

@Qualifier:根据名称进行注入, 和上面@Autowired 一起使用

@Resource:可以根据类型注入,可以根据名称注入。默认根据类型注入

@Value:注入普通类型属性


示例

@Repository(value = "user1")
public class UserDapImpl implements UserDao {
@Resource(name = "user1")
private UserDao userDao;

完全注解开发

@Configuration 		// 作为配置类,替代XML文件
@ComponentScan(basePackages = "cc.acdongla.demo01") 	// 加载配置类是自动装载该路径下的类
public class SpringConfig {}

AOP操作

切入点表达式

作用: 知道对那个类里的方法进行增强

语法结构

execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))

举例

对cc.acdongla.dao.UserDao里面的add进行增强

execution(* cc.acdongla.dao.UserDao.add(..))

对cc.acdongla.dao.UserDao里面的所有方法增强

execution(* cc.acdongla.dao.UserDao.*(..))

对cc.acdongla.dao包里的所有类所有方法进行增强

execution(* cc.acdongla.dao.*.*(..))

Aspect 注解

Spring 配置文件设置:

image-20210926154242907

被增强类

增强类

@Aspect :生成代理对象

@Before :前置通知

测试运行

image-20210926154619243

运行结果

不同类型的通知

@Before 				前置通知
@AfterReturning 		后置通知(返回通知),若出现异常不通知
@After 					最终通知,出现异常也会通知
@AfterThrowing 			异常通知,只有出现异常才通知
@Around 				环绕通知

@Around 环绕通知使用示例

@Around(value = "execution(* cc.acdongla.aopanno.Person.run(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("环绕之前");
    proceedingJoinPoint.proceed(); // 被增强的方法执行
    System.out.println("环绕之后");
}

多个切入点抽取

使用注解 @Pointcut

多个增强类设置优先级

增强类添加 @Order 注解,传递一个数字值,值越小优先级越高,从0开始

JdbcTemplate

准备工作

  1. 需要的jar包

image-20210927121425371

image-20210927121522788

  1. Spring 配置--开启组件扫描
<context:component-scan base-package="cc.acdongla"></context:component-scan>
  1. Spring 配置--数据库连接池
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
      destroy-method="close">
    <property name="url" value="jdbc:mysql:///test" />
    <property name="username" value="root" />
    <property name="password" value="root" />
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
  1. Spring 配置--创建JdbcTemplate实现

    JdbcTemplate中需要数据库连接池对象

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
</bean>
  1. 在Dao类中自动装载JdbcTemplate对象

    @Repository
    public class BookDaoImpl implements BookDao{
        @Autowired
        private JdbcTemplate jdbcTemplate;
    }
    
  2. 在Service类中自动装载Dao对象

    @Service
    public class BookService {
        @Autowired
        private BookDao bookDao;
    }
    

完整配置文件

<?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"

       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">

    <context:component-scan base-package="cc.acdongla"></context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///test" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

</beans>

增删改示例

new JdbcTemplate().update 负责增删改操作

要添加一部书到数据库

Book: 该类为数据库t_book表的实体类

BookDaoImpl

@Repository
public class BookDaoImpl implements BookDao{
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int add(Book book) {
        String sql = "insert into t_book values(?,?,?)";
        return jdbcTemplate.update(sql, book.getBname(), book.getAuthor(), book.getPrice());
    }
}

BookService

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    public void addBook() {
        int count = bookDao.add(new Book("Java编程思想", "王一赫", 9999.999));
        System.out.println(count);
    }
}

测试方法

    @Test
    public void test1() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = (BookService) context.getBean("bookService");
        bookService.addBook();
    }

查询-返回单个值

示例:查询表的数据条数

public int queryCount() {
    String sql = "select count(*) from t_book";
    return jdbcTemplate.queryForObject(sql, Integer.class);
}

查询-返回对象

自动封装Bean

new BeanPropertyRowMapper<>(Book.class): 参数传递 Bean.class

示例:一个书籍所有信息

    public Book queryBook(double price) {
        String sql = "select * from t_book where price=?";
        Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Book.class), price);
        return book;
    }

查询-返回集合

直接使用query()函数,参数使用和上面的一样

示例:查找所有书籍的信息

    public List<Book> queryAllBook() {
        String sql = "select * from t_book";
        List<Book> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Book.class));
        return query;
    }

批量-增删改

传入List<Object[]>,函数会遍历 list ,把Object里的内容提取出来,以此实现批量更新的操作。返回每次操作的影响行数

示例:批量插入

    @Override
    public int[] batchAddBooks(List<Object[]> list) {
        String sql = "insert into t_book values(?,?,?)";
        int[] ints = jdbcTemplate.batchUpdate(sql, list);
        return ints;
    }

声明式事务管理

开启事务

配置文件中加入事务管理bean

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

开启事务注解

开启id为transactionManager的事务管理类的注解

    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

使用事务注解

@Transactional

加在类上面,该类的所有方法都会被添加上事务

加在方法上面,只有该方法会添加上事务

示例:

@Service
@Transactional
public class UserService {

    @Autowired
    private UserDao userDao;

    public void addAndReduce() {
        userDao.addMoney();
//        int a = 10/0;
        userDao.reduceMoney();
    }
}

完整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.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
">

    <context:component-scan base-package="cc.acdongla"></context:component-scan>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///test" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

<!--    事务管理类-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>


</beans>

jar包参考:

propagation-事务传播行为

默认为REQUIRED

使用示例

@Transactional(propagation = Propagation.REQUIRED)

常用的是前两个

image-20210928164625725

isolation-事务隔离级别

示例

@Transactional(isolation = Isolation.READ_COMMITTED)

默认:REPEATABLE_READ 可重复读

脏读: 一个未提交事务读取到另一个未提交事务中已改变的数据,之后该事务又回滚

不可重复读: 一个未提交事务读取到一个已提交事务修改的数据

幻读: 一个未提交事务读取到一个已提交事务添加的数据

image-20210928171304317

timeout-超时时间

  1. 事务需要在指定实现内提交,否则回滚
  2. 默认值为-1,设置的单位是秒

示例

@Transactional(timeout = 10)

readOnly-是否只读

  1. 只读:只支持数据的查询操作,不支持增删改

  2. 默认为false,支持增删改查

示例:

@Transactional(readOnly = true)

异常回滚

rollbackFor: 出现那些异常进行回滚

noRollbackFor: 出现那些异常不进行回滚

示例

@Transactional(noRollbackFor = NullPointerException.class)

完全注解配置方式

TxConfig.java

package cc.acdongla.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration // 配置类
@ComponentScan(basePackages = "cc.acdongla") // 组件扫描
@EnableTransactionManagement // 开启事务管理
public class TxConfig {

    // 创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl("jdbc:mysql:///test");
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("root");
        return druidDataSource;
    }

    // 创建jdbcTemplate类
    @Bean
    public JdbcTemplate getJdbcTemplate(DruidDataSource druidDataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(druidDataSource);
        return jdbcTemplate;
    }

    // 事务管理类
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DruidDataSource druidDataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new
            DataSourceTransactionManager(druidDataSource);
        return dataSourceTransactionManager;
    }

}

posted @ 2021-09-28 18:20  yangruomao  阅读(32)  评论(0编辑  收藏  举报