Spring第一天

Spring01

阶段介绍

框架就是软件的半成品,我们在框架的基础上只需要关注业务逻辑即可.提升开发效率.

例如:mybatis,我们只需要关注sql语句及返回值

内容介绍

spring中spring framework.以后别人提到spring一般指的就是spring framework

  • ioc
  • aop
  • 声明式事务
  • springmvc

今日内容:

  • IOC:控制反转,目标就是解耦合
    • xml方式(今天学习)
    • 注解方式(明天学习)
  • DBUtils:jdbc的工具类

目标:

  • 结合spring的ioc和dbutils完成对表中数据的crud

一 Spring概述【了解】

​ 接下来这6天我们说的spring指的是spring中的子产品 :spring framework

Spring是分层的 Java SE/EE应用full-stack 轻量级开源框架。以 IOC(Inverse Of Control:控制反转)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。

官网:https://spring.io/

full-stack:全(一)栈式框架,从web到service,再到dao,spring都可以提供良好的解决方案.

  • web:springmvc
  • service:spring中声明式事务
  • dao:spring JdbcTemplate

轻量级:使用的时候消耗的资源少.


spring可以整合市面上几乎所有的框架

二 初识IOC

1 介绍

**控制反转(Inverse Of Control)**不是什么技术,而是一种设计思想。它的目的是指导我们设计出更加松耦合的程序。

控制:在java中指的是对象的控制权限(创建、销毁)

反转:指的是对象控制权由原来 由开发者在类中手动控制 反转到 由Spring容器控制

大白话就是:将对象的创建权交给spring容器管理,我们使用的时候只需要去spring容器中获取即可.

2 IOC的出现

参照ppt

三 Spring的IOC-xml方式快速入门【重点】

1 需求

​ 使用spring的ioc实现UserDao层保存操作

2 步骤分析

  1. 导入spring的依赖 spring-context(5.1.5)
  2. 创建UserDao及其实现类
  3. 在dao中提供保存方法
  4. 编写配置文件,名字自定义,在开发中一般使用 applicationContext.xml.为了方便,我叫beans.xml
  5. 使用spring中提供好的api获取spring容器中的对象.

3 代码实现

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>
//junit自行导入

UserDao

public interface UserDao {
    void save();
}

UserDaoImpl

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("userDao执行了save方法");
    }
}

编写配置文件beans.xml(目前放在main/reousrces目录下)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
</beans>

测试代码

package com.itheima.test;

import com.itheima.dao.UserDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class A_TestIOC {
    @Test
    public void test0() {
        //创建的spring的工厂(容器)对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        //从工厂中获取userDao对象
        UserDao userDao = (UserDao) ac.getBean("userDao");

        userDao.save();

    }
}

注意:在pom.xml添加了spring-context约束且将jar包导入到项目中后,可以直接创建spring的配置文件

四 Spring相关API【理解】

spring的API体系异常庞大,我们现在只关注两个BeanFactory和ApplicationContext

BeanFactory和ApplicationContext的关系

  1. BeanFactory是ApplicationContext的父接口
  2. BeanFactory获取单实例对象的时候,什么时候用什么时候再创建.
  3. ApplicationContext获取单实例对象的时候,在创建工厂对象的时候就已经创建好了所有的单实例对象,获取的时候直接返回即可.

代码是用来理解的,不用写

@Test
public void testBeanFactoryAndAC1(){
    //获取spring容器对象
    //在工厂初始化的时候就会把配置文件中的所有单实例对象创建好
    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    //从容器中获取dao对象
    UserDao userDao = (UserDao) ac.getBean("userDao");
    UserDao userDao2 = (UserDao) ac.getBean("userDao");

    System.out.println(userDao == userDao2);//true
}

@Test
public void testBeanFactoryAndAC2(){
    //获取spring容器对象
    //在工厂初始化的时候,并不会把配置所有的单实例对象创建好
    BeanFactory ac = new XmlBeanFactory(new ClassPathResource("beans.xml"));

    //从容器中获取dao对象
    //第一次调用的时候才创建好
    UserDao userDao = (UserDao) ac.getBean("userDao");
    UserDao userDao2 = (UserDao) ac.getBean("userDao");

    System.out.println(userDao == userDao2);//true
}

