SpringIoC三层架构实战

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 一、需求分析 二、创建相关数据库 三、导入相关依赖 四、实体类准备 五、相关技术讲解(Druid、JDBCTemplate) 六、三层架构实现案例

 

一、需求分析

搭建一个三层架构案例,模拟查询全部学生(学生表)信息,持久层使用JdbcTemplate和Druid技术,使用XML方式进行组件管理!

image.gif编辑


二、创建相关数据库

create database studb;
use studb;
CREATE TABLE students (
  id INT PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  gender VARCHAR(10) NOT NULL,
  age INT,
  class VARCHAR(50)
);
INSERT INTO students (id, name, gender, age, class)
VALUES
  (1, '张三', '男', 20, '高中一班'),
  (2, '李四', '男', 19, '高中二班'),
  (3, '王五', '女', 18, '高中一班'),
  (4, '赵六', '女', 20, '高中三班'),
  (5, '刘七', '男', 19, '高中二班'),
  (6, '陈八', '女', 18, '高中一班'),
  (7, '杨九', '男', 20, '高中三班'),
  (8, '吴十', '男', 19, '高中二班');

image.gif

创建完成后表格如下所示

image.gif编辑


三、导入相关依赖

<!-- SpringIoc核心jar包 包含core ioc breans 等 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>
    <!-- junit5测试 -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.3.1</version> <!-- 使用属性引用JUnit Jupiter版本 -->
      <scope>test</scope>
    </dependency>
<!--        mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>
<!--        spring-jdbc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>6.0.6</version>
        </dependency>
<!--德鲁伊连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>

image.gif


四、实体类准备

package com.alphamilk;
public class Student {
    private Integer id;
    private String name;
    private String gender;
    private Integer age;
    private String classes;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getClasses() {
        return classes;
    }
    public void setClasses(String classes) {
        this.classes = classes;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", classes='" + classes + '\'' +
                '}';
    }
}

image.gif


五、相关技术讲解(Druid、JDBCTemplate)

JDBCTemplate技术讲解

为了在特定领域帮助我们简化代码,Spring 封装了很多 『Template』形式的模板类。例如:RedisTemplate、RestTemplate 等等,包括我们今天要学习的 JdbcTemplate。 jdbc.properties 提取数据库连接信息

使用JDBCTemplate:

package com.alphamilk;
import com.alibaba.druid.pool.DruidDataSource;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;
public class test {
    @Test
    public  void Test(){
//        创建连接池对象
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/studb"); //url地址
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");//驱动信息
        dataSource.setUsername("mysql");//数据库用户名
        dataSource.setPassword("123456");//数据库密码
//    1.创建JDBCTemplate对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
//      2.传入数据连接池对象
        jdbcTemplate.setDataSource(dataSource);
//      3.实现增删查改
//       实现数据更新操作
//        jdbcTemplate.update();DDL DML DCL等非查询语句
//        jdbcTemplate.query(); DQL 查询单个对象
//        jdbcTemplate.queryForObject(); DQL 查询集合
        /*
        注意:JDBCTemplate只是简化了数据库的CRUD,并不负责提供连接池
        DruidDataSource 用于连接和创建连接池对象和数据库驱动等等
         */
    }
}

image.gif

将两个对象使用xml配置为组件

1.在项目配置下创建peoperties资源文件,将个人信息所有都放入进去,方便以后修改

alphamilk.url=jdbc:mysql://localhost:3306/studb
alphamilk.driver=com.mysql.cj.jdbc.Driver
alphamilk.username=mysql
alphamilk.password=123456

image.gif

2.写入配置文件xml

创建xml,配置IoC与DI

<?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">
<!--    引入.properties文件,.properties =》 value = “${key}”-->
<!--    context:property-placeholder location="jdbc.properties","其他properties文件",,,用逗号隔开-->
    <context:property-placeholder location="jdbc.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${alphamilk.url}"/>
        <property name="driverClassName" value="${alphamilk.driver}"/>
        <property name="username" value="${alphamilk.username}"/>
        <property name="password" value="${alphamilk.password}"/>
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

image.gif

测试:

package com.alphamilk;
import com.alibaba.druid.pool.DruidDataSource;
import com.alphamilk.pojo.Student;
import org.junit.jupiter.api.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 org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public class test {
    @Test
    public  void Test(){
//        创建Ioc容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("SpringProject.xml");
//        通过容器getBean获取组件
        DruidDataSource dataSource = (DruidDataSource) applicationContext.getBean("dataSource");
        JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
//        创建sql语句
        String sql = "insert into students (id,name,gender,age,class) values(?,?,?,?,?)";
        /*
        参数1:String sql 可以使用占位符,但是只能用于替代值,不能用于替代关键字和容器名
        参数2:Object。。。parase 传入占位符的值,并且按照从左到右的形式传递
        返回值 int 影响函数
         */
        int rows = jdbcTemplate.update(sql, 9,"黄小狗", "男", 18, "三年级一班");
        System.out.println("rows="+rows);
//        查询单条数据
         sql = "select * from students where id =?";
         /*
         参数1:可以使用占位符
         参数2:RowMapper 列名和属性名的映射器接口
         参数3:Object 。。。parase 可以传参数,替代占位符的值
          */
        Student student1 = jdbcTemplate.queryForObject(sql, new RowMapper<Student>() {
            public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
//                rs 结果集
//                rowNum 行数
//                rs结果集种获取列的值,赋值给实体类对象即可
                Student student = new Student();
                student.setId(rs.getInt("id"));
                student.setName(rs.getString("name"));
                student.setAge(rs.getInt("age"));
                student.setGender(rs.getString("gender"));
                student.setClasses(rs.getString("class"));
                return student;
            }
        }, 1);
        System.out.println("student1="+student1);
//        查询所有学生数据
//        TODO:BeanPropertyRowMapper帮助我们自动映射列和属性值!要求列名和属性名不一致! 不一致起别名
        String sql = "select id , name , gender , age ,class as classes from students";
        List<Student> studentList =jdbcTemplate.query(sql,new BeanPropertyRowMapper<Student>(Student.class));
        System.out.println("StudentList = " +studentList);
    }
}

image.gif

image.gif编辑


六、三层架构实现案例

6.1.持久层(dao层)

dao层对应的接口

package com.alphamilk.dao;
import com.alphamilk.pojo.Student;
import java.util.List;
public interface studentDao {
//    查询所有学生信息
    List<Student> querryAllStudent();
}

image.gif

dao层对应的实现类

package com.alphamilk.dao;
import com.alphamilk.pojo.Student;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class Impl implements studentDao{
    private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    @Override
    public List<Student> querryAllStudent() {
       String sql = "select id , name , gender , age ,class as classes from students";
       List<Student> students = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Student>(Student.class));
        System.out.println("dao层输出"+students);
        return students;
    }
}

image.gif

6.2业务层

service对应的业务接口

package com.alphamilk.service;
import com.alphamilk.pojo.Student;
import java.util.List;
public interface StudentService {
//    业务实现查询所有的学生信息
    List<Student> findAll();
}

image.gif

service业务层对应的实现方法

package com.alphamilk.pojo.service.Imp;
import com.alphamilk.pojo.pojo.Student;
import com.alphamilk.pojo.dao.StudentDao;
import com.alphamilk.pojo.service.StudentService;
import java.util.List;
//实现类
public class StudentServiceImpl  implements StudentService {
    private StudentDao studentDao;
    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
    }
    /**
     * 查询全部学员业务
     * @return
     */
    @Override
    public List<Student> findAll() {
        List<Student> studentList =  studentDao.queryAll();
        return studentList;
    }
}

image.gif

6.3控制层

package com.alphamilk.pojo.Controller;
import com.alphamilk.pojo.pojo.Student;
import com.alphamilk.pojo.service.StudentService;
import java.util.List;
public class StudentController {
    private StudentService studentService;
    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }
    public void  findAll(){
       List<Student> studentList =  studentService.findAll();
        System.out.println("studentList = " + studentList);
    }
}

image.gif

对应所有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"
       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:property-placeholder location="jdbc.properties"/>
    <!--druid-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${alphamilk.driver}"/>
        <property name="url" value="${alphamilk.url}"/>
        <property name="username" value="${alphamilk.username}"/>
        <property name="password" value="${alphamilk.password}"/>
    </bean>
<!--JDBCTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
<!--    dao层配置-->
    <bean id="studentDao" class="com.alphamilk.pojo.dao.Imp.StudentDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
<!--    service层配置-->
    <bean id="studentService" class="com.alphamilk.pojo.service.Imp.StudentServiceImpl">
        <property name="studentDao" ref="studentDao"/>
    </bean>
<!--    controller层配置-->
    <bean id="studentController" class="com.alphamilk.pojo.Controller.StudentController">
        <property name="studentService" ref="studentService"/>
    </bean>
</beans>

image.gif

最后的测试

package com.alphamilk;
import com.alphamilk.pojo.Controller.StudentController;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class newTest {
    @Test
    public void test(){
//        创建Ioc容器
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("SpringProject02.xml");
//        获取组件内容
        StudentController studentController = (StudentController) classPathXmlApplicationContext.getBean("studentController");
//        调用组件方法
        studentController.findAll();
//        关闭容器
        classPathXmlApplicationContext.close();
    }
}

image.gif

image.gif编辑


基于XML三层架构总结:

注入的属性必须添加 setter 方法、代码结构乱!

配置文件和 Java 代码分离、编写不是很方便!

