Spring框架-ioc和JdbcTemplate

前提

​ 我们用了Mybatis时,已经不需要再使用其他的持久层框架了。用了mybatis之后,我们只需要写持久层接口以及sql语句即可。

但是为了讲解spring中的事务,我们把JdbcTemplate拿出来讲,使用JdbcTemplate需要编写持久层实现类。

​ 此时有两个目的:

​ 第一个:通过JdbcTemplate去铺垫Spring第三天课程的事务控制。(配置的方式实现)

​ 第二个:通过JdbcTemplate去更加深入掌握依赖注入思想(今天就说明明白)

spring的课程安排

  1. 课程时长: 共5天。其中spring框架3天,springmvc框架2天

  2. Spring3天:

    ​ Spring基于XML的IOC 第一天

    ​ Spring基于注解的IOC 第二天

         Spring的AOP(xml和注解)以及Spring的事务控制(XML和注解) 第三天
    
    3. SpringMVC 2天:
    

    ​ SpringMVC的请求部分

    ​ SpringMVC的响应部分和SSM整合(Spring+SpringMVC+Mybatis)

第一章 Spring介绍(了解)

1.1 概述

Spring是分层的Java SE/EE应用 full-stack(全栈式)轻量级开源框架,以IoCInverse Of Control:反转控制)和AOPAspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。

其中full stack意为全栈式,在基于Java SE/EE的开发中,Spring框架各个部分的解决方案,例如持久层操作有Spring Jdbc/Spring Data,表现层操作有Spring MVC,Spring WebFlow等等,当然它还有很多针对项目特定需求的技术框架,在随着我们课程的深入,会逐步给同学们展现和讲解。

在我们今天讲解的Spring课程指的是Spring Framework,我们可以通过官网查看,Spring的官方网址为:

https://spring.io,浏览器输入网址可以看到如下界面:

Spring框架-ioc和JdbcTemplate_第1张图片

Spring是分层的Java应用轻量级开源框架,核心是IOC和AOP

* 分层:Spring在三层上都有自己的解决方案

* 轻量级:只启动Spring核心容器的时候,占用的内存少,耗费的资源少

* 开源:源代码开发

* 核心:IOC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)
       DI  Dependency Injection 依赖注入(如果被问到spring的3大核心,这个就是第三个)
	

1.2 体系架构图

Spring框架-ioc和JdbcTemplate_第2张图片

1.3 官方文档

Spring框架-ioc和JdbcTemplate_第3张图片

第二章 SpringIOC入门(重点)

2.1 IOC介绍

对象的创建由原来的使用new关键字在类中主动创建变成了从工厂中获取,而对象的创建过程由工厂内部来实现,

而这个工厂就是Spring的IOC容器,也就是以后我们的对象不再自己创建,而是直接向Spring要,这种思想就是IOC

IOC(控制反转)是一种设计思想,它的目的是指导我们设计出更加松耦合的程序。

控制:指的是控制权,现在可以简单理解为对象的创建权限

反转:指的对象的控制权由程序员在类中主动控制(new)反转到由Spring容器来控制。

2.2 案例实现

使用Spring的IOC来实现service和dao代码的解耦

2.2.1 环境搭建

Spring框架-ioc和JdbcTemplate_第4张图片

2.2.2基础代码编写

Spring框架-ioc和JdbcTemplate_第5张图片

2.2.3配置文件


<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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    

    
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">bean>

    
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">bean>
beans>

2.2.4测试代码

package com.itheima.test;

import com.itheima.dao.UserDao;
import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Spring基于XML的ioc入门案例
 */
public class SpringIoCTest {

    public static void main(String[] args) {
        //1.读取spring的配置文件,创建ioc容器(我们就可以把他想成是一个map)
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
        //2.根据存入时的id获取对象
        UserDao userDao = (UserDao)ac.getBean("userDao");
        UserService userService = ac.getBean("userService", UserService.class);

        //取到的对象,他是spring帮我们创建并且存入ioc容器的
        System.out.println(userDao);
        System.out.println(userService);

        userService.saveUser();
    }
}

