SSM+Maven高级+MybatisPlus万字笔记

SSM框架学习

前言:花了一周学习了SSM(Spring+SpringMVC+Mybatis)以及Maven高级部分加MybatisPlus并且做了这个笔记,自己看黑马视频做的总结,不得不说学习还得多做笔记,做完笔记后还得在回头回忆一遍,遇到没记住的部分可以回来翻阅,很方便。仅上传作纪念,之前看JavaWeb也有记笔记,到时候有时间再放上来,仅供参考,有做的不好的地方还请多多指教!

一:Spring Framework系统框架

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rYiLxYs7-1653122017069)(SSM笔记.assets/image-20220515095423696.png)]

二:Spring核心概念

1.IoC、Bean、DI
1.1:IoC&Bean
  • IoC(Inversion of Control)控制反转
    • 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权转移到外部,此思想称为控制反转。
    • Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的"外部"
    • IoC容器负责对象的创建、初始化等一系列工作,被创建的对象在IoC容器中被称为Bean
1.2:DI
  • DI(Dependency Injection)依赖注入
    • 在容器中建立Bean与Bean之间的依赖关系的整个过程,称为依赖注入。
1.3:最终效果
  • 充分解耦
  • 使用IoC容器管理Bean
  • 在IoC容器内将有依赖关系的Bean进行关系绑定(ID)
  • 使用对象时不仅可以直接从IoC容器中获取,并且获取到的Bean已经绑定了所有的依赖关系。
2.快速入门
2.1:导入相关坐标

<!--Spring框架-->

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.21.RELEASE</version>
</dependency>
2.2:定义Spring管理的类(接口)
public interface BookDao {
    
    
    public void save();
}

public class BookDaoImpl implements BookDao {
    
    
    public void save() {
    
    
        System.out.println("book dao save ...");
    }
}

public interface BookService {
    
    
    public void save();
}

public class BookServiceImpl implements BookService {
    
    
    //5.删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;

    public void save() {
    
    
        System.out.println("book service save ...");
        bookDao.save();
    }
    //6.提供对应的set方法(容器在执行)
    public void setBookDao(BookDao bookDao) {
    
    
        this.bookDao = bookDao;
    }
}
2.3:创建Spring配置文件,配置对应类作为Spring管理的Bean

applicationContext.xml

	<!--1.导入spring坐标:spring-context-->
    <!--2.配置bean-->
    <!--id属性表示bean的名字
    class属性表示给bean定义类型
	name属性表示给bean取别名,可以当做id使用-->
    <bean id="bookDao" name="dao bookDaoImpl" class="com.my.dao.impl.BookDaoImpl"/>
    <bean id="bookService" class="com.my.service.impl.BookServiceImpl">
        <!--7.配置server与Dao的关系-->
        <!--name属性表示配置哪一个具体的属性,属性名称
        ref属性表示参照哪一个bean-->
        <property name="bookDao" ref="bookDao"/>
    </bean>
2.4:初始化IoC容器(Spring核心容器/Spring容器),通过容器获取Bean
public static void main(String[] args) {
    
    
    //3.加载配置文件得到上下文对象,也就是容器对象
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

    //4.获取资源
    // BookDao bookDao = (BookDao) ctx.getBean("bookDao");
    // bookDao.save();
    
    BookService bookService = (BookService) ctx.getBean("bookService");
    bookService.save();
}
3:bean的作用范围
  • scope属性用于改变bean的作用范围,默认情况下scope属性为singleton,此时为单例模式,即创建出来的bean都是同一个,当scope属性为prototype时候,即为非单例模式。

  • 为什么bean默认情况下为单例模式?可以用一个bean完成多个功能,提高复用性。

  • 适合交给容器进行管理的bean:

    • 表现层对象(servlet)
    • 业务层对象(service)
    • 数据层对象(Dao)
    • 工具类对象
  • 不适合交给容器进行管理的bean

    • 封装实体的域对象
4:实例化bean的四种方式
4.1:构造方法(常用)
  • 需要提供默认构造方法(无参构造方法)
  • 如果无参构造方法不存在,将抛出异常BeanCreationException
4.2:静态工厂(了解)
  • 静态工厂

    public class OrderDaoFactory{
          
          
        public static OrderDao getOrderDao(){
          
          
            return new OrderDaoImpl();
        }
    }
    
  • 配置

    <bean
        id="orderDao"
        class="com.my.factory.OrderDaoFactory"
        factory-method="getOrderDao"
    />
    
4.3:实例工厂(了解)

在这里插入图片描述

扫描二维码关注公众号,回复: 14467392 查看本文章
4.4:FactoryBean(实用)
  • BookDaoFactoryBean.java
public class BookDaoFactoryBean implements FactoryBean<BookDao> {
    
    
    @Override
    public BookDao getObject() throws Exception {
    
    
        return new BookDaoImpl();
    }

    @Override
    public Class<?> getObjectType() {
    
    
        return BookDao.class;
    }
}
  • 配置信息
<!--FactoryBean方式-->
<bean id="bookDaoFac" class="com.my.factory.BookDaoFactoryBean"/>
4.5:Bean生命周期
  • 初始化容器

    1. 创建对象(内存分配)
    2. 执行构造方法
    3. 执行属性注入(set操作)
    4. 执行bean初始化方法
  • 使用Bean

    1. 执行业务操作
  • 关闭/销毁容器

    1. 执行bean销毁方法
  • bean生命周期控制

    • 配置
      • init-method
      • destroy-method
    • 接口(了解)
      • InitializingBean
      • DisposableBean
  • 关闭容器

    • ConfigurableApplicationContext

      • 手工关闭容器

        ConfigurableApplicationContext接口close()操作

      • 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机

        ConfigurableApplicationContext接口registerShutdownHook()操作