XML配置文件解析效率低

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
打赏
0
0
0
0
32
分享
相关文章
数据中台架构解析:湖仓一体的实战设计
在数据量激增的数字化时代,企业面临数据分散、使用效率低等问题。数据中台作为统一管理与应用数据的核心平台,结合湖仓一体架构,打通数据壁垒,实现高效流转与分析。本文详解湖仓一体的设计与落地实践,助力企业构建统一、灵活的数据底座,驱动业务决策与创新。
RocketMQ实战—3.基于RocketMQ升级订单系统架构
本文主要介绍了基于MQ实现订单系统核心流程的异步化改造、基于MQ实现订单系统和第三方系统的解耦、基于MQ实现将订单数据同步给大数据团队、秒杀系统的技术难点以及秒杀商详页的架构设计和基于MQ实现秒杀系统的异步化架构。
340 64
RocketMQ实战—3.基于RocketMQ升级订单系统架构
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
企业级LLMOps落地指南:蜂巢架构×可视化编排实战
本文将基础的单应用扩展成多应用,并实现工作流组件,包括:多应用模块设计、工作流模块设计、LangGraph实现图应用、前端Vue-Flow组件使用、工作流转LLM工具设计思路、关联工作流登技巧。
38 3
企业级LLMOps落地指南:蜂巢架构×可视化编排实战
从理论到落地:MCP 实战解锁 AI 应用架构新范式
本文旨在从 MCP 的技术原理、降低 MCP Server 构建复杂度、提升 Server 运行稳定性等方面出发,分享我们的一些实践心得。
1752 102
一文带你从入门到实战全面掌握RocketMQ核心概念、架构部署、实践应用和高级特性
本文详细介绍了分布式消息中间件RocketMQ的核心概念、部署方式及使用方法。RocketMQ由阿里研发并开源,具有高性能、高可靠性和分布式特性,广泛应用于金融、互联网等领域。文章从环境搭建到消息类型的实战(普通消息、延迟消息、顺序消息和事务消息)进行了全面解析,并对比了三种消费者类型(PushConsumer、SimpleConsumer和PullConsumer)的特点与适用场景。最后总结了使用RocketMQ时的关键注意事项,如Topic和Tag的设计、监控告警的重要性以及性能与可靠性的平衡。通过学习本文,读者可掌握RocketMQ的使用精髓并灵活应用于实际项目中。
619 7
 一文带你从入门到实战全面掌握RocketMQ核心概念、架构部署、实践应用和高级特性
微服务架构下的电商API接口设计:策略、方法与实战案例
本文探讨了微服务架构下的电商API接口设计,旨在打造高效、灵活与可扩展的电商系统。通过服务拆分(如商品、订单、支付等模块)和标准化设计(RESTful或GraphQL风格),确保接口一致性与易用性。同时,采用缓存策略、负载均衡及限流技术优化性能,并借助Prometheus等工具实现监控与日志管理。微服务架构的优势在于支持敏捷开发、高并发处理和独立部署,满足电商业务快速迭代需求。未来,电商API设计将向智能化与安全化方向发展。
Google揭秘Agent架构三大核心:工具、模型与编排层实战指南
本文为Google发布的Agent白皮书全文翻译。本文揭示了智能体如何突破传统AI边界,通过模型、工具与编排层的三位一体架构,实现自主推理与现实交互。它不仅详解了ReAct、思维树等认知框架的运作逻辑,更通过航班预订、旅行规划等案例,展示了智能体如何调用Extensions、Functions和Data Stores,将抽象指令转化为真实世界操作。文中提出的“智能体链式组合”概念,预示了未来多智能体协作解决复杂问题的革命性潜力——这不仅是技术升级,更是AI赋能产业的范式颠覆。
638 1
OSS与NAS混合云存储架构:非结构化数据统一管理实战
AI训练集管理面临数据规模爆炸与访问模式多样的挑战。传统单一存储方案存在成本高、访问慢等问题。创新混合架构融合OSS与NAS,实现热冷数据自动分层,降低存储成本62%,提升训练速度3.8倍。通过统一接口、智能调度与自动迁移,兼顾高性能与低成本,助力AI训练高效稳定运行。
鸿蒙5开发宝藏案例分享---应用架构实战技巧
本文深入探讨鸿蒙应用架构设计与线程通信实战技巧,涵盖分层架构(产品定制层、基础特性层、公共能力层)的实际应用,通过代码示例讲解如何降低耦合、实现多端复用。同时解析子线程安全更新UI的实现方式,利用 `TaskDispatcher` 和 `Emitter` 进行线程间通信。此外,还分享模块化设计中 HAP、HAR、HSP 的选择与动态加载技巧,以及官方文档未明确提及的开发经验。帮助开发者将理论转化为实践,提升应用性能与可维护性。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问