当前位置: 首页 > article >正文

【期末复习】JavaEE(下)

1. MVC开发模式

1.1. 运行流程

1.2. SpringMVC 核心组件

1.3. 注解解释

2. ORM与MyBatis

2.1. ORM—对象关系映射

2.2. MyBatis

2.2.1. 创建步骤

会话是单例的,不能跨方法。(单例的原因主要是从数据安全角度出发)

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.Reader;
import java.util.List;

public class MyBatisExample {
    public static void main(String[] args) {
        SqlSessionFactory sqlSessionFactory = null;
        try (Reader reader = Resources.getResourceAsReader("mybatis-config.xml")) {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try (SqlSession session = sqlSessionFactory.openSession()) {
            // 获取 Mapper 接口的代理对象
            UserMapper userMapper = session.getMapper(UserMapper.class);

            // 使用 Mapper 接口的方法执行 SQL 操作1
            User user = userMapper.selectUserById(1);
            System.out.println(user);

            User newUser = new User();
            newUser.setName("John");
            newUser.setAge(30);
            // 使用 Mapper 接口的方法执行 SQL 操作2
            userMapper.insertUser(newUser);
            session.commit(); // 提交事务

            // 使用 Mapper 接口的方法执行 SQL 操作3
            List<User> users = userMapper.selectAllUsers();
            for (User u : users) {
                System.out.println(u);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2.2.2. mybatis-config.xml 配置

UserDao 是接口,在 namespace 必须是完整的路径。

2.2.3. sql 注入

2.2.4. 动态 SQL

if 和 where 是最重要的。

2.2.4.1. if

2.2.4.2. where

where 可以自动选择去掉多余的 and

2.2.4.3. set

set 可以自动去掉多余的 ,

2.2.4.4. foreach 语句

collection 是集合的变量名

2.2.4.5. trim 标签

2.2.4.6. choose、when、otherwise

2.2.5. Mybatis 的结果类型(使用 resultMap 和 resultType)

2.2.5.1. resultMap 的详细使用

在 MyBatis 中,resultMap 是一个非常重要的标签,它主要用于复杂的结果映射,特别是当数据库表的列名和 Java 对象的属性名不一致,或者需要映射关联关系(如一对一、一对多等)时。以下是 resultMap 的详细使用方法:

一、基本使用步骤

  1. 定义 resultMap
    在 Mapper XML 文件中,首先定义一个 resultMap,指定 id(用于在 SQL 语句中引用该结果映射)和 type(映射结果的 Java 类型)。
<resultMap id="userResultMap" type="com.example.User">
    <id property="id" column="user_id"/>
    <result property="userName" column="user_name"/>
    <result property="age" column="user_age"/>
</resultMap>

在上述 resultMap 中:

  • id="userResultMap":是结果映射的唯一标识符,后续会在 select 语句中使用。
  • type="com.example.User":表示映射的 Java 类型是 com.example.User 类。
  • <id> 标签:用于映射主键,property 是 Java 对象的属性名,column 是数据库表的列名。
  • <result> 标签:用于映射非主键的普通列,property 是 Java 对象的属性名,column 是数据库表的列名。

  1. select 语句中使用 resultMap
    resultMap 应用于 select 语句中,而不是 resultType
<select id="selectUserById" resultMap="userResultMap">
    select user_id, user_name, user_age from users where user_id = #{id}
</select>

二、处理复杂对象映射

当处理对象之间的关联关系时,resultMap 变得更加重要。

2.2.5.1.1. 一对一关联映射

假设 User 类中有一个 Address 对象作为属性,并且 Address 存储在另一个表中,需要进行一对一关联映射。

  1. 首先,在 User 类中添加 Address 属性:
public class User {
    private int id;
    private String userName;
    private int age;
    private Address address;
    // getters and setters
}
  1. 然后,在 Mapper XML 文件中定义 resultMap 包含 association 元素:
<resultMap id="userWithAddressResultMap" type="com.example.User">
    <id property="id" column="user_id"/>
    <result property="userName" column="user_name"/>
    <result property="age" column="user_age"/>
    <association property="address" javaType="com.example.Address">
        <id property="id" column="address_id"/>
        <result property="street" column="address_street"/>
        <result property="city" column="address_city"/>
        <result property="zipcode" column="address_zipcode"/>
    </association>

</resultMap>
  1. select 语句中使用该 resultMap
<select id="selectUserWithAddressById" resultMap="userWithAddressResultMap">
    select u.user_id, u.user_name, u.user_age, 
           a.address_id, a.address_street, a.address_city, a.address_zipcode
    from users u
    join addresses a on u.user_id = a.user_id
    where u.user_id = #{id}
</select>

2.2.5.1.2. 一对多关联映射

假设 User 类中有一个 List<Order> 表示用户的多个订单,需要进行一对多关联映射。

  1. User 类中添加 List<Order> 属性:
public class User {
    private int id;
    private String userName;
    private int age;
    private List<Order> orders;
    // getters and setters
}
  1. 在 Mapper XML 文件中定义 resultMap 包含 collection 元素:
<resultMap id="userWithOrdersResultMap" type="com.example.User">
    <id property="id" column="user_id"/>
    <result property="userName" column="user_name"/>
    <result property="age" column="user_age"/>
    <collection property="orders" ofType="com.example.Order">
        <id property="id" column="order_id"/>
        <result property="orderName" column="order_name"/>
        <result property="amount" column="order_amount"/>
    </collection>

</resultMap>
  1. select 语句中使用该 resultMap
<select id="selectUserWithOrdersById" resultMap="userWithOrdersResultMap">
    select u.user_id, u.user_name, u.user_age, 
           o.order_id, o.order_name, o.order_amount
    from users u
    join orders o on u.user_id = o.user_id
    where u.user_id = #{id}
</select>

三、继承和扩展 resultMap

可以使用 extends 属性扩展已有的 resultMap,以避免重复定义。

<resultMap id="extendedUserResultMap" type="com.example.User" extends="userResultMap">
    <result property="email" column="user_email"/>
</resultMap>

四、使用 resultMap 的好处

  • 灵活映射:可以处理各种复杂的映射情况,包括列名和属性名不匹配、关联对象映射等。
  • 代码清晰:将结果映射的逻辑集中在 XML 文件中,使得 SQL 语句和结果映射逻辑清晰,易于维护。

五、注意事项

  • 列名和属性名:确保 resultMap 中的 column 与 SQL 语句中的列名一致,property 与 Java 对象的属性名一致。
  • 关联关系:使用 association 处理一对一关系,使用 collection 处理一对多关系,确保关联的对象和集合类型正确。

使用 resultMap 可以让 MyBatis 更好地处理复杂的结果映射,使数据库结果能够准确地映射到 Java 对象及其关联对象或集合,提供了强大而灵活的结果映射机制,特别是在处理对象之间的复杂关系时,它是 MyBatis 实现对象关系映射的关键元素。

2.2.5.2. typeAliases

2.2.6. 查询的 resultType

2.2.7. sql 抽取

3. Spring MVC

SpringMVC 中有默认的编码拦截器,所以不用管乱码的问题。

3.1. Spring MVC工作原理

3.2. 控制器编写

3.3. 拦截器

3.3.1. 拦截器配置

3.3.1.1. 编写拦截器

3.3.1.2. 配置拦截器
3.3.1.2.1. 基于代码

3.3.1.2.2. 基于 xml

3.3.2. 单个拦截器

3.3.3. 多个拦截器

4. Spring

4.1. Spring 体系结构

4.2. 核心容器

4.3. web

4.4. 数据访问

4.5. 其他模块

4.6. Spring 特征

4.7. IOC

4.8. DI

4.9. Bean配置(重点)

使用ApplicationContext 对象获取 bean:

bean 的配置文件:

4.9.1. 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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--    1.使用property标签-->
    <bean id="book" class="com.bean.Book">
        <!--        如果类中有显示构造函数,则必须加上这两行-->
        <constructor-arg index="0" value=""/>
        <constructor-arg index="1" value=""/>
        <property name="name" value="书名0"></property>
        <property name="price" value="2022.12"></property>
    </bean>

    <!--    2.使用 构造器+index 标签-->
    <bean id="book" class="com.bean.Book">
        <constructor-arg index="0" value="书名1"/>
        <constructor-arg index="1" value="2024.12"/>
    </bean>

    <!--    3.使用 构造器+name 标签-->
    <bean id="book" class="com.bean.Book">
        <constructor-arg name="name" value="书名2"></constructor-arg>
        <constructor-arg name="price" value="2023.12"></constructor-arg>
    </bean>

    <!--    4.使用 p标签-->
    <bean id="book" class="com.bean.Book" p:name="书名3" p:price="2025.12">
        <!--        如果类中有显示构造函数,则必须加上这两行-->
        <constructor-arg index="0" value=""/>
        <constructor-arg index="1" value=""/>
    </bean>
</beans>

4.9.2. 注解配置(重点)

4.9.3. ApplicationContext 的构造方式

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("D:\\code\\4Spring\\ssm_st" +

ClassPathXmlApplicationContext:使用文件名

FileSystemXmlApplicationContext:使用绝对路径

4.9.4. Bean的作用域

4.9.4.1. 多例模式
<bean id="book" class="com.bean.Book" p:name="书名3" p:price="2025.12" scope="prototype">
        <!--        如果类中有显示构造函数,则必须加上这两行-->
        <constructor-arg index="0" value=""/>
        <constructor-arg index="1" value=""/>
    </bean>
4.9.4.2. 单例模式
<bean id="book" class="com.bean.Book" p:name="书名3" p:price="2025.12" scope="singleton">
        <!--        如果类中有显示构造函数,则必须加上这两行-->
        <constructor-arg index="0" value=""/>
        <constructor-arg index="1" value=""/>
    </bean>

4.9.5. bean 的 xml 装配

4.9.5.1. 手动-ref 标签

<!--    bean的装配-->
    <!--    1.手动装配-->
    <bean id="cat" class="com.bean.Cat"></bean>
    <bean id="dog" class="com.bean.Dog"></bean>
    <bean id="animal" class="com.bean.Animal">
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>
4.9.5.2. 自动-autowire
  1. 通过名字
    <!--    2.自动装配-->
    <bean id="cat" class="com.bean.Cat"></bean>
    <bean id="dog" class="com.bean.Dog"></bean>
    <bean id="animal" class="com.bean.Animal" autowire="byName"></bean>
  1. 通过类型
    <!--    2.自动装配-->
    <bean id="cat" class="com.bean.Cat"></bean>
    <bean id="dog" class="com.bean.Dog"></bean>
    <bean id="animal" class="com.bean.Animal" autowire="byType"></bean>
4.9.5.2.1. autowire 属性取值

4.9.5.3. 总结
  1. 手动需要使用 ref 标签进行引用
  2. 自动需要通过 名字 或者 类型 ,间接使用 setter 方法进行装配

4.10. bean 的注解装配

4.10.1. Autowired

  1. 匹配流程:
    1. 根据类型
    2. 类型相同,根据名称
  1. 不用 setter 方法

4.10.2. Qualifier

  1. 按照名字查
  2. 不能单独使用

4.10.3. Resource

  1. 匹配流程:
    1. 根据名称
    2. 名称相同,根据类型

4.10.4. 注解包扫描装配

4.11. AOP

4.11.1. 相关概念

4.11.2. 基于 xml

        <!--    注册bean-->
        <bean id="userService" class="com.bean.service.UserService"></bean>
        <!--    注册切面bean-->
        <bean id="myPoint" class="com.pointCut.MyPointCut"></bean>
        <!--    配置切面-->
        <aop:config>
            <aop:aspect ref="myPoint">
                <!--        配置切点-->
                <aop:pointcut id="point" expression="execution(String com.bean.service.UserService.show())"/>
                <!--        配置通知-->
                <aop:before method="before" pointcut-ref="point"></aop:before>
                <aop:after method="after" pointcut-ref="point"></aop:after>
            </aop:aspect>
        </aop:config>

切点和通知不需要注册 bean。

4.11.3. 基于注解

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.Arrays;


// 配置类,启用 AOP 支持
@Configuration
@EnableAspectJAutoProxy
@SpringBootApplication
public class AopExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(AopExampleApplication.class, args);
    }


    // 定义一个简单的业务服务
    @Service
    public static class UserService {

        public String getUserById(int id) {
            System.out.println("Executing getUserById with id: " + id);
            return "User " + id;
        }

        public void updateUser(int id, String name) {
            System.out.println("Updating user with id: " + id + " and name: " + name);
        }
    }


    // 定义自定义注解
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Loggable {
    }


    // 切面类,包含各种通知
    @Aspect
    @Component
    public static class LoggingAspect {

        // 定义切点,拦截 UserService 类的所有方法
        @Pointcut("execution(* com.example.AopExampleApplication.UserService.*(..))")
        public void userServicePointcut() {
        }


        // 前置通知
        @Before("userServicePointcut()")
        public void beforeAdvice(JoinPoint joinPoint) {
            System.out.println("Before method execution: " + joinPoint.getSignature().getName());
            System.out.println("Arguments: " + Arrays.toString(joinPoint.getArgs()));
        }


        // 后置通知
        @After("userServicePointcut()")
        public void afterAdvice(JoinPoint joinPoint) {
            System.out.println("After method execution: " + joinPoint.getSignature().getName());
        }


        // 环绕通知
        @Around("userServicePointcut()")
        public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("Before around advice: " + joinPoint.getSignature().getName());
            Object result = joinPoint.proceed();
            System.out.println("After around advice: " + joinPoint.getSignature().getName());
            return result;
        }


        // 返回通知,获取方法返回值
        @AfterReturning(pointcut = "userServicePointcut()", returning = "result")
        public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
            System.out.println("Method returned: " + result);
        }


        // 异常通知,处理方法抛出的异常
        @AfterThrowing(pointcut = "userServicePointcut()", throwing = "e")
        public void afterThrowingAdvice(JoinPoint joinPoint, Exception e) {
            System.out.println("Method threw exception: " + e.getMessage());
        }


        // 自定义注解作为切点
        @Pointcut("@annotation(Loggable)")
        public void loggablePointcut() {
        }


        @Before("loggablePointcut()")
        public void loggableBeforeAdvice(JoinPoint joinPoint) {
            System.out.println("Before annotated method execution: " + joinPoint.getSignature().getName());
        }
    }
}

还需要在 xml 开启配置:

  <!--    基于注解配置切面的xml-->
    <context:component-scan base-package="com.*"></context:component-scan>
    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

4.11.4. 环绕通知

@Around("execution(String com.bean.service.UserService.show())")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("====around->执行方法之前的处理====");
        Object res = pjp.proceed();
        System.out.println("====around->执行方法之后的处理====");
        System.out.println("方法执行的返回结果:"+res);
    }

4.11.5. 返回结果后的通知

@AfterReturning("execution(String com.bean.service.UserService.show())")
    public void afterReturning() {
        System.out.println("====afterReturning->执行方法之后的处理====");
    }

4.11.6. 抛异常后的通知

@AfterThrowing("execution(String com.bean.service.UserService.show())")
    public void afterThrowing() {
        System.out.println("====afterThrowing->执行异常之后的处理====");
    }

4.11.7. 切点表达式

4.12. 事务管理

4.12.1. 编程式事务

4.12.2. 声明式事务

4.12.3. 例子

4.12.4. 注解实现

4.12.5. 传播方式

4.12.6. 隔离级别

5. SSM整合


http://www.kler.cn/a/456487.html

相关文章:

  • C语言 练习
  • Kafka消息不丢失与重复消费问题解决方案总结
  • Presence:Colyseus用于管理实时分布式数据的工具
  • python 渗透开发工具之SQLMapApi Server不同IP服务启动方式处理 解决方案SqlMapApiServer外网不能访问的情况
  • 哪些框架、软件、中间件使用了netty? 哪些中间件、软件底层使用了epoll?
  • Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码 【AI辅助开发系列】
  • Arduino中借助LU-ASR01实现语音识别
  • Go语言基础语法
  • RNA-Seq 数据集、比对和标准化
  • 基于GA遗传优化TCN时间卷积神经网络时间序列预测算法matlab仿真
  • 【AIGC-ChatGPT副业提示词指令 - 动图】魔法咖啡馆:一个融合创意与治愈的互动体验设计
  • 总结一下本次使用docker部署遇到的问题
  • 【已解决】图片png转ico格式
  • 伏羲0.13(文生图)
  • 三极管、运放和稳压二极管恒流电路设计原理分析
  • Vue中接入萤石等直播视频(更新中ing)
  • 如何在Express.js中定义多个HTTP方法?
  • <packaging>jar</packaging>和<packaging>pom</packaging>的区别
  • nginx Rewrite 相关功能
  • fopen的概念和使用方法
  • 正则表达式 - 使用总结
  • 多个微服务 Mybatis 过程中出现了Invalid bound statement (not found)的特殊问题
  • 系统分析师案例分析100问
  • 【Leetcode 热题 100】78. 子集
  • 提升生产力工具
  • ShaderJoy ——一种可交互的翻页效果【GLSL】