在这里插入图片描述

5:向类传递数据
5.1:依赖注入方式
  1. setter注入
    • 简单类型
    • 引用类型
  2. 构造器注入
    • 简单类型
    • 引用类型
5.2:setter注入
  1. 引用类型

    • 在bean中定义引用数据类型属性并提供可访问的set方法

      private UserDao userDao;
      
      public void setUserDao(UserDao userDao) {
              
              
          this.userDao = userDao;
      }
      
    • 配置中使用property标签ref属性注入引用类型对象

      <bean id="userDao" class="com.my.dao.impl.UserDaoImpl"/>
      <bean id="bookService" class="com.my.service.impl.BookServiceImpl">
          <!--name属性表示配置哪一个具体的属性
          ref属性表示参照哪一个bean-->
          <!--注入引用数据类型-->
          <property name="userDao" ref="userDao"/>
      </bean>
      
  2. 简单类型

    • 在bean中定义引用类型属性并提供可访问的set方法

      BookDaoImpl

      public class BookDaoImpl implements BookDao {
              
              
          private int conNum;
          private String dbName;
      
          public void setConNum(int conNum) {
              
              
              this.conNum = conNum;
          }
      
          public void setDbName(String dbName) {
              
              
              this.dbName = dbName;
          }
      
          public void save() {
              
              
              System.out.println("book dao save ..."+conNum+" "+dbName);
          }
      }
      
    • 配置中使用property标签value属性注入简单类型数据

      <bean id="bookDao" class="com.my.dao.impl.BookDaoImpl">
          <!--注入简单数据类型-->
          <property name="conNum" value="10"/>
          <property name="dbName" value="mysql"/>
      </bean>
      
5.3:构造器注入
  1. 引用类型

    • 在bean中定义引用数据类型属性并提供可访问的构造方法

      private BookDao bookDao;
      private UserDao userDao;
      
      public BookServiceImpl(BookDao bookDao, UserDao userDao) {
              
              
          this.bookDao = bookDao;
          this.userDao = userDao;
      }
      
    • 配置中使用constructor-arg标签ref属性注入引用类型对象

      <bean id="bookService" class="com.my.service.impl.BookServiceImpl">
          <!--注入引用数据类型-->
          <constructor-arg name="bookDao" ref="bookDao"/>
          <constructor-arg name="userDao" ref="userDao"/>
      </bean>
      
  2. 简单类型

    • 在bean中定义简单数据类型属性并提供可访问的构造方法

      private int conNum;
      private String dbName;
      
      public BookDaoImpl(int conNum, String dbName) {
              
              
          this.conNum = conNum;
          this.dbName = dbName;
      }
      
    • 配置中使用constructor-arg标签value属性注入简单类型对象

      <bean id="bookDao" class="com.my.dao.impl.BookDaoImpl">
          <constructor-arg name="conNum" value="10"/>
          <constructor-arg name="dbName" value="mysql"/>
      </bean>
      
    • 配置中使用constructor-arg标签type属性设置按照形参类型注入

    • 配置中使用constructor-arg标签index属性设置按照形参位置注入

5.4:依赖注入方式选择

在这里插入图片描述

5.5:自动类型的装配
  1. 使用bean标签autowire属性设置自动装配的类型(byType、byName(耦合度高,不推荐))

    <bean id="bookDao" class="com.my.dao.impl.BookDaoImpl"/>
    <bean id="bookService" class="com.my.service.impl.BookServiceImpl" autowire="byType"/>
    <bean id="bookService" class="com.my.service.impl.BookServiceImpl" autowire="byName"/>
    
  2. 依赖自动装配特征

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y8PTeIUR-1653122017072)(SSM笔记.assets/image-20220515195109170.png)]

5.6:注入集合
public class BookDaoImpl implements BookDao {
    
    
    private int[] array;
    private List<String> list;
    private Set<String> set;
    private Map<String, String> map;
    private Properties properties;

    public void setArray(int[] array) {
    
    
        this.array = array;
    }

    public void setList(List<String> list) {
    
    
        this.list = list;
    }

    public void setSet(Set<String> set) {
    
    
        this.set = set;
    }

    public void setMap(Map<String, String> map) {
    
    
        this.map = map;
    }

    public void setProperties(Properties properties) {
    
    
        this.properties = properties;
    }

    public void save() {
    
    
        System.out.println(Arrays.toString(array));
        System.out.println(list);
        System.out.println(set);
        System.out.println(map);
        System.out.println(properties);
    }
}

``

<bean id="bookDao" class="com.my.dao.impl.BookDaoImpl">
    <property name="array">
        <array>
            <value>100</value>
            <value>200</value>
            <value>300</value>
        </array>
    </property>

    <property name="list">
        <list>
            <value>country</value>
            <value>aaa</value>
            <value>bbb</value>
        </list>
    </property>

    <property name="set">
        <set>
            <value>100</value>
            <value>aaa</value>
            <!--自动去重-->
            <value>aaa</value>
            <value>bbb</value>
        </set>
    </property>

    <property name="map">
        <map>
            <entry key="country" value="china"/>
            <entry key="province" value="guangdong"/>
            <entry key="city" value="shenzhen"/>
        </map>
    </property>

    <property name="properties">
        <props>
            <prop key="country">china</prop>
            <prop key="province">guangdong</prop>
            <prop key="city">guangzhou</prop>
        </props>
    </property>