实现类

  • FileSystemXmlApplicationContext【了解】
    功能:从指定磁盘目录加载xml配置文件,创建spring的ioc容器
  • ClassPathXmlApplicationContext
    功能:从类路径下加载xml配置文件,创建spring的ioc容器
  • AnnotationConfigApplicationContext
    功能:加载注解配置类,创建spring的ioc容器

方法

  1. public Object getBean(String name) throws BeansException;
    功能:通过指定id获取对象的实例,需要手动强转
  2. public T getBean(Class requiredType);
    功能:通过指定类型获取对象的实例,不需要强转
    注意:同一个类型下只能有一个对象实例
  3. public T getBean(String name, Class requiredType);
    功能:通过指定id和类型获取对象的实例

五 Spring配置文件【重点】

1 Bean标签

基本配置

    <!--
        bean: 创建好指定的对象
            id:给对象起个名字(项目中唯一),方便在java代码中获取
            class:对象对应的全限定类名
		只有上面两个属性的话,这些bean都是单实例对象
    -->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

其他配置-一般不用

<!--
        bean标签
            scope属性:用类配置对象的作用范围
                常见的两个取值:
                singleton:单实例对象,默认值
                prototype:多实例对象
                多实例一般不用,struts是一个web层框架,它里面的执行类都是多实例对象.
            init-method属性:指定对象初始化要执行的方法,spring底层使用
            destroy-method属性:指定对象销毁前要执行的方法,spring底层使用

    -->
    <bean id="userDao2" class="com.itheima.dao.impl.UserDaoImpl" scope="prototype" init-method="ii" destroy-method="dd"/>

public class UserDaoImpl implements UserDao {

    public UserDaoImpl() {
        System.out.println("userDao对象创建了");
    }

    @Override
    public void save() {
        System.out.println("dao的save执行了");
    }

    public void ii(){
        System.out.println("对象的初始化操作方法执行了");
    }

    public void dd(){
        System.out.println("对象的马上要销毁了");
    }
}


public class B_TestAttr {
    @Test
    public void testScope(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao2");
        UserDao userDao2 = (UserDao) ac.getBean("userDao2");

        //若scope没有配置或者scope配置为singleton的时候,返回值就是true
        //单实例对象,在工厂初始化的时候就创建好了

        //若scope配置为prototype的时候,返回值就是false,
        //多实例对象,什么时候用什么时候创建.
        System.out.println(userDao == userDao2);
    }

    @Test
    public void testInitMethodAndDestroyMethod(){
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao2");

        //若scope没有配置或者scope配置为singleton的时候,返回值就是true
        //单实例对象,在工厂初始化的时候就创建好了

        //若scope配置为prototype的时候,返回值就是false,
        //多实例对象,什么时候用什么时候创建.

        //明确的执行容器销毁操作,单实例对象目前都还在spring容器中,当容器要销毁的时候,就会调用各个对象的销毁方法
        //多实例对象的创建权交给spring管理,但是销毁操作是通过垃圾回收器管理的.
        ac.close();
    }
}

2 spring创建对象实例三种方式

之前创建对象的方式:

  • new 对象();
  • 工厂.静态方法();
  • 工厂对象.普通方法();

构造方法实例化【重点】

之前创建对象 UserDao userDao = new UserDaoImpl()

现在只需要在配置文件中配置

<bean id="名字" class="全限定类名"/>

工厂静态方法实例化【了解】

应用场景

​ 依赖的jar包中有个A类,A类中有个静态方法m1,m1方法的返回值是一个B对象。如果我们频繁使用B对象,此时我们可以将B对象的创建权交给spring的IOC容器,以后我们在使用B对象时,无需调用A类中的m1方法,直接从IOC容器获得

例如

之前web中创建DataSource

​ DataSource ds = DruidDataSourceFactory.createDatasource();

使用springIOC方案的步骤:

  1. 创建一个工厂类
  2. 提供一个静态方法,可以返回一个routeDao对象
  3. 配置

代码实现

public interface RouteDao {
    void save();
}

public class RouteDaoImpl implements RouteDao {
    @Override
    public void save() {
        System.out.println("routeDao的save方法执行了");
    }
}

public class RouteDaoFactory {
    public static RouteDao createRouteDao(){
        return new RouteDaoImpl();
    }
}

<!--
        方式2:类的静态方法创建
            class:工厂的全限定类名
            factory-method:指定创建目标对象的方法名
    -->
