三层架构理解(实现前后端分离)
1.浏览器进行访问
2.通过vue的异步请求,调用后端()通过@RequestMapping注解进行映射到controller,此时的页面未进行渲染
3后端
.c-s-d 以及d-s-c都是因为之间的方法调用(思考时,可以倒着思考,就是
提出请求时:controller调用Service 的方法,而Service 又调用Daode方法
请求返回: Dao访问数据传给Service ,Service处理完数据返回给controller)
4.数据处理完成后,由vue渲染,之后展现
顺序:
浏览器请求index.html → 服务器返回HTML → 浏览器解析Vue代码 →Vue mounted钩子触发axios请求 → 请求到达Spring Controller →Controller调用Service → Service调用Dao → Dao读取文件 →数据返回Service → Service返回Controller → Controller返回JSON →axios接收响应 → Vue更新数据 → 表格渲染完成
默认时index.html,没有只能显示调用需要访问的界面
bean重复解决方案
ioc重复(不同包下类名相同),重复:加入bean的对象名相同(因为加入bean的对象是根据类名的小驼峰创建的)
示例:
@Service(自定义对象别名) ,eg: 类UserServiceImpl上@Service("abc") ,对象名字就是abc// 语法2的应用场景:当包名不一样但是类名一样的时候就需要起别名
di重复(注入时重复):因为定义时市根据接口定义的,注入是根据接口来查询的(接口是可以有多个实现类的)
解决方案一:添加在实现类上 ;设定优先级/@Primary
//@Primary//解决依赖注入存在多个类型对象方案1:设置优先级,如果在容器里面查找IUserService解耦实现类对象优先使用这个进行依赖注入
解决方案二:添加在定义实现类对象的地方(private IUserService userService2;)
@Autowired + Qualifier("userServiceImpl2") 没有顺序要求 ;参数要求:与bean的名字保持一致(bean默认是类名变成小驼峰)
@Autowired先按类型(IUserService)查找 Bean。- 若找到多个同类型 Bean,再通过
@Qualifier指定的名称查找。
解决方案三:添加在定义实现类对象的地方(private IUserService userService2;)@Resource
语法:
1.@Resource(name = "userServiceImpl") 参数要求:与bean的名字保持一致(bean默认是类名变成小驼峰)
2.@Resource 无参数时,先按照定义的名字(不是bean,是定义的)进行查找,再按照类型(如果有多个,会抛出异常)
//解决依赖注入存在多个类型对象方案3:这个不是spring框架提供的注解,而是jakartaEE提供的注解,spring框架通过反射解析这个注解赋予DI的功能
总结:
获取bean的方式(重名要在启动类的同一个包下,bean相当于命名都是按照类名小驼峰命名的,与所在包无关,因此重名时要标注)
@Autowired 按类型(@Autowired + Qualifier("userServiceImpl2") 先名称,名称必须是bean);@Resource按名称(有参必须是bean,无参按定义)
问题:
@Component public class Class1 {} public class Class2 { // 普通类,无 @Component @Autowired private Class1 class1; class2不进行bean的管理, @Autowired会生效吗,原因是什么
@Autowired 的工作原理是通过 Spring 的 BeanFactory 查找匹配的 Bean。普通类不在容器中,无法触发这一查找过程。
@Autowired仅在 Spring 管理的 Bean 中生效。- 普通类的依赖注入需通过构造函数或Setter 方法手动完成。
- 建议将所有需要依赖注入的类注册为 Spring Bean,遵循 IoC(控制反转)原则。
- 因此,针对普通类,加入注入依赖的@Autowired也不会生效。
测试类:会自动找到启动类运行spring环境,前提是当前类必须在启动类所在包及其子包下
这个路径指的是逻辑上的
只要测试类在启动类包或子包下,无论层级多深都会被扫描
eg:
启动类: com.itheima包下
测试类:com.itheima包下,com.itheima的子包下均可以被扫描,但是在com.abc这种包下则不会被扫描
mabitas插件生成xml文件,根据下面的关键字生成不同的标签(没有下了含义的可以进行选择,有的则会默认生成对应的)
- 查询类关键词:
select、find、get、list→ 生成<select> - 修改类关键词:
update、modify→ 生成<update> - 插入类关键词:
insert、add→ 生成<insert> - 删除类关键词:
delete、remove→ 生成<delete>
根据返回值类型推断
- 返回实体类 / 集合 → 生成
<select>(需指定resultType或resultMap) - 返回
int(影响行数) → 生成<update>/<insert>/<delete> - 返回
void→ 通常生成<update>/<insert>/<delete>
MyBatis 的#{}与${}的对应关系
#{}:底层使用预编译语句,将参数替换为占位符?,因此只能用于参数值(参数值就是字面意思)。${}:直接进行字符串替换,因此可以用于生成标识符,但存在 SQL 注入风险。
场景 |
是否可用占位符 |
MyBatis 方式 |
示例 |
表名、列名 |
❌ 否 |
|
|
WHERE 条件值 |
✅ 是 |
|
|
ORDER BY 字段 |
❌ 否 |
|
|
标识符(Identifiers)
- 定义:SQL 中用于命名对象的名称,如:
- 表名:
users、orders - 列名:
id、username、create_time - 别名:
SELECT u.name FROM users AS u中的u
总结:${} 可以动态传入,但是容易被sql注入,因为其是进行字符替换
#{},只能传参数值,,本质是占位符?替换,无法替换标识符