1、SpringBoot的包结构
2、各个包之间的关系
Controller : 主要负责具体业务模块流程的控制,会调用Service层的接口来控制业务逻辑
Dao :不管是什么框架,我们很多时候都会与数据库进行交互。如果遇到一个场景我们都要去写SQL语句,那么我们的代码就会很冗余。所以,我们就想到了把数据库封装一下,让我们的数据库的交道看起来像和一个对象打交道,这个对象通常就是DAO。当我们操作这个对象的时候,这个对象会自动产生SQL语句来和数据库进行交互,我们就只需要使用DAO就行了。 通常我们在DAO层里面写接口,里面有与数据打交道的方法。
DaoImpl :里边写的时对Dao包中的接口的具体实现,包含一些数据库操作语句。
entity : 实体类,里边实体类信息,也是和数据库中数据的对应
mapper : 实体类映射,RowMapper的接口就是用来把数据库中的列字段和Java Bean中的属性对应上,这样我们就可以进行赋值操作了,也想JDBC中的bean.setName(rs.getString(“Name”));Spring将这段代码抽象出来写成了一个接口,即我们要在这里去实现的RowMapper。
Service : 服务是一个相对独立的功能模块,主要负责业务逻辑应用设计。首先也要设计接口,然后再设计其实现该接口的类。这样我们就可以在应用中调用service接口进行业务处理。service层业务实现,具体调用到已经定义的DAO的接口,封装service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性 。
ServiceImpl : 对Service接口进行实现,调用Dao层的方法。
3、代码分享
NO.1--------Controller.java
package com.example.controller;
import com.example.entity.Student;
import com.example.service.studentService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* 调用service层,主函数在Application
*/
@Controller // 在Controller层必须要有的注解
@AllArgsConstructor // 作用在studentService 和 Student 两个类上的,是为了构建其构造方法,并且实例化这两个变量
public class studentController {
private final studentService studentservice;
private final Student student;
/**
* 查找全部
*/
@RequestMapping("listAll")
public void listAll() {
// 查找列表数据
List<Student> students = studentservice.SelectAll();
// 列出查找出的信息
System.out.println(students);
}
@RequestMapping("listBySex")
public List<Student> listBySex(boolean sex) {
List<Student> students1 = studentservice.SelectBySex(sex);
if (students1.toString().equals("张飞")) {
return null;
}
return students1;
}
}
NO.2--------xxxdao.java
package com.example.dao;
import com.example.entity.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @program: Spring-Prepare
* @author: 涛
* @create: 2021-12-28
**/
/**
* 持久层,接口层,和数据库互动,编程对数据库的操作的方法。
* @Mapper 可不写
*/
public interface studentDao {
List<Student> SelectAll();
List<Student> SelectBySex(Boolean sex);
String Insert();
}
NO.3--------xxxDaoImpl.java
package com.example.dao.Impl;
import com.example.dao.studentDao;
import com.example.entity.Student;
import com.example.mapper.StudentMapper;
import lombok.AllArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import java.util.List;
@AllArgsConstructor // 自动构建jdbcTemplate的构造方法
@Repository
/**
* @Repository 只能标注在 DAO 类:
* 这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为Spring的数据访问异常类型。
* Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。
**/
@Service // 自动注入到Spring容器中,不需要再次定义bean
public class studentImpl implements studentDao {
// 获取对象
private JdbcTemplate jdbcTemplate;
// 查询全部学生信息
@Override
public List<Student> SelectAll() {
String sql = "select * from student";
return jdbcTemplate.query(sql, new StudentMapper());
}
// 查询相同性别的学生的全部信息
@Override
public List<Student> SelectBySex(Boolean sex) {
String sql = "select * from student where sex <> true";
return jdbcTemplate.query(sql, new StudentMapper());
}
// 新增学生信息
@Override
public String Insert() {
return null;
}
}
NO.4--------xxxEntity.java
package com.example.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
/**
* 实体类信息
*/
@Repository(value = "/Student")
public class Student {
// 学生姓名 数据库设置成varchar类型
private String name;
// 学生年龄 数据库设置成int类型
private int age;
// 学生性别 0(男) 、 1(女) 数据库设置成 tinyint类型
private boolean sex;
// 学生身份证号 数据库设置成 int类型,但明显长度不够
private Integer IDCord;
// 学生生日 数据库设置成Date类型
private Date birthDay;
}
NO.5--------xxxMapper.java
package com.example.mapper;
import com.example.entity.Student;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 实体类映射
* RowMapper的接口就是用来把数据中的列字段和java Bean中的属性对应上,这样就可以赋值了。
* 也像JDBC中的bean.setName(rs.getString(“name”);Spring把这段代码抽象出来写成RowMapper.
*/
public class StudentMapper implements RowMapper<Student> {
@Override
public Student mapRow(ResultSet resultSet, int i) throws SQLException {
Student student = new Student();
student.setName(resultSet.getString("name"));
student.setAge(resultSet.getInt("age"));
student.setSex(resultSet.getBoolean("sex"));
student.setIDCord(resultSet.getInt("IDCord"));
student.setBirthDay(resultSet.getDate("BirthDay"));
return student;
}
}
NO.6--------xxxService.java
package com.example.service;
import com.example.entity.Student;
import java.util.List;
/**
* 服务层,对dao层的调用
*/
public interface studentService {
List<Student> SelectAll();
List<Student> SelectBySex(Boolean sex);
String Insert();
}
NO.7--------xxxServiceImpl.java
package com.example.service.serviceImpl;
import com.example.dao.studentDao;
import com.example.entity.Student;
import com.example.service.studentService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 对接口service中的方法的实现,同时也完成了调用Dao层中的方法的功能
* 前边要加上 @Service作为映射
*/
@Service // 加上该注解,将会将该类自动注入到spring容器中,不需要在applicationContext.xml中文件中再次定义bean了
@Repository // 作用于定义到的studentDao类
@AllArgsConstructor // 对注入dao层方法时创建构造方法,初始化变量“studentdao”
@Transactional // 需要AOP拦截及事务的处理,会影响到性能,只有对public才会起作用。放在实现接口的实现类上
public class studentServiceImpl implements studentService {
/*注入dao层的方法*/
private final studentDao studentdao;
@Override
public List<Student> SelectAll() {
return studentdao.SelectAll();
}
@Override
public List<Student> SelectBySex(Boolean sex) {
return studentdao.SelectBySex(sex);
}
@Override
public String Insert() {
return studentdao.Insert();
}
}
NO.8--------application.yml
spring:
# 注解链接数据库
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/*****?useUnicode=true&characterEncoding=UTF-8
username: ******
password: *******
dbcp2:
max-idle: 20
min-idle: 10
# 注解使tomcat端口号不冲突
server:
port: 8888
NO.9--------在来一个Test供大家参考 studentControllerTest .java
package com.example.test.controller;
import com.example.SpringbootApplication;
import com.example.entity.Student;
import com.example.service.studentService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
@RunWith(SpringRunner.class)
// 是一个运行器,在运行的时候需要指定运行器。而SpringRunner是SpringJUnit4ClassRunner.class的小子类,其作用和SpringJunit4ClassRunner.class一样
@SpringBootTest(classes = {SpringbootApplication.class})
// 指定启动类,也可以不写括号里的信息
public class studentControllerTest {
@Autowired
// 注入studentService已经被实现的接口,但是如果将该接口被final修饰,则需要初始化该接口。
private studentService studentservice;
@Test
public void SeeAll() {
try {
List<Student> students = studentservice.SelectAll();
System.out.println(students);
} catch (Exception e) {
System.out.println("查找全部时,得出结果失败,失败原因: " + e);
} finally {
System.out.println("*************查找全部,代码执行完毕***********\n");
}
}
@Test
public void SeeBySex() {
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
boolean sex = bufferedReader.markSupported();
List<Student> selectBySex = studentservice.SelectBySex(sex);
System.out.println(selectBySex);
} catch (Exception e) {
System.out.println("按性别查找全部时,得出结果错误,失败的原因是: " + e);
} finally {
System.out.println("*************按性别查找全部,代码执行完毕***********\n");
}
}
}
4、欢迎指教
如果有什么问题或需要指教的,请留言或者直接联系本人qq:2748508180。Thanks***