2.3要点分析

  1. SpringIOC容器启动过程中要做哪些操作

    ![[]](https://img-blog.csdnimg.cn/8a3f7b3154cc4f1ab225b584f0f76db4.png)

  2. SpringIOC存储对象的Map到底在哪里
    Spring框架-ioc和JdbcTemplate_第6张图片

2.4API(了解)

2.4.1两个接口

* BeanFactory
	这是SpringIOC容器的顶级接口,它定义了SpringIOC的最基础的功能,但是其功能比较简单,一般面向Spring自身使用
	BeanFactroy在第一次使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化

* ApplicationContext
	这是在BeanFactory基础上衍生出的接口,它扩展了BeanFactory的功能,一般面向程序员使用 
	ApplicationContext是在容器启动时,根据用户的配置选择一次性创建并加载了所有的Bean,或者在使用时才创建Bean

* 注意: 上面两种方式创建的对象都是单例,只是创建对象的时机不同


bean 指的就是我们写在spring配置文件中的对象

2.4.2三个实现类

* 这三个类的作用都是:读取配置文件, 初始化Spring的IOC容器,  不一样的是加载配置文件的位置
	- ClassPathXmlApplicationContext         读取类路径下的xml作为配置文件
	- FileSystemXmlApplicationContext        读取本地目录下的xml作为配置文件	
	- AnnotationConfigApplicationContext     读取一个Java类作为配置文件

Spring框架-ioc和JdbcTemplate_第7张图片

2.4.3一个方法

* getBean() 用于从Spring容器中获取Bean对象,参数可以使用三种情况:
	getBean("id")                     使用bean的id从容器中查找对象
	getBean(Bean.class)               使用bean的class类型从容器中查找对象
	getBean("id", Bean.class)         使用bean的id 和 class类型从容器中查找对象

第三章Bean的配置(重点)

3.1bean的创建方式

3.1.1环境准备

package com.itheima.service;

/**
 * 用户的业务层接口
 */
public interface UserService {

    /**
     * 模拟一个业务层方法
     */
    void saveUser();
}

package com.itheima.service.impl;

import com.itheima.service.UserService;

/**
 * 用户的业务层实现类
 *
 * 此处我们用此类和类中的方法演示bean定义的细节
 */
public class UserServiceImpl implements UserService {

    /**
     * 构造方法
     */
    public UserServiceImpl(){
        System.out.println("对象创建了");
    }

    /**
     * 初始化方法
     */
    public void init(){
        System.out.println("对象初始化好了");
    }

    /**
     * 销毁方法
     */
    public void destroy(){
        System.out.println("对象销毁了");
    }

    @Override
    public void saveUser() {
        System.out.println("此处就是业务层调用持久层实现功能");
    }
}

3.1.2创建对象的三种方式(了解)

我们常用的创建对象的方式有三种:

  1. 直接使用new关键字创建
  2. 使用静态工厂创建
  3. 使用实例化工厂创建

3.1.3直接调用构造函数创建


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
		
		
		

    
    
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">bean>
beans>

3.1.4使用静态工厂创建

package com.itheima.factory;

import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;

/**
 * 静态工厂
 *
 */
public class StaticFactory {

    /**
     * 模拟使用第三方工具包来创建对象
     * 第三方工具包中的对象没法使用默认构造函数创建
     * 而是提供了一个工厂,在工厂中有一个静态方法,这个方法可以获取到我们想要的对象
     * 那么spring是支持把他配置到ioc容器的
     * @return
     */
    public static UserService createUserService(){
        return  new UserServiceImpl();
    }
}

    
    <bean id="userService2" class="com.itheima.factory.StaticFactory" factory-method="createUserService">bean>

3.1.5使用实例化工厂创建

package com.itheima.factory;

import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;

/**
 * 实例工厂
 *
 */
public class InstanceFactory {

    /**
     * 模拟使用第三方工具包来创建对象
     * 第三方工具包中的对象没法使用默认构造函数创建
     * 而是提供了一个工厂,在工厂中有一个普通方法,这个方法可以获取到我们想要的对象
     * 那么spring是支持把他配置到ioc容器的
     * @return
     */
    public UserService createUserService(){
        return  new UserServiceImpl();
    }
}

    
    <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory">bean>
    <bean id="userService3" factory-bean="instanceFactory" factory-method="createUserService">bean>

3.2bean的作用域

* 在Spring中,对于bean支持多种作用域,常见的有下面几个:
- singleton(默认)    单例模式,即对象只创建一次, 然后一直存在
- prototype          多例模式,即每次获取bean的时候,IOC 都给我们创建一个新对象
- request            web项目中,Spring创建一个Bean的对象,将对象存入到request域中
- session            web 项目中,Spring 创建一个Bean 的对象,将对象存入到session域中
 

    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl" scope="singleton">bean>


3.3bean的生命周期

研究bean的生命周期,无非就是弄明白bean是什么时候创建的,什么时候销毁的

在Spring中,bean的作用范围会影响到其生命周期,所以我们要分单例和多例对象来研究bean的生命周期

    
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"
          scope="prototype" init-method="init" destroy-method="destroy">bean>

3.4依赖注入(重点)

依赖注入(Dependency Injection,DI) 其实就是给对象中的属性赋值的过程

依赖注入有两种方式,分别是使用构造函数和set方法

3.4.1环境准备

package com.itheima.service;

/**
 * 用户的业务层接口
 */
public interface UserService {

    /**
     * 模拟一个业务层方法
     */
    void saveUser();
}

3.4.2构造函数注入

package com.itheima.service.impl;

import com.itheima.service.UserService;

import java.util.*;

/**
 * 用户的业务层实现类
 */
public class UserServiceImpl implements UserService {

    private String driver;//基本类型和String的演示
    private int port;//基本类型和String的演示

    private Date date;//其他bean类型的演示

    private String[] myStrs;//数组类型的演示
    private List<String> myList;//list集合类型的演示
    private Set<String> mySet;//set集合类型的演示
    private Map<String,String> myMap;//map集合的类型的演示
    private Properties myProps;//properties类型的演示

    public UserServiceImpl(String driver, int port, Date date) {
        this.driver = driver;
        this.port = port;
        this.date = date;
    }

    @Override
    public void saveUser() {
        System.out.println(driver);
        System.out.println(port);
        System.out.println(date);
    }
}

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    
		
    
    
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
        <constructor-arg name="driver" value="com.mysql.jdbc.Driver">constructor-arg>
        <constructor-arg name="port" value="3306">constructor-arg>
        <constructor-arg name="date" ref="now">constructor-arg>
    bean>

    <bean id="now" class="java.util.Date">bean>
beans>

3.4.3set方法注入

package com.itheima.service.impl;

import com.itheima.service.UserService;

import java.util.*;

/**
 * 用户的业务层实现类
 * 用于演示set方法注入
 */
public class UserServiceImpl2 implements UserService {

    private String driver;//基本类型和String的演示
    private int port;//基本类型和String的演示

    private Date date;//其他bean类型的演示

    private String[] myStrs;//数组类型的演示
    private List<String> myList;//list集合类型的演示
    private Set<String> mySet;//set集合类型的演示
    private Map<String,String> myMap;//map集合的类型的演示
    private Properties myProps;//properties类型的演示

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public void setMyStrs(String[] myStrs) {
        this.myStrs = myStrs;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }

    @Override
    public void saveUser() {
        System.out.println(driver);
        System.out.println(port);
        System.out.println(date);
        System.out.println(Arrays.toString(myStrs));
        System.out.println(myList);
        System.out.println(mySet);
        System.out.println(myMap);
        System.out.println(myProps);
    }
}

    <bean id="userService2" class="com.itheima.service.impl.UserServiceImpl2">
        <property name="driver" value="com.itheima.test">property>
        <property name="port" value="8080">property>
        <property name="date" ref="now">property>
    bean>

3.4.4注入集合属性

 
        <property name="myStrs">
            <array>
                <value>AAAvalue>
                <value>BBBvalue>
                <value>CCCvalue>
            array>
        property>
        <property name="myList">
            <array>
                <value>AAAvalue>
                <value>BBBvalue>
                <value>CCCvalue>
            array>
        property>
        <property name="mySet">
            <array>
                <value>AAAvalue>
                <value>BBBvalue>
                <value>CCCvalue>
            array>
        property>

        <property name="myMap">
            <props>
                <prop key="propKey1">propValue1prop>
                <prop key="propKey2">propValue2prop>
                <prop key="propKey3">propValue3prop>
            props>
        property>

        <property name="myProps">
            <map>
                <entry key="key1" value="value1">entry>
                <entry key="key2" value="value2">entry>
                <entry key="key3" value="value3">entry>
            map>
        property>

3.5多配置文件使用

* 我们现在的配置都集中配在了一个applicationContext.xml文件中,这样会使这个文件很难维护。
* 针对这个问题,Spring给我们提供了两种解决方案:
	1. 同时引入多个配置文件
	2. 引入一个主配置文件,在主配置文件中引入其他配置文件

* 注意:
	1. 同一个xml文件中不允许出现相同名称的bean,如果出现会报错
	2. 多个xml文件如果出现相同名称的bean,不会报错,但是后加载的会覆盖前加载,所以尽量保证bean的名称是唯一的

第四章 JdbcTemplate(会用)

4.1JdbcTemplate介绍

* JdbcTemplate是Spring提供的持久层技术,用于操作数据库,它底层封装了JDBC技术。
* 核心类:
	JdbcTemplate  用于执行增删改查的SQL语句
	RowMapper     这是一个接口,主要作用是将数据库返回的记录封装进实体对象
* 核心方法:
	update  用来执行增、删、改语句
	query/queryForObject用来执行查询语句
//创建一个JdbcTemplate对象,用来执行增删改查, 需要给一个数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//update方法,用于执行增删改语句
//第一个参数:sql语句   后面的参数:sql语句中的所需要的的值
jdbcTemplate.update("insert into account value(null,?,?)",1,2);

//query或者queryForObject方法,用于执行查询语句
//query 用于查询多条记录,返回一个集合   queryForObject用于查询一条记录,返回一个实体
//第一个参数:sql语句   第二个参数:封装返回值   后面的参数:sql语句中的所需要的的值
jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class)); 
jdbcTemplate.queryForObject("select * from account where id = ?",  new BeanPropertyRowMapper<Account>(Account.class), 1);