<bean id="routeDao" class="com.itheima.instance.RouteDaoFactory" factory-method="createRouteDao"/>


工厂普通方法实例化【了解】

应用场景

​ 依赖的jar包中有个A类,A类中有个普通方法m1,m1方法的返回值是一个B对象。如果我们频繁使用B对象,
此时我们可以将B对象的创建权交给spring的IOC容器,以后我们在使用B对象时,无需调用A类中的m1方法,直接从IOC容器获得。

例如:

之前在web中的做法

//伪代码
CommonFactory  factory = new CommonFactory();
UserDao userDao = factory.createUserDao();

步骤:

  1. 创建一个工厂类
  2. 提供一个普通方法,可以返回一个routeDao对象
  3. 配置

代码实现

public class RouteDaoCommonsFactory {
    public RouteDao createCommonsDao(){
        return new RouteDaoImpl();
    }
}

<!--
        方式3:类的普通方法创建
            a.先将工厂对象交给容器管理
            b.在通过工厂对象方法创建目标对象交给容器管理
    -->
<bean id="commonsFactory" class="com.itheima.instance.RouteDaoCommonsFactory"/>
<!--
        factory-bean:指向的是工厂对象在容器中的id
        factory-method:指定的是工厂类中创建目标对象的方法
    -->
<bean id="routeDao2" factory-bean="commonsFactory" factory-method="createCommonsDao"/>

六 Bean依赖注入概述

依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。

spring创建对象的时候要将对象里面的成员字段通过依赖注入进行初始化操作。

1 set方法注入

要求成员变量必须有对应的set方法.

<!--依赖注入:set方式,通过set方法设置属性-->
<bean id="ds" class="com.alibaba.druid.pool.DruidDataSource">
    <!--注入四个基本属性-->
    <!--
            property标签:注入属性值
                name:对象中有set方法的属性名
                value:设置值.值的类型必须是基本类型、包装类或者string类型
        -->
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql:///springdb"/>
    <property name="username" value="root"/>
    <property name="password" value="1234"/>
</bean>

public class D_TestDIHello {
    @Test
    //别忘记导入mysql驱动和druid依赖
    public void createDSWithWeb() throws SQLException {
        //之前web方式
        DruidDataSource ds = new DruidDataSource();

        //设置4个基本属性
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql:///springdb");
        ds.setUsername("root");
        ds.setPassword("1234");

        DruidPooledConnection conn = ds.getConnection();
        System.out.println(conn);

        conn.close();
    }

    @Test
    public void crateDSWithIOC() throws SQLException {
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        DataSource ds = (DataSource) ac.getBean("ds");
        Connection conn = ds.getConnection();
        System.out.println(conn);
        conn.close();
    }
}


public class UserServiceImpl implements UserService {

    private UserDao userDao;
    //给成员遍历提供set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }


    @Override
    public void save() {
        System.out.println("userService中的save方法执行了");
        userDao.save();
    }
}

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
    <!--
            property
                ref:给引用类型的属性进行赋值,值就是目标对象在spring容器中的id值
        -->
    <property name="userDao" ref="userDao"/>
</bean>

测试代码

public class E_TestDISet {
    @Test
    public void testDISet(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService = (UserService) ac.getBean("userService");
        userService.save();
    }
}

2 构造方法注入

假如一个类OrderService有两个变量:String,OrderDao

之前方式:

OrderService orderService = new OrderServiceImpl("张三",orderDao);//构造方法赋值


使用spring的方式注入:

  1. 在OrderService中提供一个两个参数的构造器
  2. 将orderDao放入spring容器中
  3. 在配置文件中使用构造方法方式注入两个变量的值,将service对象加入spring容器中

public class OrderDaoImpl implements OrderDao {
    @Override
    public void save() {
        System.out.println("orderDao 中的save方法执行了");
    }
}

public class OrderServiceImpl implements OrderService{

    private String name;
    private OrderDao orderDao;

    //提供了构造器
    public OrderServiceImpl(String name, OrderDao orderDao) {
        this.name = name;
        this.orderDao = orderDao;
    }

    @Override
    public void save() {
        System.out.println("orderservice中的save方法执行了:"+name);
        orderDao.save();
    }
}