</bean>
6:数据源对象管理
6.1:基本配置

6.1.1导入Druid坐标

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>

6.1.2配置数据源对象作为spring管理的bean

<bean  class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
    <property name="username" value="root"/>
    <property name="password" value="440983"/>
</bean>
6.2:加载properties文件

6.2.1.开启context名称空间

<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"  <!--更改1-->
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context  <!--更改2-->
            http://www.springframework.org/schema/context/spring-context.xsd"> <!--更改3-->

6.2.2.使用context命名空间,加载指定properties文件

<context:property-placeholder location="jdbc.properties"/>

6.2.3.使用${}读取加载的属性值

<bean id="dataSource"  class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

6.2.4.其他设置

在这里插入图片描述

6.2.5.加载配置文件

在这里插入图片描述

6.2.6.容器相关

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gqUnsbVR-1653122017074)(SSM笔记.assets/image-20220515232349459.png)]

6.2.7获取bean

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AzbPkyPK-1653122017074)(SSM笔记.assets/image-20220515232415151.png)]

6.3:注解开发bean

6.3.1使用@Componet定义bean

@Component("bookDao")
public class BookDaoImpl implements BookDao {
    
    
}

@Component
public class BookServiceImpl implements BookService {
    
    
}

6.3.2核心配置文件中通过组件扫描加载bean

<!--配置核心文件扫描bean-->
<context:component-scan base-package="com.my"/>

6.3.3 Spring提供@Component注解的三个衍生注解(与Component功能一样)

@Controller  //用于表现层bean定义
@Service  //用于业务层定义bean
@Repository  //用于数据层bean定义
7:纯注解开发:
7.1:基本配置

7.1.1:Spring3.0开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道

7.1.2:Java类代替Spring核心配置文件

com.my.config.SpringConfig.java

@Configuration   //用于设定当前类为配置类
// @ComponentScan("com.my")  
@ComponentScan({
    
    "com.my.service","com.my.dao"})  //用于设定扫描路径,只能添加一次,多个数据用数组格式
public class SpringConfig {
    
    
}

7.1.3:读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象

public static void main(String[] args) {
    
    
    ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
    //获取资源 按bean名称获取
    BookDao bookDao = (BookDao) ctx.getBean("bookDao");
    System.out.println(bookDao);

    // 按bean类型获取
    BookService bookService = ctx.getBean(BookService.class);
    System.out.println(bookService);
}

7.1.4:小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bXl4UcWW-1653122017075)(SSM笔记.assets/image-20220516103744714.png)]

7.2:作用范围及生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mHd2neTf-1653122017075)(SSM笔记.assets/image-20220516104915366.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u47LWBUE-1653122017075)(SSM笔记.assets/image-20220516104925179.png)]

7.3:依赖注入

7.3.1:注入引用类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yVL3XsFI-1653122017076)(SSM笔记.assets/image-20220516111247525.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o7k3PIUd-1653122017076)(SSM笔记.assets/image-20220516111326512.png)]

7.3.2:简单数据类型

@Value("${}")
private String name;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HKHoioUA-1653122017077)(SSM笔记.assets/image-20220516111550591.png)]

7.3.3:小结

7.4:第三方Bean的注入

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vaS1i70A-1653122017077)(SSM笔记.assets/image-20220516113838220.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XToMzcB8-1653122017077)(SSM笔记.assets/image-20220516113853091.png)]

7.5:XML配置VS注解配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h4apuS75-1653122017078)(SSM笔记.assets/image-20220516114459770.png)]

8:Spring整合Mybatis
8.1:jdbcConfig
public class jdbcConfig {
    
    
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource(){
    
    
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }
8.2:mybatisConfig
public class mybatisConfig {
    
    
    //替换xml基本配置信息
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
    
    
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setTypeAliasesPackage("com.my.pojo");
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
    }

    //替换
    /*<mappers>
        <package name="com.my.dao"/>
    </mappers>*/
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
    
    
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.my.dao");
        return msc;
    }
}
8.3:SpringConfig
@Configuration
@ComponentScan("com.my")
@PropertySource("classpath:jdbc.properties")
@Import({
    
    jdbcConfig.class,mybatisConfig.class})
public class SpringConfig {
    
    
}
9:Spring整合Junit
9.1:导入坐标
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.20.RELEASE</version>
</dependency>
9.2:创建junit测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {
    
    
    @Autowired
    private AccountService accountService;

    @Test
    public void testFindById(){
    
    
        Account ac = accountService.findById(1);
        System.out.println(ac);
    }

    @Test
    public void testFindAll(){
    
    
        for (Account account : accountService.findAll()) {
    
    
            System.out.println(account);
        }

    }
}
10:AOP(面向切面编程)
10.1:基本概念
  • AOP(Aspect Oriented Programming)面向切面编程,一种编程规范,指导开发者如何组织程序结构

    • OOP:面向对象编程
  • 作用:在不惊动原始设计的基础上为其进行功能增强

  • Spring概念:无侵入式/无入侵式

  • 连接点(JoinPoint):程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等

    • 在SpringAOP中,理解为方法的执行
  • 切入点(Pointcut):匹配连接点的式子

    • 在SpringAOP中,一个切入点可以描述一个具体方法,也可以匹配多个方法
      • 一个具体方法:com.my.dao包下的BookDao接口中的无形参无返回值的save()方法
      • 匹配多个方法:所有的save方法,所有以get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法。
  • 通知(Advice):在切入点处执行的操作,也就是共性功能

    • 在SpringAOP中,功能最终以方法的形式呈现
  • 通知类:定义通知的类

  • 切面(Aspect):描述通知与切入点的对应关系