4.2JdbcTemplate使用

使用JdbcTemplate完成对数据库的增删改查

准备数据环境

create table account(
	id int primary key auto_increment,
	name varchar(100) not null unique,
	money float(10,2)
)

4.2.2 创建模块,引入依赖

Spring框架-ioc和JdbcTemplate_第8张图片

 <dependencies>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>5.3.12version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.3.12version>
        dependency>

        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>

        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
            <version>1.1.21version>
        dependency>

        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.18version>
        dependency>

        
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>
    dependencies>

4.2.3 创建实体类

package com.itheima.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.Serializable;

/**
 * 账户的实体类
 */
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Account implements Serializable {

    private Integer id;
    private String name;
    private Float money;
}

4.2.4 编写配置文件


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    
    <context:property-placeholder location="classpath:jdbc.properties">context:property-placeholder>
		
	
    <bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource">property>
    bean>

    
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}">property>
        <property name="url" value="${jdbc.url}">property>
        <property name="username" value="${jdbc.username}">property>
        <property name="password" value="${jdbc.password}">property>
    bean>
beans>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_ee393
jdbc.username=root
jdbc.password=1234

4.2.5 测试

package com.itheima.test;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * JdbcTemplate的入门案例
 */
public class JdbcTemplateDemo1 {

    /**
     * JdbcTemplate的使用:
     *     1.创建对象
     *     2.调用方法完成对数据库的操作
     *          update  增删改方法都执行JdbcTemplate的update方法
     *          query   查询方法都执行JdbcTemplate的query方法
     * @param args
     */
    public static void main(String[] args) {
        //1.创建JdbcTemplate的对象
        JdbcTemplate jt = new JdbcTemplate();
        //2.为JdbcTemplate准备数据源
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring_ee393");
        dataSource.setUsername("root");
        dataSource.setPassword("1234");
        //3.把数据源传给JdbcTemplate
        jt.setDataSource(dataSource);
        //4.保存一个账户
        String sql = "insert into account(name,money)values(?,?);";//JDBC的参数占位符(不是mybatis)
        jt.update(sql,"test",1000f);
    }
}