<!--依赖注入:构造方法,通过构造方法设置属性-->
<bean id="orderDao1" class="com.itheima.dao.impl.OrderDaoImpl"/>
<bean id="orderService" class="com.itheima.service.impl.OrderServiceImpl">
    <!--
            通过contrucat-arg 给变量赋值
                name:构造器中参数的名字
                value:赋值,给简单类型复制(基本类型,包装类,string)
                ref:赋值,给除了string类型之外的其他引用类型,且已经存在spring容器中
        -->
    <constructor-arg name="name" value="张三"/>
    <constructor-arg name="orderDao" ref="orderDao1"/>
</bean>

//测试代码
public class F_TestDIContrucator {
    @Test
    public void test1(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        OrderService orderService = (OrderService) ac.getBean("orderService");
        orderService.save();
    }
}

3 p命名空间注入(了解)

本质上也是set方法,在此基础上进行了简化

使用步骤:

  1. 需要在spring的配置文件中引入p名称空间
  2. 在需要注入的bean标签中通过 p:属性="" 或者 p:属性-ref=""方式注入
<!--p名称空间注入-->
<bean id="ds2" class="com.alibaba.druid.pool.DruidDataSource" 			 
      p:driverClassName="com.mysql.jdbc.Driver"
      p:url="jdbc:mysql:///springdb" p:username="root" p:password="1234"/>

<bean id="userService2" class="com.itheima.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>

4 Bean依赖注入的数据类型

普通数据类型

基本类型和string

通过标签的value属性注入数据

引用数据类型

通过标签的ref属性注入数据

集合数据类型(了解)

单列集合

list、set、array

都可以使用其中的任意一个单列标签进行依赖注入

双列集合

map、props

可以使用其中的任意一个双列标签进行依赖注入

public class CollectionBean {
    private List ll;
    private Set ss;
    private int[] arr;

    private Map mm;
    private Properties pp;

    public void setLl(List ll) {
        this.ll = ll;
    }

    public void setSs(Set ss) {
        this.ss = ss;
    }

    public void setArr(int[] arr) {
        this.arr = arr;
    }

    public void setMm(Map mm) {
        this.mm = mm;
    }

    public void setPp(Properties pp) {
        this.pp = pp;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "ll=" + ll +
                ", ss=" + ss +
                ", arr=" + Arrays.toString(arr) +
                ", mm=" + mm +
                ", pp=" + pp +
                '}';
    }
}


<!--
        List ll = new ArrayList();
        ll.add(22);
        ll.add(33);
        ll.add(orderDao);
        ll.add(new Date());
    -->
    <bean id="collectionBean" class="com.itheima.vo.CollectionBean">
        <property name="ll">
            <list>
                <value>22</value>
                <value>33</value>
                <ref bean="orderDao"/>
                <bean class="java.util.Date"/>
            </list>
        </property>

        <property name="ss">
           <!-- <set>
                <value>aa</value>
                <value>bb</value>
            </set>-->
            <list>
                <value>aa</value>
                <value>bb</value>
            </list>
        </property>

        <property name="arr">
            <!--<array>
                <value>1</value>
                <value>11</value>
            </array>-->
            <list>
                <value>1</value>
                <value>11</value>
            </list>
        </property>

        <property name="mm">
            <map>
                <entry key="aa" value="11"/>
                <entry key="bb" value="22"/>
            </map>
        </property>

        <property name="pp">
            <!--<props>
                <prop key="cc">33</prop>
                <prop key="dd">44</prop>
            </props>-->
            <map>
                <entry key="ccc" value="111"/>
                <entry key="ddd" value="222"/>
            </map>
        </property>
    </bean>

七 配置文件模块化

进入企业开发我们会按模块来进行配置文件配置,将现有的配置文件的抽取

并集配置【了解】

ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml","xxx.xml");

主从配置【重点】

在spring的主配置文件中通过import标签引入其他的配置文件即可

<!--
        引入spring其他的配置文件
            resource中的classpath暂时可以不写,但是到web项目中的时候就必须写
    -->
<import resource="classpath:xxx.xml"/>

八 DBUtils

1 DBUtils概述

DBUtils是Apache的一款用于简化Dao代码的工具类,它底层封装了JDBC技术。

核心对象:QueryRunner

​ 作用:执行sql语句对象

构造器:

​ new QueryRunner(DataSource 连接池);

核心方法

