https://img2024.cnblogs.com/blog/3305226/202503/3305226-20250331155133325-143341361.jpg

Spring框架学习(二)

Spring框架学习(二)

Spring整合Mybatis

学习视频:【黑马程序员SSM框架教程_Spring+SpringMVC+Maven高级+SpringBoot+MyBatisPlus企业实用开发技术】https://www.bilibili.com/video/BV1Fi4y1S7ix?p=109&vd_source=2884b80d333f3bfc8048b360e6195550

Mybatis学习

1.准备数据库以及依赖

准备一个数据库,创建一个表

image-20250607181014492

create table tb_user(
    id int primary key auto_increment,
    username varchar(20),
    password varchar(20),
    gender char(1),
    addr varchar(30)
);


INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');

依赖:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.11</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
</dependency>

2.编写MyBatis核心配置文件

User javabean

public class User {

    private Integer id;
    private String username;
    private String password;
    private String gender;
    private String addr;
......    

配置UserMapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--
    namespace:名称空间,区分具体的sql操作
-->
<mapper namespace="test">
    <select id="selectAll" resultType="com.kudo.pojo.User">
        select * from tb_user;
    </select>
</mapper>

Mybatis核心配置文件。 加载数据库以及mapper

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///pikachu?useSSL=false"/>
                <property name="username" value="kudo"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

3.编写测试类

public class Test_Demo {
    public static void main(String[] args) throws Exception {
        //加载配置文件创建SqlSessionFactory
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取sqlSession,执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> users = sqlSession.selectList("test.selectAll");

        System.out.println(users);
        sqlSession.close();
    }
}

Mapper代理开发

解决硬编码问题

1.定义与 SQL 映射文件同名的 Mapper 接口,并且将 Mapper 接口和 SQL 映射文件放置在同一目录下

这样编译后是在同一目录下的,**记得也要更改核心配置文件中Mapper.xml的路径

image-20250607190247326

2.设置 SQL 映射文件的 namespace 属性为 Mapper 接口全限定名

UserMapper.xml

image-20250607191635575

3.在 Mapper 接口中定义方法,方法名就是 SQL 映射文件中 sql 语句的 id,并保持参数类型和返回值类型一致

public interface UserMapper {

    List<User> selectAll();
}

4.使用Mapper代理

public class Test_Demo {
    public static void main(String[] args) throws Exception {
        //加载配置文件创建sqlS
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取sqlSession,执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //List<User> users = sqlSession.selectList("test.selectAll");
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.selectAll();
        System.out.println(users);
        sqlSession.close();
    }
}

Mapper核心配置文件

image-20250607193103802

在mapper配置中,可以使用包扫描的方式,而不是一个个配置

<mappers>
<!--        <mapper resource="com/kudo/mapper/UserMapper.xml"/>-->
    <package name="com.kudo.mapper"/>
</mappers>

properties标签,加载外部配置文件

<properties resource="jdbc.properties"/>

environment标签 配置多个数据库环境,开发与测试环境分开

而typeAliases则达到起别名的效果,com.kudo.pojo.User 可以写为user

如mapper中的返回类型

<mapper namespace="com.kudo.mapper.UserMapper">
    <select id="selectAll" resultType="user">-- com.kudo.pojo.User
        select * from tb_user;
    </select>
</mapper>
<typeAliases>
        <package name="com.kudo.pojo"/>
</typeAliases> 
<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///pikachu?useSSL=false"/>
                <property name="username" value="kudo"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///pikachu?useSSL=false"/>
                <property name="username" value="kudo"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
</environments>

Spring整合Mybatis

注解代替Mapper接口以及Mapper配置文件

新建UserDao接口

package com.kudo.dao;

import com.kudo.pojo.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserDao {

    @Select("select * from tb_user")
    List<User> selectAll();
}

mybatis-config.xml中,更改配置即可

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="jdbc.properties"/>