10.2:入门案例

10.2.1:导入aop相关坐标

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

10.2.2:实现dao接口与实现类

@Repository
public class BookDaoImpl implements BookDao {
    
    
    public void save() {
    
    
        System.out.println(System.currentTimeMillis());
        System.out.println("book dao save ...");
    }

    @Override
    public void update() {
    
    
        System.out.println("book dao update...");
    }
}

10.2.3:定义通知类,制作通知

10.2.4:定义切入点

10.2.5:绑定切入点与通知关系,并指定通知添加到原始连接点的具体执行位置

10.2.6:定义通知类受Spring容器管理,并定义当前类为切面类

@Component   //6.1 定义通知类受Spring容器管理
@Aspect  //6.2 定义当前类为切面类
public class MyAdvice {
    
    
    //4.定义切入点
    @Pointcut("execution(void com.my.dao.BookDao.update())")
    public void pt(){
    
    }

    //3.定义通知类
    @Before("pt()")  //5.绑定切入点与通知关系,并指定通知添加到原始连接点的具体执行位置
    public void before(){
    
    
        System.out.println(System.currentTimeMillis());
    }
}

10.2.7:开启Spring对Aop注解驱动支持

@Configuration
@ComponentScan("com.my")
@EnableAspectJAutoProxy  //7.开启Spring对Aop注解驱动支持
public class SpringConfig {
    
    
}

10.2.8:其他代码

public class App {
    
    
    public static void main(String[] args) {
    
    
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao = ctx.getBean(BookDao.class);
        bookDao.update();
    }
}
10.3:AOP执行流程

10.4:AOP切入点表达式

在这里插入图片描述

10.5:AOP通知

10.5.1:前置通知 @Before

10.5.2:后置通知 @After

10.5.3:环绕通知(重点)
在这里插入图片描述

●参数ProceedingJoinPoint参数必须放在第一位。

10.5.4:返回后通知(了解) @AfterReturning 原始切入点方法正常执行完毕后运行

10.5.5:抛出异常通知(了解) @AfterThrowing 抛出异常后执行,不抛异常不执行

10.6:执行效率案例
@Component
@Aspect
public class ProjectAdvice {
    
    
    @Pointcut("execution(* com.my.service.*Service.*(..))")
    private void servicePt(){
    
    }

    @Around("ProjectAdvice.servicePt()")
    public void runSpeed(ProceedingJoinPoint pjp) throws Throwable {
    
    
        //获取执行签名信息
        Signature signature = pjp.getSignature();
        //通过签名获取执行类型(接口名)
        String className = signature.getDeclaringTypeName();
        //通过签名获取执行操作名称(方法名)
        String methodName = signature.getName();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
    
    
            Object ret = pjp.proceed();
        }
        long end = System.currentTimeMillis();
        System.out.println("执行"+className+"."+methodName+"万次耗时"+(end-start)+"ms");
    }
}
10.7:AOP通知获取数据

10.7.1:获取参数

10.7.2:获取返回值

11:Spring事务
11.1:开启事务步骤


在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4p0KUBwA-1653122017079)(SSM笔记.assets/image-20220517105446886.png)]

11.2:事务角色

11.3:事务配置&传播行为

11.3.1:事务配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tggpckuc-1653122017079)(SSM笔记.assets/image-20220517141054596.png)]

11.3.2:事务传播

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-biHJ9JjY-1653122017079)(SSM笔记.assets/image-20220517141132671.png)]

11.3.3:案例

  1. 在jdbcConfig中添加事务管理器
//设置事务管理器
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
    
    
    DataSourceTransactionManager ptm = new DataSourceTransactionManager();
    ptm.setDataSource(dataSource);
    return ptm;
}
  1. 在SpringConfig中开启事务支持
@Configuration
@ComponentScan("com.my")
@PropertySource("classpath:jdbc.properties")
@Import({
    
    jdbcConfig.class,mybatisConfig.class})
@EnableAspectJAutoProxy   //开启Spring对Aop注解驱动的支持
@EnableTransactionManagement //开启事务支持
public class SpringConfig {
    
    
}
  1. Dao层操作
//数据层操作
public interface AccountDao {
    
    
    @Update("update tbl_account set money = money + #{money} where name = #{name}")
    void inMoney(@Param("name")String name,@Param("money")Double money);

    @Update("update tbl_account set money = money - #{money} where name = #{name}")
    void outMoney(@Param("name") String name,@Param("money") Double money);
}
public interface LogDao {
    
    
    @Insert("insert into tbl_log(info,createDate) values(#{info},now())")
    void log(String info);
}
  1. Service层
public interface AccountService {
    
    
    @Transactional
    public void transfer(String out,String in,Double money);
}
public interface LogService {
    
    
    //propagation设置事务属性:传播行为设置为当前操作需要新事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void log(String out,String in,Double money);

}
@Service
public class AccountServiceImpl implements AccountService {
    
    
    @Autowired
    private AccountDao accountDao;