方法名作用
update(sql,Object … args)执行DML语句
query(sql,ResultSetHandler hl,Object … args)执行DQL语句
update(conn,sql,Object … args)执行DML语句
query(conn,sql,ResultSetHandler hl,Object … args)执行DQL语句

快速入门-保存操作

需求:

​ 往账户表中保存一条记录

步骤:

  1. 导入依赖(mysql驱动,druid,junit,dbutils)
  2. 导入JDBCUtils工具类(jdbc哪天编写的)及数据库配置文件 (今天资料中也有)
  3. 创建AccountDao接口及其实现类
  4. 编写save方法
    • 创建QueryRunner对象
    • 执行插入操作
  5. 编写测试类

实现:

数据库表

CREATE DATABASE springdb;
USE springdb;
CREATE TABLE account(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(8),
	money INT
);
INSERT INTO account VALUES(NULL,'tom',1000),(NULL,'jack',1000);

pom.xml

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.32</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.9</version>
</dependency>
<dependency>
    <groupId>commons-dbutils</groupId>
    <artifactId>commons-dbutils</artifactId>
    <version>1.4</version>
</dependency>

Account类

public class Account {
    private Integer id;
    private String name;
    private Double money;
    //getter和setter自己提供
}

AccountDaoImpl

public class AccountDaoImpl implements AccountDao {
    @Override
    public int save(Account account) throws SQLException {
        //- 创建QueryRunner对象
        QueryRunner qr = new QueryRunner(JDBCUtils.getDS());
        //- 执行插入操作
        int row = qr.update("insert into account values(null,?,?)", account.getName(), account.getMoney());
        return row;
    }
}

测试类

public class H_TestDBUtilsHello {
    public static void main(String[] args) throws SQLException {
        //创建account对象
        Account account = new Account();
        account.setName("rose");
        account.setMoney(2000d);

        //创建AccountDao对象
        AccountDao accountDao = new AccountDaoImpl();

        //调用dao方法
        System.out.println(accountDao.save(account));
    }
}

2 Spring整合DBUtils

需求

​ 基于Spring的IOC的xml配置,实现账户的CRUD案例

​ 提供servie和dao

技术分析

  1. 数据源(连接池)一个项目中只需要使用一个,可以交给spring管理
  2. QueryRunner对象一个项目中只需要使用一个,可以交给spring管理
    • 通过构造方法注入连接池
  3. AccountDaoImpl对象一个项目中值需要使用一个,可以交给spring管理
    • 提供QueryRunner成员变量,提供set方法
    • 使用set方式注入QueryRunner对象
  4. AccountService对象一个项目中只需要使用一个,可以交给spring管理
    • 提供AccountDao成员变量,且提供set方法
    • 使用set方式注入AccountDao对象

步骤分析

  1. 新建一个模块
  2. 导入依赖(mysql驱动,druid,junit,commons-dbutils,spring-context)
  3. 新建Account类
  4. 新建AccountDao接口及其实现类,提供crud操作
    • 提供Queryrunner成员变量及其set方法
  5. 新建AccountService接口及其实现类,提供crud操作
    • 提供AccountDao成员变量及其set方法
  6. 编写spring配置文件
    • 配置数据源,queryRunner,dao,service
  7. 测试

代码实现

  • dao中的代码
public class AccountDaoImpl implements AccountDao {
    private QueryRunner qr;
    public void setQr(QueryRunner qr) {
        this.qr = qr;
    }

    @Override
    public int save(Account account) throws SQLException {
        return qr.update("insert into account values(null,?,?)",account.getName(),account.getMoney());
    }

    @Override
    public int update(Account account) throws SQLException {
        return qr.update("update account set name = ?,money = ? where id = ?",account.getName(),account.getMoney(),account.getId());
    }

    @Override
    public int delete(int id) throws SQLException {
        return qr.update("delete from account where id = ?",id);
    }

    @Override
    public List<Account> findAll() throws SQLException {
        List<Account> list = qr.query("select * from account", new BeanListHandler<Account>(Account.class));
        return list;
    }

    @Override
    public Account findById(int id) throws SQLException {
        Account acc = qr.query("select * from account where id = ?", new BeanHandler<>(Account.class), id);
        return acc;
    }