package com.itheima.test;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * JdbcTemplate的入门案例
 *      使用Spring的IoC容器
 */
public class JdbcTemplateDemo2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        //1.读取核心配置文件,创建ioc容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.根据id获取JdbcTemplate对象
        JdbcTemplate jt = ac.getBean("jt", JdbcTemplate.class);
        //3.保存一个账户
        String sql = "insert into account(name,money)values(?,?);";//JDBC的参数占位符(不是mybatis)
        jt.update(sql,"ioc",2000f);
    }
}

package com.itheima.test;

import com.itheima.domain.Account;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.ArrayList;
import java.util.List;

/**
 * JdbcTemplate的入门案例
 *      使用JdbcTemplate完成增删改查
 */
public class JdbcTemplateDemo3 {

    private JdbcTemplate jt = null;

    @Before
    public void init(){
        //1.读取核心配置文件,创建ioc容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.根据id获取JdbcTemplate对象
        jt = ac.getBean("jt", JdbcTemplate.class);
    }
    /**
     *   JdbcTemplate的update(String sql,Object...params);
     *      增删改方法都使用这个update方法
     *      第一个参数:要执行的SQL语句
     *      第二个参数:执行语句所需的参数
     */


    /**
     * 测试保存
     */
    @Test
    public void testSave(){
        //3.保存一个账户
        String sql = "insert into account(name,money)values(?,?);";//JDBC的参数占位符(不是mybatis)
        jt.update(sql,"ioc",2000f);
    }