    @Autowired
    private LogService logService;

    @Override
    public void transfer(String out, String in, Double money) {
    
    
        try{
    
    
            accountDao.outMoney(out,money);
            int a = 1/0;
            accountDao.inMoney(in,money);
        }finally {
    
    
            logService.log(out,in,money);
        }
    }
}
@Service
public class LogServiceImpl implements LogService {
    
    
    @Autowired
    private LogDao logDao;
    @Override
    public void log(String out, String in, Double money) {
    
    
        logDao.log(out+"向"+in+"转账"+money+"钱");
    }
}
  1. Test
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {
    
    
    @Autowired
    AccountService accountService;

    @Test
    public void transferTest(){
    
    
        accountService.transfer("Tom","Jerry",100D);
    }
}

三:SpringMVC

1:概述
  • SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
  • 优点
    • 使用简单,开发便捷(相比于Servlet)
    • 灵活性强
2:快速入门

2.1:导入坐标

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>

2.2:初始化SpringMVC环境

@Configuration
@ComponentScan("com.my")   //设定SpringMVC加载对应bean
public class SpringMVCConfig {
    
    
}

2.3:创建SpringMVC控制器类(等同于Servlet功能)

@Controller
public class UserController {
    
    
    @RequestMapping("/save")  //设置当前控制器方法请求访问路径
    @ResponseBody   //设置当前控制器方法响应内容为当前返回值,无需解析
    public String save(){
    
    
        System.out.println("user save...");
        return "{'info':'springmvc'}";
    }
}

2.4:初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC请求拦截的路径

//AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    
    
    //初始化容器并注册返回容器到Tomcat中,以便可以访问bean
    @Override
    protected WebApplicationContext createServletApplicationContext() {
    
    
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMVCConfig.class);
        return ctx;
    }

    //设定SpringMVC对应的请求映射路径,设置为/表示拦截所有请求,任意请求都将转入到SpringMVC进行处理
    @Override
    protected String[] getServletMappings() {
    
    
        return new String[]{
    
    "/"};
    }

    //如果创建Servlet容器时需要加载非SpringMVC对应的bean,使用当前方法进行,使用方式同createServletApplicationContext()
    @Override
    protected WebApplicationContext createRootApplicationContext() {
    
    
        return null;
    }
}
3:Controller加载控制与业务Bean加载控制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3SBZO2ni-1653122017079)(SSM笔记.assets/image-20220517171628419.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m5fdBcQw-1653122017080)(SSM笔记.assets/image-20220517171656007.png)]

4:URL传递参数
  • 正常情况下名称对名称

    • 普通参数 save(String name,int age)

    • 封装对象 save(User user)

    • 数组 save(String[] array)

      参数设置 array 10、array 20…

  • 名称对不上用@RequestParam

    • 集合 save(@RequestParam List list)

      参数设置 list 10、list 20…

5:JSON数据传递参数

5.1:添加JSON数据转换坐标

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.6.1</version>
</dependency>

5.2:在body中设置JSON数据并发送

5.3:开启自动转换JSON数据的支持

@Configuration
@ComponentScan("com.my")
@EnableWebMvc    //开启自动转换JSON数据的支持,开启SpringMVC多项辅助功能
public class SpringMVCConfig {
    
    
}

5.4:设置接收JSON数据

@Controller
public class UserController {
    
    
    @ResponseBody  //将请求中请求体所包含的数据传递给请求参数,此注解一个方法只能使用一次
    @RequestMapping("/listParamForJson")
    public String listParamForJson(@RequestBody List<String> likes){
    
    
        System.out.println("list common(json)参数传递==>" + likes);
        return "{'info':'springmvc'}";
    }

6:日期类型参数传递
  • dataParam(Date date, //2020/2/12

    @DateTimeFormat(pattern=“yyyy-MM-dd”) Date date1, //2020-5-17

    @DateTimeFormat(pattern=“yyyy/MM/dd HH:mm:ss”) Date date2 //2020/02/20 20:20:20

    )

7:响应
//响应页面/跳转页面
@RequestMapping("/toJumpPage")
public String toJumpPage(){
    
    
    System.out.println("跳转页面");
    return "page.jsp";
}

//响应纯文本数据
@RequestMapping("/toText")
@ResponseBody
public String toText(){
    
    
    System.out.println("返回纯文本数据");
    return "response text";
}

//响应POJO对象
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
    
    
    System.out.println("返回json对象数据");
    User user = new User();
    user.setName("Tom");
    user.setAge(20);
    return user;
}

//响应POJO集合对象
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
    
    
    System.out.println("返回JSON集合数据");
    User user1 = new User();
    user1.setName("Tom");
    user1.setAge(15);

    User user2 = new User();
    user2.setName("Jerry");
    user2.setAge(18);

    User user3 = new User();
    user3.setName("Jack");
    user3.setAge(20);

    List<User> users = new ArrayList<>();
    users.add(user1);
    users.add(user2);
    users.add(user3);
    return users;
}
8:REST

8.1:概述

8.2:REST风格案例

// REST/POST
@RequestMapping(value = "/users", method = RequestMethod.POST)
@ResponseBody
public String save() {
    
    
    System.out.println("user save...");
    return "{'module':'user save'}";
}

@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id) {
    
    
    System.out.println("user delete..."+id);
    return "{'module':'user delete'}";
}