    @Override
    public int findTotal() throws SQLException {
        Long i = (Long)qr.query("select count(*) from account", new ScalarHandler());
        return i.intValue();
    }
}

  • service中的代码
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public int save(Account account) throws SQLException {
        return accountDao.save(account);
    }

    @Override
    public int update(Account account) throws SQLException {
        return accountDao.update(account);
    }

    @Override
    public int delete(int id) throws SQLException {
        return accountDao.delete(id);
    }

    @Override
    public List<Account> findAll() throws SQLException {
        return accountDao.findAll();
    }

    @Override
    public Account findById(int id) throws SQLException {
        return accountDao.findById(id);
    }

    @Override
    public int findTotal() throws SQLException {
        return accountDao.findTotal();
    }
}


  • 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///springdb"/>
        <property name="username" value="root"/>
        <property name="password" value="1234"/>
    </bean>

 	<!--配置queryRunner-->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner">
        <!--通过构造器注入数据源-->
        <constructor-arg name="ds" ref="dataSource"/>
    </bean>

    <!--配置dao-->
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
        <!--通过set方式注入queryRunner-->
        <property name="runner" ref="runner"/>
    </bean>


    <!--配置service-->
    <bean id="accountService" class="com.itheima.service.AccountServiceImpl">
        <!--通过set方式注入dao-->
        <property name="accountDao" ref="accountDao"/>
    </bean>
</beans>

  • 测试
package com.itheima.test;

import com.itheima.domain.Account;
import com.itheima.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.sql.SQLException;
import java.util.List;

public class TestService {
    @Test
    public void testSave() throws SQLException {
        Account account = new Account();
        account.setMoney(200);
        account.setName("柴桑");

        //创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        //获取service
        AccountService accountService = (AccountService) ac.getBean("accountService");

        int i = accountService.save(account);

        System.out.println(i);
    }

    @Test
    public void testUpdate() throws SQLException {
        Account account = new Account();
        account.setMoney(1200);
        account.setName("柴先生");
        account.setId(4);

        //创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        //获取service
        AccountService accountService = (AccountService) ac.getBean("accountService");

        int i = accountService.update(account);

        System.out.println(i);
    }

    @Test
    public void testFindAll() throws SQLException {
        //创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        //获取service
        AccountService accountService = (AccountService) ac.getBean("accountService");

        List<Account> list = accountService.findAll();

        for (Account account : list) {
            System.out.println(account);
        }
    }

    @Test
    public void testFindTotal() throws SQLException {
        //创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        //获取service
        AccountService accountService = (AccountService) ac.getBean("accountService");

        System.out.println(accountService.findTotal());

    }
}


3 抽取jdbc配置

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///springdb
jdbc.username=root
jdbc.password=1234

九 总结

ioc:

控制反转,将bean的创建权交给spring管理

步骤:

  1. 导入spring-context依赖

  2. 编写spring的配置文件

    <bean id="起个名字" class="全限定类名"/>

  3. 编写java代码,从容器中获取指定的对象

    ApplicationContext ac = new ClasspathXMLApplicationContext("配置文件名字");
    目标对象 = ac.getBean("bean的id写上");
    
    

bean的实例化三种方式:

  • 构造器实例化
  • 工厂静态方法实例化(了解)
  • 工厂普通方法实例化(了解)

DI:依赖注入

  • 在ioc的基础上,将bean交给spring管理的时候,需要把这个bean中的成员变量赋值进去.
    • 可以通过set方式
    • 可以通过构造器方式

DI方式

  • set方式
    • 要求成员变量必须有set方法
    • 在配置文件中通过bean标签的property标签注入属性值
      • <property name="属性名称" value=""|ref=""/>
  • 构造器方式
    • 要求提供相应的构造器
    • 在配置文件中通过bean标签的constructor-arg标签注入值
      • <constructor-arg name="参数名字" value=""|ref=""/>
  • p名称空间方式(set方法精简版)

给集合数据类型注入数据

  • 单列集合:list set array任何一个标签进行注入数据
  • 双列集合:map props任何一个标签进行注入数据

模块化:

  • 主从配置,在主配置文件中通过import标签来引入其他spring配置文件

DBUtils:

  • apache提供的dao层工具类
  • new QueryRunner(连接池);
  • 两套方法
    • update(…)
    • query(…)

spring整合DBUtils

  • 分析出模块中那些是单实例对象,就可以将这些对象交给spring管理.若需要注入数据的话,使用set或者构造方法注入
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值