一、需求分析
搭建一个三层架构案例,模拟查询全部学生(学生表)信息,持久层使用JdbcTemplate和Druid技术,使用XML方式进行组件管理!
编辑
二、创建相关数据库
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, '高中二班');
创建完成后表格如下所示
编辑
三、导入相关依赖
<!-- 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>
四、实体类准备
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 + '\'' + '}'; } }
五、相关技术讲解(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 用于连接和创建连接池对象和数据库驱动等等 */ } }
将两个对象使用xml配置为组件
1.在项目配置下创建peoperties资源文件,将个人信息所有都放入进去,方便以后修改
alphamilk.url=jdbc:mysql://localhost:3306/studb alphamilk.driver=com.mysql.cj.jdbc.Driver alphamilk.username=mysql alphamilk.password=123456
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>
测试:
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); } }
编辑
六、三层架构实现案例
6.1.持久层(dao层)
dao层对应的接口
package com.alphamilk.dao; import com.alphamilk.pojo.Student; import java.util.List; public interface studentDao { // 查询所有学生信息 List<Student> querryAllStudent(); }
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; } }
6.2业务层
service对应的业务接口
package com.alphamilk.service; import com.alphamilk.pojo.Student; import java.util.List; public interface StudentService { // 业务实现查询所有的学生信息 List<Student> findAll(); }
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; } }
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); } }
对应所有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>
最后的测试
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(); } }
编辑
基于XML三层架构总结:
注入的属性必须添加 setter 方法、代码结构乱!
配置文件和 Java 代码分离、编写不是很方便!
XML配置文件解析效率低