@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
    
    
    System.out.println("user update..."+user);
    return "{'module':'user update'}";
}

//查询
@RequestMapping(value = "/users/{id}",method = RequestMethod.GET)
@ResponseBody
public String getById(@PathVariable Integer id){
    
    
    System.out.println("user getById..."+id);
    return "{'module':'user getById'}";
}

8.3:简化

/**
 * 简化REST
 */
@RestController("/book")
public class BookController {
    
    
    // REST/POST
    @PostMapping
    public String save() {
    
    
        System.out.println("book save...");
        return "{'module':'book save'}";
    }

    @DeleteMapping("/{id}")
    public String delete(@PathVariable Integer id) {
    
    
        System.out.println("book delete..."+id);
        return "{'module':'book delete'}";
    }
    
    @PutMapping
    public String update(@RequestBody Book book){
    
    
        System.out.println("book update..."+book);
        return "{'module':'book update'}";
    }

    //查询
    @GetMapping("/{id}")
    public String getById(@PathVariable Integer id){
    
    
        System.out.println("book getById..."+id);
        return "{'module':'book getById'}";
    }
    
    @GetMapping
    public String getAll(){
    
    
        System.out.println("book getAll...");
        return "{'module':'book getAll'}";
    }
}

8.4:设置对静态资源的放行

public class SpringMvcSupport extends WebMvcConfigurationSupport {
    
    
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    
    
        //当访问/pages/???时候,走pages目录下的内容,防止被SpringMVC拦截
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}
9:表现层返回结果规范化处理

9.1:在controller定义Result类

public class Result {
    
    
    private Object data;   //返回数据
    private Integer code;  //返回结果代码
    private String msg;   //消息

9.2:定义返回代码

com.my.controller.Code.java

public class Code {
    
    
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;

    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;

}

9.3:修改表现层返回类型

@GetMapping
public Result getAll() {
    
    
    List<Book> bookList = bookService.getAll();
    Integer code = (bookList == null ? Code.GET_ERR:Code.GET_OK);
    String msg = (bookList == null? "数据查询失败!":"");
    return new Result(code,bookList,msg);
}
10:异常处理

10.1:集中处理

com.my.controller.ProjectExceptionAdvice.java

@RestControllerAdvice   //将类声明为异常处理类
public class ProjectExceptionAdvice {
    
    
    @ExceptionHandler(Exception.class)  //定义处理哪一种异常
    public Result doException(Exception ex){
    
    
        return new Result(11111,null,"捕捉到异常!");
    }
}

10.2:异常分类

  • 业务异常(BusinessException)

    • 规范的用户行为产生的异常
    • 不规范的用户行为操作产生的异常
  • 系统异常(SystemException)

    • 项目运行过程中可预计且无法避免的异常
  • ​ 其他异常(Exception)

    • 编程人员未预期到的异常

10.3:异常分类处理

10.3.1:定义Result返回体

com.my.controller.Result.java

public class Result {
    
    
    private Object data;   //返回数据
    private Integer code;  //返回结果代码
    private String msg;   //消息

10.3.2:定义异常编码

package com.my.controller;

public class Code {
    
    
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;

    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;

    public static final Integer SYSTEM_ERR = 50001;
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
    public static final Integer SYSTEM_UNKNOWN_ERR = 59999;
    public static final Integer BUSINESS_ERR = 60002;
}

10.3.3:定义异常类

package com.my.exception;

public class BusinessException extends RuntimeException{
    
    
    private Integer code;

    public Integer getCode() {
    
    
        return code;
    }

    public void setCode(Integer code) {
    
    
        this.code = code;
    }

    public BusinessException(Integer code, String message) {
    
    
        super(message);
        this.code = code;
    }

    public BusinessException(Integer code, String message, Throwable cause) {
    
    
        super(message, cause);
        this.code = code;
    }
}
package com.my.exception;

public class SystemException extends RuntimeException{
    
    
    private Integer code;

    public Integer getCode() {
    
    
        return code;
    }

    public void setCode(Integer code) {
    
    
        this.code = code;
    }

    public SystemException(Integer code, String message) {
    
    
        super(message);
        this.code = code;
    }

    public SystemException(Integer code, String message, Throwable cause) {
    
    
        super(message, cause);
        this.code = code;
    }
}

10.3.4:定义异常处理类

package com.my.controller;

import com.my.exception.BusinessException;
import com.my.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 处理异常
 */
@RestControllerAdvice   //将类声明为异常处理类
public class ProjectExceptionAdvice {
    
    
    @ExceptionHandler(SystemException.class)  //定义处理哪一种异常
    public Result doSystemException(SystemException ex){
    
    
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    @ExceptionHandler(BusinessException.class)  //定义处理哪一种异常
    public Result doBusinessException(BusinessException ex){
    
    
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    @ExceptionHandler(Exception.class)  //定义处理哪一种异常
    public Result doException(Exception ex){
    
    
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOWN_ERR,null,"系统繁忙,请稍后再试!");
    }
}

10.3.5:捕捉异常

com.my.controller.BookController.java

@GetMapping(value = ("/getById"))
public Result getById(@RequestParam("id") Integer id) {
    
    
    if(id == 0){
    
    
        throw new BusinessException(Code.BUSINESS_ERR,"请规范您的操作!");
    }
    //将可能出现的异常进行包装,转换成自定义异常
    try{
    
    
        int i = 1/0;
    }catch (Exception e){
    
    
        throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请稍后再试!",e);
    }
    Book book = bookService.getById(id);
    Integer code = (book == null? Code.GET_ERR:Code.GET_OK);
    String msg = (book == null? "数据查询失败!":"");
    return new Result(code,book,msg);
}
11:拦截器

11.1:声明拦截器的bean,并实现HandlerInterceptor接口(注意:扫描加载bean)

package com.my.controller.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class ProjectInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("preHandle...");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("postHandle...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("afterCompletion...");
    }
}

11.2:定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法(注意:扫描加载配置)

package com.my.config;

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    
    