    <typeAliases>
        <package name="com.kudo.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--        <mapper resource="com/kudo/mapper/UserMapper.xml"/>-->
        <package name="com.kudo.dao"/>
    </mappers>
</configuration>

用注解代替,即将sqlSessionFactory这个核心对象交给ioc管理,此xml中除了mappers标签,其他标签都为sqlSessionFactory服务,所以第三方管理创建这个bean即可,然后MapperScannerConfigurer用于包的扫描

public class MybatisConfig {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {
         SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
         ssfb.setTypeAliasesPackage("com.kudo.dao");
         ssfb.setDataSource(dataSource);
         return ssfb;
    }
    
    @Bean
    MapperScannerConfigurer mapperScannerConfigurer(SqlSessionFactoryBean sqlSessionFactoryBean) {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.kudo.dao");
        return mapperScannerConfigurer;
    }
}

操作mybatis

public class Test_Demo {
    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) ctx.getBean(UserServiceImpl.class);
        System.out.println(userService.selectAll());
    }
}
@Service("UserService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    public List<User> selectAll(){
        return userDao.selectAll();
    };

}

Spring整合jUnit

依赖:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>
package service;

import com.kudo.config.SpringConfig;
import com.kudo.service.UserService;
import com.kudo.service.impl.UserServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
    @Autowired
    private UserService userService;

    @Test
    public void testSelectAll(){
        System.out.println(userService.selectAll());
    }
}

AOP

AOP:面向切面编程,在不惊动原始设计的基础上为其进行功能增加

image-20250608205220406

连接点(JoinPoint)

程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等

  • 在 SpringAOP 中,理解为方法的执行

切入点(Pointcut)

匹配连接点的式子

  • 在 SpringAOP 中,一个切入点可以只描述一个具体方法,也可以匹配多个方法
    • 一个具体方法:com.itheima.dao 包下的 BookDao 接口中的无形参无返回值的 save 方法
    • 匹配多个方法:所有的 save 方法,所有的 get 开头的方法,所有以 Dao 结尾的接口中的任意方法,所有带有一个参数的方法

通知(Advice)

在切入点处执行的操作,也就是共性功能

  • 在 SpringAOP 中,功能最终以方法的形式呈现

通知类

定义通知的类

切面(Aspect)

描述通知与切入点的对应关系

依赖:

spring-context包括了aop依赖

<dependency>
            <groupId>org.aspectj</groupId> 
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
</dependency>
@Component//加入IoC容器
@Aspect//定义为一个切面类
public class MyAdvice {
    //定义切入点
    @Pointcut("execution(void com.kudo.service.UserService.update())")
    private void pc(){}

    @Before("pc()")//绑定切入点和通知的关系并指定位置
    public void method(){   //制作通知
        System.out.println(System.currentTimeMillis());
    }
}
@ComponentScan("com.kudo")
@Configuration
@EnableAspectJAutoProxy//告诉spring有用注解开发的aop启动@Aspect
public class SpringConfig {

}

AOP切入点表达式

image-20250608214008442

案例:如使用aop处理用户发送过来的密码,需要做去空格处理

dao层

@Repository
public class ResourcesDaoImpl implements ResourcesDao {

    @Override
    public boolean check(String url, String password) {
        return password.equals("root");//模拟数据层的校验
    }
}

service层

@Service
public class ResourcesServiceImpl implements ResourcesService {
    @Autowired
    private ResourcesDao resourcesDao;
    @Override
    public boolean yesorno(String url,String password) {
        return resourcesDao.check(url,password);
    }
}

测试类 未用aop处理password

public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        ResourcesService resourcesService = ctx.getBean(ResourcesService.class);
        System.out.println(resourcesService.yesorno("http://www.baidu.com","root "));
    }
}

aop

@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(boolean com.kudo.service.ResourcesService.yesorno(*,*))")
    public void pt(){}

    @Around("MyAdvice.pt()")
    public Object method(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        for (int i = 0; i < args.length; i++) {
            if (args[i].getClass() == String.class) {
                args[i]=args[i].toString().trim();
            }
        }
        return pjp.proceed(args);
    }
}
posted @ 2025-06-12 19:15  kudo4869  阅读(9)  评论(0)    收藏  举报