    /**
     * 测试更新
     */
    @Test
    public void testUpdate(){
        jt.update("update account set name=? , money=? where id=?","ee393期",50000f,1);
    }


    @Test
    public void testDelete(){
        int res = jt.update("delete from account where id = ?", 2);
        System.out.println("影响数据库记录的行数:"+res);
    }

    /**
     * JdbcTemplate的query(String sql,RowMapper rowMapper,Object...params)方法
     *    该方法只能用于查询,他有3个参数
     *    第一个参数:要执行的SQL语句
     *    第二个参数:指定查询结果的封装规则。
     *                RowMapper他是一个接口,我们可以自己写实现类
     *                通常情况下我们都会封装到实体类中,只要实体类的属性与数据库表中字段一致,就可以使用Spring提供的
     *                Spring提供的类:BeanPropertyRowMapper
     *    第三个参数:执行sql语句所需的参数
     *
     */

    /**
     * 测试查询所有
     */
    @Test
    public void testFindAll(){
        List<Account> accounts = jt.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class));
        for (Account account : accounts) {
            System.out.println(account);
        }
    }

    /**
     * 测试根据id查询
     */
    @Test
    public void testFindById(){
        List<Account> accounts = jt.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),1);
        if(accounts != null && accounts.size() > 0 ){
            System.out.println(accounts.get(0));
        }
    }
}

第五章 综合练习(重点)

使用Spring和JdbcTemplate完成对数据库的crud操作

  • 持久层 JdbcTemplate

  • 业务层 Spring

  • 表示层 单元测试

5.1 创建模块,引入依赖

Spring框架-ioc和JdbcTemplate_第9张图片

 <dependencies>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>5.3.12version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.3.12version>
        dependency>

        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>

        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
            <version>1.1.21version>
        dependency>

        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.18version>
        dependency>

        
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>
    dependencies>

5.2 创建实体类

package com.itheima.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.Serializable;

/**
 * 账户的实体类
 */
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Account implements Serializable {

    private Integer id;
    private String name;
    private Float money;
}

5.3创建dao层接口

package com.itheima.dao;

import com.itheima.domain.Account;

import java.util.List;

/**
 * 账户的持久层接口
 */
public interface AccountDao {

    /**
     * 查询所有账户
     * @return
     */
    List<Account> findAll();

    /**
     * 根据id查询账户
     * @param id
     * @return
     */
    Account findById(Integer id);

    /**
     * 保存
     * @param account
     */
    void save(Account account);

    /**
     * 更新
     * @param account
     */
    void update(Account account);

    /**
     * 删除
     * @param id
     */
    void delete(Integer id);
}

5.4创建dao层实现类

package com.itheima.dao.impl;