    //设置过滤静态访问资源
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    
    
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }

    //自动装配拦截器
    @Autowired
    private ProjectInterceptor projectInterceptor;
    
    //添加拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");  //设置具体拦截路径,可设置多个
    }
}

11.3:添加扫描路径

@Configuration
@ComponentScan({
    
    "com.my.controller","com.my.config"})
@EnableWebMvc
public class SpringMvcConfig {
    
    
}

11.4:简化(注意:侵入式较强)

com.my.config.SpringMvcConfig.java

@Configuration
@ComponentScan({
    
    "com.my.controller"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
    
    
    //自动装配拦截器
    @Autowired
    private ProjectInterceptor projectInterceptor;

    //添加拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");  //设置具体拦截路径
    }
}

11.5:执行流程

11.6:拦截器参数

11.7:拦截器链

四:Maven高级

1:分模块开发

1.1:创建Maven模块

1.2:书写模块代码

1.3:通过Maven指令安装模块到本地仓库(install指令)

2:可选依赖于排除依赖

2.1:可选依赖

true

指对外隐藏当前所依赖的资源----不透明

2.2:排除依赖

指主动断开依赖的资源,被排除的资源无需指定版本-------不需要

3:多环境配置与应用

3.1:多环境

3.2:跳过测试

4:yml文件读取

五:SpringBoot&MybatisPlus

1:快速入门

1.1:导入坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>
    <groupId>com.my</groupId>
    <artifactId>MybatisPlus-demo1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>MybatisPlus-demo1</name>
    <description>MybatisPlus-demo1</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

1.2:创建配置文件(注意空格)

application.yml

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_db
    username: root
    password: 440983

1.3:创建Book及BookDao

@Data    //添加Lombok注解
public class Book {
    
    
    private int id;
    private String type;
    private String name;
    private String description;
}

@Mapper
public interface BookDao extends BaseMapper<Book> {
    
    
}
  • 说明:@Data注解为当前实体类在编译期设置对应的get/set方法,toString方法、hashCode方法、equals方法等
  • 要注意数据库中表的名称要为book

1.4:测试

@SpringBootTest
class ApplicationTests {
    
    
    @Autowired
    private BookDao bookDao;

    @Test
    void getByIdTest() {
    
    
        Book book = bookDao.selectById(1);
        System.out.println(book);
    }

    @Test
    void updateTest(){
    
    
        Book book = new Book();
        book.setId(1);
        book.setDescription("操作系统从入门到入坟");
        int i = bookDao.updateById(book);
        System.out.println(i);
    }
    
    <!--
        bookDao.deleteBatchIds(List);   <!--多数据按id删除-->
        bookDao.selectBatchIds(List);   <!--多数据按id查询-->
    -->
}

2:分页查询

2.1:设置分页拦截器作为Spring管理的bean