import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * 账户的持久层实现类
 */
public class AccountDaoImpl implements AccountDao {

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public List<Account> findAll() {
        return jdbcTemplate.query("select * from account ",new BeanPropertyRowMapper<Account>(Account.class));
    }

    @Override
    public Account findById(Integer id) {
        List<Account> accounts = jdbcTemplate.query("select * from account where id = ? ", new BeanPropertyRowMapper<Account>(Account.class), id);
        return (accounts != null && accounts.size() == 1) ? accounts.get(0) : null ;
    }

    @Override
    public void save(Account account) {
        jdbcTemplate.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney());
    }

    @Override
    public void update(Account account) {
        jdbcTemplate.update("update account set name=?,money=? where id = ?",account.getName(),account.getMoney(),account.getId());
    }

    @Override
    public void delete(Integer id) {
        jdbcTemplate.update("delete from account where id = ?",id);
    }
}

5.5 创建service层接口

package com.itheima.service;


import com.itheima.domain.Account;

import java.util.List;

/**
 * 账户的业务层接口
 */
public interface AccountService {

    /**
     * 查询所有账户
     * @return
     */
    List<Account> findAll();

    /**
     * 根据id查询账户
     * @param id
     * @return
     */
    Account findById(Integer id);

    /**
     * 保存
     * @param account
     */
    void save(Account account);

    /**
     * 更新
     * @param account
     */
    void update(Account account);

    /**
     * 删除
     * @param id
     */
    void delete(Integer id);
}

5.6 创建service层实现类

package com.itheima.service.impl;

import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;

import java.util.List;

/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

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

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

    @Override
    public Account findById(Integer id) {
        return accountDao.findById(id);
    }

    @Override
    public void save(Account account) {
        accountDao.save(account);
    }

    @Override
    public void update(Account account) {
        accountDao.update(account);
    }

    @Override
    public void delete(Integer id) {
        accountDao.delete(id);
    }
}

5.7 加入spring的配置文件


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    
    <context:property-placeholder location="classpath:jdbc.properties">context:property-placeholder>

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

    
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}">property>
        <property name="url" value="${jdbc.url}">property>
        <property name="username" value="${jdbc.username}">property>
        <property name="password" value="${jdbc.password}">property>
    bean>
beans>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
        
        <property name="jdbcTemplate" ref="jdbcTemplate">property>
    bean>

beans>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
        
        <property name="accountDao" ref="accountDao">property>
    bean>


beans>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    
    <import resource="classpath:applicationContext-dao.xml">import>
    <import resource="classpath:applicationContext-jdbc.xml">import>
    <import resource="classpath:applicationContext-service.xml">import>

beans>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_ee393
jdbc.username=root
jdbc.password=1234

5.8 测试

package com.itheima.test;

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

import java.util.List;

/**
 * 测试spring的ioc配置
 */
public class AccountServiceTest {

    private AccountService accountService;

    @Before
    public void init(){
        //1.获取Ioc容器
        //spring多配置文件开发之:并列关系
//        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext-dao.xml",
//                                                                                     "classpath:applicationContext-service.xml",
//                                                                                     "classpath:applicationContext-jdbc.xml");
        //spring多配置文件开发之:主从关系   如果只是单独使用spring,主从关系的配置方式更多一些。(后面用了spring-boot之后,就不区分,只有一个配置文件)
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        //2.根据id获取bean
        accountService = ac.getBean("accountService", AccountService.class);
    }

    @Test
    public void testFindAll(){
        List<Account> accounts = accountService.findAll();
        for (Account account : accounts) {
            System.out.println(account);
        }
    }

    @Test
    public void testFindById(){
        Account account = accountService.findById(1);
        System.out.println(account);
    }

    @Test
    public void testSave(){
        Account account = new Account();
        account.setName("测试ioc");
        account.setMoney(10000f);
        accountService.save(account);
    }

    @Test
    public void testUpdate(){
        Account account = accountService.findById(3);
        account.setName("testioc");
        account.setMoney(5678f);
        accountService.update(account);
    }

    @Test
    public void testDelete(){
        accountService.delete(3);
    }
}

你可能感兴趣的:(Spring框架,spring,java,经验分享,maven,后端)