@Configuration
public class MpConfig {
    
    
    @Bean
    public MybatisPlusInterceptor pageInterceptor(){
    
    
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

2.2:执行分页查询

public void pageTest(){
    
    
    IPage<Book> page = new Page<Book>(1, 3);
    bookDao.selectPage(page,null);
    System.out.println("当前页码:"+page.getCurrent());
    System.out.println("每页数据总量:"+page.getSize());
    System.out.println("总页数:"+page.getPages());
    System.out.println("数据总量:"+page.getTotal());
    System.out.println("当前页数据:"+page.getRecords());
}
3:条件查询
//条件查询
@Test
public void getAllTest(){
    
    
    //方式一:按条件查询
    QueryWrapper<Book> qw = new QueryWrapper<Book>();
    qw.lt("id",6);    //小于
    for (Book book : bookDao.selectList(qw)) {
    
    
        System.out.println(book);
    }

    //方式二:lambda格式
    QueryWrapper<Book> qw = new QueryWrapper<Book>();
    qw.lambda().lt(Book::getId,6);
    for (Book book : bookDao.selectList(qw)) {
    
    
        System.out.println(book);
    }

    //方式三(推荐)
    LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
    lqw.lt(Book::getId,6);
    for (Book book : bookDao.selectList(lqw)) {
    
    
        System.out.println(book);
    }

    //多条件查询
    LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
    //4到10之间
    // lqw.lt(Book::getId,10).gt(Book::getId,4);
    //小于4或者大于10
    lqw.lt(Book::getId,4).or().gt(Book::getId,10);
    for (Book book : bookDao.selectList(lqw)) {
    
    
        System.out.println(book);
    }
    
    /*----------------------------------------NULL判定---------------------------------*/
    LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
    BookQuery bookQuery = new BookQuery();
    bookQuery.setId(10);
    bookQuery.setId2(5);
    //lt 小于,le 小于等于
    //gt 大于,ge 大于等于
    //链式编程
    /* 
    lqw.lt(null != bookQuery.getId(),Book::getId,bookQuery.getId())
    .gt(null != bookQuery.getId2(),Book::getId,bookQuery.getId2());
    */
    lqw.lt(null != bookQuery.getId(),Book::getId,bookQuery.getId());
    lqw.gt(null != bookQuery.getId2(),Book::getId,bookQuery.getId2());
    for (Book book : bookDao.selectList(lqw)) {
    
    
        System.out.println(book);
    }
    
    /*----------------------------查询投影---------------------------------*/
    //查询结果包含模型中部分属性
    LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
    //查询id、书名、描述
    lqw.select(Book::getId,Book::getName,Book::getDescription);
    List<Book> bookList = bookDao.selectList(lqw);
    bookList.forEach(System.out::println);
    
    
    //查询结果包含模型中未定义的属性
    QueryWrapper<Book> qw = new QueryWrapper<>();
    /* qw.select("id","name","description");
    for (Book book : bookDao.selectList(qw)) {
        System.out.println(book);
    } */
    qw.select("count(*) as nums,type");
    qw.groupBy("type");
    List<Map<String, Object>> maps = bookDao.selectMaps(qw);
    System.out.println(maps);
    
    /*-------------------------其他查询---------------------------------*/
    lqw.between(Book::getId,10,20);    //查询id在10到20之间,包含10和20
    lqw.like("计算机");			//like %计算机%
    lqw.likeLeft("计算机");		//like %计算机
    lqw.likeRigt("计算机");		//like 计算机%
}
4:映射匹配兼容性
@Data    //添加Lombok注解
@TableName("tbl_book")   //设置当前类与数据库表之间的对应关系
public class Book {
    
    
    private Integer id;
    @TableField(value = "type",select = false)   //value设置数据库表段名称,select:设置是否参与查询
    private String Type;
    private String name;
    private String description;

    @TableField(exist = false)   //设置属性在数据库表段中是否存在,默认为true,此属性无法与value合并使用
    private Integer isON;
}
  • 全局配置

    mybatis-plus:
      global-config:
        db-config:
          id-type: auto    <!--设置id生成策略-->
          table-prefix: tbl_   <!--设置表之间对应关系,在所有pojo类名前加上"tbl_"-->
    
5:逻辑查询

5.1:数据库添加字段用于表示是否删除(注意尽量不要用关键字作为字段名)

5.2:用yml文件全局配置

mybatis-plus:
  global-config:
    banner: false
    db-config:
      logic-delete-field: is_delete   #设置表示逻辑删除的字段
      logic-delete-value: 1        #设置表示删除的值
      logic-not-delete-value: 0    #设置表示未删除的值

5.3:pojo类添加相应属性

// @TableLogic(value = "0",delval = "1")
private Integer is_delete;     //表示逻辑删除

5.4:执行删除操作

@Test
void deleteTest(){
    
    
    bookDao.deleteById(3);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ku5rodfz-1653122017080)(SSM笔记.assets/image-20220521115510938.png)]

  • 注意这时执行的是UPDATE操作
    Book::getId,Book::getName,Book::getDescription);
    List bookList = bookDao.selectList(lqw);
    bookList.forEach(System.out::println);

    //查询结果包含模型中未定义的属性
    QueryWrapper qw = new QueryWrapper<>();
    /* qw.select(“id”,“name”,“description”);
    for (Book book : bookDao.selectList(qw)) {
    System.out.println(book);
    } /
    qw.select("count(
    ) as nums,type");
    qw.groupBy(“type”);
    List<Map<String, Object>> maps = bookDao.selectMaps(qw);
    System.out.println(maps);

    /-------------------------其他查询---------------------------------/
    lqw.between(Book::getId,10,20); //查询id在10到20之间,包含10和20
    lqw.like(“计算机”); //like %计算机%
    lqw.likeLeft(“计算机”); //like %计算机
    lqw.likeRigt(“计算机”); //like 计算机%
    }


###### 4:映射匹配兼容性

```java
@Data    //添加Lombok注解
@TableName("tbl_book")   //设置当前类与数据库表之间的对应关系
public class Book {
    private Integer id;
    @TableField(value = "type",select = false)   //value设置数据库表段名称,select:设置是否参与查询
    private String Type;
    private String name;
    private String description;

    @TableField(exist = false)   //设置属性在数据库表段中是否存在,默认为true,此属性无法与value合并使用
    private Integer isON;
}
  • 全局配置

    mybatis-plus:
      global-config:
        db-config:
          id-type: auto    <!--设置id生成策略-->
          table-prefix: tbl_   <!--设置表之间对应关系,在所有pojo类名前加上"tbl_"-->
    
5:逻辑查询

5.1:数据库添加字段用于表示是否删除(注意尽量不要用关键字作为字段名)

5.2:用yml文件全局配置

mybatis-plus:
  global-config:
    banner: false
    db-config:
      logic-delete-field: is_delete   #设置表示逻辑删除的字段
      logic-delete-value: 1        #设置表示删除的值
      logic-not-delete-value: 0    #设置表示未删除的值

5.3:pojo类添加相应属性

// @TableLogic(value = "0",delval = "1")
private Integer is_delete;     //表示逻辑删除

5.4:执行删除操作

@Test
void deleteTest(){
    
    
    bookDao.deleteById(3);
}

[外链图片转存中...(img-ku5rodfz-1653122017080)]

  • 注意这时执行的是UPDATE操作

猜你喜欢

转载自blog.csdn.net/weixin_45750572/article/details/124900037