整合单元测试与日志

说明:

(1) 本篇博客合理性解释:

● 在前介绍了Spring与Mybatis配置;

● 但是,在实际开发中,还需要增加【声明式事务】、【日志模块】、【单元测试框架】等内容;本篇博客主要介绍配置这些模块;

● 然后,本篇博客在整合的时候,也进行了测试;


零:【logback日志】,【声明式事务】 ,【JUnit单元测试】:简述;

除了把Mybatis和Spring整合在一起之外,为了辅助工程能够更好的开发,还需要额外配置三项内容:

说明:

(1) 配置logback日志输出:通过logback,可以在程序运行过程中,更清晰的看到程序的执行过程,以及有哪些潜在问题;

(2) 声明式事务配置:声明式事务比编程式事务更简单和灵活,可以简化事务控制代码;

● Mybatis中也有事务控制机制,只是有点麻烦;

● Spring JDBC中有编程式事务和声明式事务;其中,声明式事务相对比较灵活;

(3) 整合JUnit单元测试:我们编写的程序,在正式发布前需要单元测试;这个组件能够提高测试的效率;


一:整合【JUnit单元测试】;

1.在pom.xml中引入【spring-test模块】和【junit单元测试依赖】;

spring对JUnit有着很好的支持;

   <!--单元测试依赖-->
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
             <version>5.2.6.RELEASE</version>
         </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.12</version>
         </dependency>

说明:

(1) 第一次接触JUnit单元测试,可以参考【单元测试与Unit4】;

(2) 第一次接触【spring-test测试模块】,可以参考【Spring与JUnit4整合】;

(3) 当我们在项目中引入这些依赖后,不需要任何配置,在这个Spring项目中,就可以利用JUnit完成单元测试了;

(4) 【spring-test】的版本,尽量和上面引入的spring-webmvc的版本保持一致;

2.测试【JUnit单元测试】,同时也走了一遍【Spring与Mybatis整合后的,访问数据库的流程!!!】;


(0)声明:两点【我们使用Mybatis中的接口开发方式了】,【我们配置的Mapper扫描器,可以自动生成Dao层的Mapper接口的实现类了】;

● 首先,自【回顾Mapper接口开发过程】开始,我们接触了Mybatis更普遍的开发方式:【基于Xml配置下,使用Mapper接口】,即Dao层都是接口,不是类了;

● 然后,在【Mybatis与Spring整合】中,我们配置了 Mapper扫描器,这些扫描器的作用就是扫描Mapper接口,生成对应的实现类;


(1)TestMapper接口:一个仅供测试用的Mapper接口;


(2)test.xml:一个仅供测试用的xml文件;

<?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">
 <mapper namespace="com.imooc.reader.mapper.TestMapper">
     <insert id="insert">
         insert into test(content) values ('测试内容')
     </insert>
 </mapper>

说明:

(1) Mybatis的xml文件,第一遇到是在【MyBatis环境配置】,如有需要可以参考;其实,这些文件的声明和约束不需要记忆,需要的时候,直接来复制就行;

(2) 我们在这个test.xml中定义了一个SQL语句,然后想让这个SQL语句对应TestMapper接口中的insert()方法;

(3) 然后,根据 【开发MyBatis工具类】中介绍的Mybatis接口开发方式的规则,这儿需要遵守;

(4) 然后这个<insert>中的SQL语句,是向test表中,插入数据:

(而且这个标签是<insert>标签,本身就告诉了Mybatis,这个标签的SQL语句是用于数据新增的;)


此时,【Mybatis的,Dao层的,Mapper接口】和【对应的,xml文件】都准备好了;由于我们配置了Mapper扫描器,此时,在运行时候,就可以自动生成接口的实现类了;


(3)为了测试,创建一个测试用的TestService类:

TestService:

 
     package com.imooc.reader.service;
 
     import com.imooc.reader.mapper.TestMapper;
     import org.springframework.stereotype.Service;
 
     import javax.annotation.Resource;
 
     @Service
     public class TestService {
         @Resource
         private TestMapper testMapper;
 
         public void batchImport() {
             for (int i = 0; i < 5; i++) {
                 testMapper.insert();
             }
         }
     }
 

说明:

(1) TestService说明;


(4)一切准备就绪,就可以创建测试类,去测试了;

TestServiceTest类:

     package com.imooc.reader.service;
 
     import org.junit.Test;
     import org.junit.runner.RunWith;
     import org.springframework.test.context.ContextConfiguration;
     import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
     import javax.annotation.Resource;
 
     import static org.junit.Assert.*;
 
     @RunWith(SpringJUnit4ClassRunner.class)
     @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
     public class TestServiceTest {
 
         @Resource
         private TestService testService;
         @Test
         public void batchImport() {
             testService.batchImport();
             System.out.println("测试数据批量导入成功。");
         }
     }

说明:

(1) 方法说明:

(2) 运行前需要引入【servlet依赖】;

上一次遇到引入servlet依赖,并且设置scope是在【拦截器入门】;

否则会报错:

(3) 运行测试类,查看结果;

在测试JUnit的时候,通过走了这一遍流程,也发现:在【SSM整合的情况下】,开发变简单了好多;也能感觉到:

● 我们在【Spring与Mybatis整合】中配置的:SqlSessionFactoryBean,Mapper接口扫描器的重要性;

● SSM整合的好处,尤其是IoC容器的好处;


至此,在程序运行时,并没有相应的日志输出;我们也就不会了解,在程序运行时,Spring内部做了什么事情;在开发时和程序上线后,我们需要日志的支持;为此就引入了接下来的部分:整合【logback日志】;

前面介绍过logback日志组件:如有需要可以依次参考;

●【MyBatis日志管理】:第一次引入SLF4日志门面、logback日志实现;(也知道了Mybatis框架中,可以很好的使用logback日志组件)

●【【logger.error()】介绍;(只是将日志打印在Console控制台)】:介绍了logger.error()方法的几种重构形式;

●【Spring编程式事务】:知道引入logback后,Spring框架就可以默认使用logback来输出日志(此时,还是向控制台输出日志);

● 【把日志信息存储到本地日志文件中】中接触到了,把日志信息存储到本地的日志文件中;

二:整合【logback日志】

Spring对logback有着良好的支持,引入logback后,Spring框架就可以默认使用logback来输出日志;

1.在pom.xml中,引入logback依赖;

 <!--引入logback-->
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <version>1.2.3</version>
         </dependency>

说明:

(1) 不过多阐述,很简单,如有需要,参考以前的几篇博客就行;可以参考最近的一篇: 【把日志信息存储到本地日志文件中】;

(2) 引入llogback依赖后,Spring会自动识别logback的存在,对其进行集成;

2.在resources目录下,创建logback.xml文件,并通过基本配置,看下是否OK;

logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
 <configuration>
     <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
         <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
             <pattern>%d{HH:mm:ss} %-5level [%thread] %logger{30} - %msg%n</pattern>
             <chasert>UTF-8</chasert>
         </encoder>
     </appender>
 
     <root level="debug">
         <appender-ref ref="console"/>
     </root>
 </configuration>

说明:

(1) 对于logback.xml有不明白的地方,如有需要,可以参考 :

●【把日志信息存储到本地日志文件中】;

●【MyBatis日志管理]]】;

(2) 内容分析:这儿我们设置的是:把日志输出到控制台,而不是输出到本地的日志文件;

(3) 重新运行下TestServiceTest这个测试类,看下结果,OK;

(4) 在实际工作中,可以根据业务需求,自己调整具体的日志格式;


以前在MySQL、JDBC、Apache Commons DbUtils,Mybatis、Spring JDBC中,接触过【数据库连接,DataSource数据源,事务控制】等内容;

● 如果迷糊了,可以参考【附加:(补):MySQL、JDBC、Apache Commons DbUtils,Mybatis、Spring JDBC:【数据库连接,DataSource数据源,事务控制】的总结和梳理;】这篇文章;

三:配置【声明式事务】;

声明式事务就是通过配置或注解的方式,来简化程序中的事务管理;

0.没有去控制事务时:很糟糕,不能实际商用;

然后,重新运行TestServiceTest测试类:(测试前,为了方便观察,把test表给清空了)

1.配置【声明式事务】;(这儿我们使用注解形式,来配置声明式事务)

这儿有不明白的地方,可以去参考【spring】, 【Spring声明式事务】及附近文章。

(1)首先要确保【spring-tx】组件已经已经引入了;

对此有不明白的可以参考【Spring声明式事务】,即我们在配置声明式事务时,需要在applicationContext.xml中使用【tx】命名空间中的标签来配置事务;(Spring自然知道这一点,所以当我们引入spring-jdbc的时候,spring-tx也一并被引入了吧)


(2)然后,在applicationContext.xml中引入【tx】命名空间和对饮的schema约束;

这些东西完全不需要自己死记硬背,需要的时候来这儿或官网去复制就行了;

  <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:task="http://www.springframework.org/schema/task"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/task
                http://www.springframework.org/schema/task/spring-task.xsd
                http://www.springframework.org/schema/mvc
                http://www.springframework.org/schema/mvc/spring-mvc.xsd
                http://www.springframework.org/schema/tx
                https://www.springframework.org/schema/tx/spring-tx.xsd">
    </beans>


(3)然后,配置【DataSourceTransactionManager】事务管理器对象;(声明式事务,离不开事务管理器)

     <!--声明式事务,配置事务管理器-->
        <bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>


(4)然后, 启用注解形式声明式事务;

  <!-- 启用注解形式声明式事务 -->
        <tx:annotation-driven transaction-manager="transactionManager"/>
 

这儿是在【注解形式声明式事务】第一次遇到,如果不明白可以快速去参考;


至此,我们就配置完成了;

2.(注解形式的)声明事务的使用和验证;


然后,重新运行TestServiceTest测试类:(测试前,为了方便观察,把test表给清空了)


SSM整合:总结;

(1) 至此,整体的【Spring】,【Spring MVC】,【Mybatis】三个框架的配置与整合就算是完成了;我们已经搭建了一个底层的开发环境;

SpringMVC环境配置 Spring与Mybatis整合 整合【logback日志】 (2) 这三篇内容十分重要,一定要掌握。

SSM整合Mybatis-Plus

说明:

(1) 本篇博客合理性解释:

● Mybatis框架用来实现数据库的增删改查;但是,Mybatis使用起来还是比较麻烦的,增删改查语句的书写还是比较麻烦的;Mybatis-Plus框架是在Mybatis框架的基础上,开发的一款敏捷开发插件;通过Mybatis-Plus,我们可以迅速的实现增删改查操作,从而让我们从Mybatis繁琐的书写SQL的过程中摆脱出来,可以极大减少MyBatis的开发工作量;

(2) 本篇博客的主要内容是:

● Mybatis-Plus简介;

● SSM项目整合Mybatis-Plus;

● Mybatis-Plus开发步骤简述;

具体的Mybatis-Plus开发的演示,在下篇博客会介绍;


一:Mybatis-Plus:简介

1.Mybatis-Plus简介;

Mybatis-Plus是基于Mybatis基础上的,一个敏捷开发插件;其作用是,帮助我们快速完成对应数据表的增删改查操作;

(1) Mybatis-Plus是国人开发的一款敏捷开发插件;

(2) Mybatis-Plus主要作用是:自动实现Mapper接口以及它的CRUD增删改查的操作;

(3) Mybatis-Plus是基于Mybatis的;

● Mybatis-Plus是在Mybatis原有基础上进行扩展得来的,Mybatis的最基础的原始代码没有被调整;

● 所以,Mybatis-Plus和Mybatis原始的代码有很好的兼容性;

● 同时Mybatis-Plus这些扩展的功能也是非侵入性的,不会对Mybatis造成任何影响;

2.为什么要有Mybatis-Plus;

3. Mybatis-Plus官网;


二:【Mybatis-Plus】和【SSM】整合

1.【Mybatis-Plus】和【SSM】整合:简述

【Mybatis-Plus】要想和【已经配置好的SSM框架】进行有机整合的话,需要分成两个阶段;

(1) 在pom.xml,引入【Mybatis-Plus】依赖;

(2) 在Spring的配置文件applicationContext.xml中,要修改SqlSessionFactory的实现类;通过更改SqlSessionFactory的实现类,来实现Mybatis-Plus的集成工作;

(3) 在Mybatis的配置文件mybatis-config.xml中,增加Mybatis-Plus的分页插件信息;

2.【Mybatis-Plus】和【SSM】整合;(重要!!!)

(1)第一步:通过pom.xml,引入【Mybatis-Plus】依赖;

 <!--引入mybatis-plus依赖-->
     <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus</artifactId>
         <version>3.3.2</version>
     </dependency>


(2)第二步:在Spring的配置文件applicationContext.xml中,要修改SqlSessionFactory的实现类;

  <!--Mybatis与Spring整合:配置SqlSessionFactory-->
        <!--原生的Mybatis与Spring整合:
        <bean id="sessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
        -->
        <bean id="sessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="mapperLocations"
value="classpath:mappers/*.xml"/>
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
        </bean>


(3)第三步: 在Mybatis的配置文件mybatis-config.xml中,增加Mybatis-Plus的分页插件信息;

   <plugins>
            <!--配置Mybatis-Plus分页插件-->
            <plugin
interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin>
        </plugins>

在介绍Mybatis的时候,【分页插件PageHelper】也介绍了Mybatis的一款分页插件PageHelper;


至此,【Mybatis-Plus】和【SSM】整合就完成了。


三:Mybatis-Plus开发步骤:简述

1.Mybatis-Plus开发步骤:简述;

(1) 创建实体类,这些实体类需要使用【@TableName/@TableId/@TableField】注解,实现与【表、字段】的映射;

(2) 创建Mapper接口,这个Mapper接口必须要继承(由Mybatis-Plus提供的)BaseMapper接口;BaseMapper接口作为父接口,提供如【新增、修改、删除、查询】等方法的声明;

创建了Mapper接口后,还要有与之对应的xml;(这都是成对出现的)

(3) 在我们实际调用开发的时候:在Service中注入对应的Mapper对象,然后通过BaseMapper内置的API实现快速的增删改查操作;

2.Mybatis-Plus核心注解:【@TableName/@TableId/@TableField】:简述

(0) 【@TableName/@TableId/@TableField】这三个注解说明了【类】和【表】的对应关系;

(1) @TableName:说明【哪个实体类】和【哪个表】对应;

(2) @TableId:说明【实体类的哪个属性】对应了【表的主键】;

(3) @TableField:说明了【实体类的属性】和【表字段】的对应;


(4) 通过这三个注解,Mybatis-Plus在加载实体对象的时候,其就会知道【实体对象】和【数据库中表】的对应关系;进而Mybatis-Plus就会自动去生成SQL语句;(这些,在实际运行时,通过日志都是可以看到的)

3.Mybatis-Plus的BaseMapper接口核心API:简述;

(1) insert(entity):数据新增;

(2) updateById(entity):根据主键更新对应的对象;其会自动生成对应的update的SQL语句;

(3) deleteById(id):根据主键删除数据;其会自动生成对应的delete的SQL语句;

(4) selectById(id):根据主键获取到与之对应的实体对象;

(5) selectList(queryWrapper):

● 需要一个参数:queryWrapper,即条件生成器

● 条件生成器,就是描述本次查询的条件有哪些;

● 其也会自动生成对应的select的SQL语句;

● 这个方法会返回一个List结果,包含多条返回的数据;

(6) selectPage(page,queryWrapper):分页查询;


(7) 通过BaseMapper的核心API可以发现:其都是自动的生成SQL语句;而生成SQL语句的依据,就是根据实体类中使用的【@TableName/@TableId/@TableField】注解来进行的;

Mybatis-plus演示

说明:

(1) 本篇博客合理性解释:

● 在上文中:【介绍了Mybatis-plus】【SSM和Mybatis-Plus整合】【Mybatis-Plus开发步骤】;

● 那么本篇博客,就通过代码实际演示Mybatis-Plus的使用;

(2)通过本篇博客,目前感受到Mybatis-Plus的三个重要的点:

● 知道Mybatis-Plus的开发套路;

● BaseMapper接口中常用的方法,需要慢慢积累,等到具体业务的时候,心里清楚应该用哪个方法;

● 查询的时候,需要用到QueryWrapper查询构造器,这儿只是对其做了简要介绍,QueryWrapper很多东西可以在需要的时候,去查就是了;


零:【回顾一下】:当我们在SSM项目中,使用Mybatis时:开发套路

当我们只使用Mybatis时,要想实现操作数据库,基本需要以下几个步骤:

1.数据表:自然,数据库中要有个待访问的表;


2.实体类:然后,需要有个实体类来对应这个表;

Test实体类与test表对应,按照比较规范的开发方式,因为设置了驼峰命名,Test类的属性应该比照test表的字段名来写;

  package com.imooc.reader.entity;
 
     /**
      * 测试用的实体类,与test表对应;
      */
     public class Test {
         private Integer id;
         private String content;
 
         public Test() {
         }
 
         public Test(Integer id, String content) {
             this.id = id;
             this.content = content;
         }
 
         public Integer getId() {
             return id;
         }
 
         public void setId(Integer id) {
             this.id = id;
         }
 
         public String getContent() {
             return content;
         }
 
         public void setContent(String content) {
             this.content = content;
         }
     }

3.Mapper接口:然后,在(普遍采用的)接口开发方式中,我们需要创建一个【用于操作test表的接口:TestDao接口】;

TestDao接口:在这儿,我们在接口中,示意性的定义了操作test表的方法;

  package com.imooc.reader.mapper;
 
     import com.imooc.reader.entity.Test;
 
     /**
      * 演示Mybatis的,测试用的MapperDao,操作test表;
      */
     public interface TestDao {
         public Test selectById();
         public void insert(Test test);
     }

4.xml实现:然后,就是创建test.xml,编写SQL语句,去实现TestDao接口中定义的方法了;

test.xml:

   <?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">
    <mapper namespace="com.imooc.reader.mapper.TestDao">
        <select id="selectById" parameterType="Integer" resultType="com.imooc.reader.entity.Test">
            select * from test where id = #{value}
        </select>
 
        <insert id="insert">
            insert into test(content) values (#{content})
        </insert>
    </mapper>

5.然后,就可以调用TestDao中的方法,愉快的操作数据库了;

我们在TestService类中,编写调用代码;

 package com.imooc.reader.service;
 
     import com.imooc.reader.entity.Test;
     import com.imooc.reader.mapper.TestDao;
     import com.imooc.reader.mapper.TestMapper;
     import org.springframework.stereotype.Service;
     import org.springframework.transaction.annotation.Transactional;
 
     import javax.annotation.Resource;
 
     @Service
     public class TestService {
 
         @Resource
         private TestDao testDao;
         @Transactional
         public void testMybatis() {
             Test test = testDao.selectById(38);
             System.out.println(test.getContent());
             Test test1 = new Test();
             test1.setContent("hehehehe");
             testDao.insert(test1);
         }
 
     }

然后,在TestServiceTest测试类中,去测试;

package com.imooc.reader.service;
 
     import org.junit.Test;
     import org.junit.runner.RunWith;
     import org.springframework.test.context.ContextConfiguration;
     import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
     import javax.annotation.Resource;
 
     import static org.junit.Assert.*;
 
     @RunWith(SpringJUnit4ClassRunner.class)
     @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
     public class TestServiceTest {
 
         @Resource
         private TestService testService;
 
 
         @Test
         public void testMybatis() {
             testService.testMybatis();
         }
     }


总结;

主要想指出的是:我们在接口中定义的方法,需要在xml中编写SQL去实现;


一:当我们在SSM项目中,使用Mybatis-Plus:开发演示;(走了一遍Mybatis-Plus的流程)

1.数据表:为了演示Mybatis-Plus,先创建一个测试用的表:test_mp表;

为了测试Mybatis-Plus,imooc_reader逻辑逻辑空间中,创建一个测试用的表test_mp;

2.实体类:创建与test_mp表对应的实体类:TestMp实体类:实体类使用了【@TableName,@TableId @TableField】注解;

在使用Mybatis时,每一个表都要有一个实体类与其对应;

TestMp实体类:

package com.imooc.reader.entity;
 
     import com.baomidou.mybatisplus.annotation.IdType;
     import com.baomidou.mybatisplus.annotation.TableField;
     import com.baomidou.mybatisplus.annotation.TableId;
     import com.baomidou.mybatisplus.annotation.TableName;
 
     /**
      * 与imooc_reader逻辑空间中的test_mp表对应
      */
 
     @TableName("test_mp")//说明这个实体类对应于哪张表;
     public class TestMp {
         @TableId(type = IdType.AUTO) //说明这个属性对应了表的主键;
         @TableField("id")//说明属性对应于哪个字段;
         private Integer id;
         @TableField("content")
         private String content;
 
         public TestMp() {
         }
         public TestMp(Integer id, String content) {
             this.id = id;
             this.content = content;
         }
         public Integer getId() {
             return id;
         }
 
         public void setId(Integer id) {
             this.id = id;
         }
 
         public String getContent() {
             return content;
         }
 
         public void setContent(String content) {
             this.content = content;
         }
     }

说明:

(1) 如果【实体类的属性名】和【数据表的字段名】相同,或者符合其符合驼峰命名规则的话:实体类属性上的@TableField注解可以省略;(个人感觉,如果一个项目中,大家都严格遵守编程规范的话,省略@TableField注解,也挺好的)

(2) 这一步比较关键,在写实体类的时候,一定要比照着表来写,别写错;

3.Mapper接口:然后,我们需要创建一个【用于操作test_mp表的接口:TestMpDao接口,该接口需要继承BaseMapper接口】;

TestMpDao:

package com.imooc.reader.mapper;
 
     import com.baomidou.mybatisplus.core.mapper.BaseMapper;
     import com.imooc.reader.entity.TestMp;
 
     public interface TestMpDao extends BaseMapper<TestMp>{
 
     }

说明:

(1) 创建Mapper接口,这个Mapper接口必须要继承(由Mybatis-Plus提供的)BaseMapper接口;BaseMapper接口作为父接口,提供如【新增、修改、删除、查询】等方法的声明;TestMpDao接口继承了BaseMapper接口,自然也继承了BaseMapper接口中的方法;

(2) BaseMapper接口是Mybatis-Plus提供的核心父接口,BaseMapper接口的内容如下:

 /*
     * Copyright (c) 2011-2020, baomidou ([email protected]).
     * <p>
     * Licensed under the Apache License, Version 2.0 (the "License"); you
may not
     * use this file except in compliance with the License. You may obtain a
copy of
     * the License at
     * <p>
     * https://www.apache.org/licenses/LICENSE-2.0
     * <p>
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
the
     * License for the specific language governing permissions and
limitations under
     * the License.
     */
    package com.baomidou.mybatisplus.core.mapper;
 
    import com.baomidou.mybatisplus.core.conditions.Wrapper;
    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.core.toolkit.Constants;
    import org.apache.ibatis.annotations.Param;
 
    import java.io.Serializable;
    import java.util.Collection;
    import java.util.List;
    import java.util.Map;
 
 
    /**
     * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
     * <p>这个 Mapper 支持 id 泛型</p>
     *
     * @author hubin
     * @since 2016-01-23
     */
    public interface BaseMapper<T> extends Mapper<T> {
 
        /**
         * 插入一条记录
         *
         * @param entity 实体对象
         */
        int insert(T entity);
 
        /**
         * 根据 ID 删除
         *
         * @param id 主键ID
         */
        int deleteById(Serializable id);
 
        /**
         * 根据 columnMap 条件,删除记录
         *
         * @param columnMap 表字段 map 对象
         */
        int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object>
columnMap);
 
        /**
         * 根据 entity 条件,删除记录
         *
         * @param wrapper 实体对象封装操作类(可以为 null)
         */
        int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
 
        /**
         * 删除(根据ID 批量删除)
         *
         * @param idList 主键ID列表(不能为 null 以及 empty)
         */
        int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends
Serializable> idList);
 
        /**
         * 根据 ID 修改
         *
         * @param entity 实体对象
         */
        int updateById(@Param(Constants.ENTITY) T entity);
 
        /**
         * 根据 whereEntity 条件,更新记录
         *
         * @param entity        实体对象 (set 条件值,可以为 null)
         * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
         */
        int update(@Param(Constants.ENTITY) T entity,
@Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
 
        /**
         * 根据 ID 查询
         *
         * @param id 主键ID
         */
        T selectById(Serializable id);
 
        /**
         * 查询(根据ID 批量查询)
         *
         * @param idList 主键ID列表(不能为 null 以及 empty)
         */
        List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<?
extends Serializable> idList);
 
        /**
         * 查询(根据 columnMap 条件)
         *
         * @param columnMap 表字段 map 对象
         */
        List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object>
columnMap);
 
        /**
         * 根据 entity 条件,查询一条记录
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
 
        /**
         * 根据 Wrapper 条件,查询总记录数
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T>
queryWrapper);
 
        /**
         * 根据 entity 条件,查询全部记录
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T>
queryWrapper);
 
        /**
         * 根据 Wrapper 条件,查询全部记录
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER)
Wrapper<T> queryWrapper);
 
        /**
         * 根据 Wrapper 条件,查询全部记录
         * <p>注意: 只返回第一个字段的值</p>
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T>
queryWrapper);
 
        /**
         * 根据 entity 条件,查询全部记录(并翻页)
         *
         * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER)
Wrapper<T> queryWrapper);
 
        /**
         * 根据 Wrapper 条件,查询全部记录(并翻页)
         *
         * @param page         分页查询条件
         * @param queryWrapper 实体对象封装操作类
         */
        <E extends IPage<Map<String, Object>>> E selectMapsPage(E page,
@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    }
 

可以看到BaseMapper接口中,定义了一系列select、insert、update、delete方法;这些方法需要慢慢熟悉和记忆;我们自己写的接口继承了BaseMapper接口,自然也继承了BaseMapper接口中的方法;

(3) 在定义的时候需要传入一个泛型,说明对应的是哪个实体类;

4.xml:然后,就是创建test_mp.xml,以对应TestMpDao接口;

 <?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">
 <mapper namespace="com.imooc.reader.mapper.TestMpDao"> </mapper>
 

说明:

(1) 我们创建了这个xml文件,并让其对应了TestMpDao接口;但是,我们在test_mp.xml中并没有编写SQL语句,去实现TestMpDao接口中的方法;

5.测试;

package com.imooc.reader;
 
     import com.imooc.reader.entity.TestMp;
     import com.imooc.reader.mapper.TestMpDao;
     import org.junit.Test;
     import org.junit.runner.RunWith;
     import org.springframework.test.context.ContextConfiguration;
     import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
     import javax.annotation.Resource;
 
     @RunWith(SpringJUnit4ClassRunner.class)
     @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
     public class MybatisPlusTest {
 
         @Resource
         private TestMpDao testMpDao;
 
         @Test
         public void testInsert() {
             TestMp testMp = new TestMp();
             testMp.setContent("测试Mybatis-plus");
             testMpDao.insert(testMp);
         }
     }

说明:

(1) 测试类说明:Mybatis-Plus会根据在实体类中定义的映射关系,自动生成方法对应的SQL实现;

(2) 运行结果;

6.总结说明;

(1)Mybatis-Plus:总结;

(2)Mybatis-Plus补充:Mybatis-Plus只是对Mybatis的增强, 原先Mybatis的东西自然依旧可以使用;

(3) 目前来看需要注意两点;

● 实体类一定要写对,一定要比对着数据表写;

● Mybatis-Plus只是对Mybatis的增强, 原先Mybatis的东西自然依旧可以使用;


二:继续演示Mybatis-Plus;(其实,也是演示BaseMapper的其他方法了)

1.演示一:试一下更新的方法;

我们通过以前的内容也知道,在实际开发中,我们要想更新的话,一般是先查一个数据,然后再在这个数据的基础上进行更新;

2.演示二:试一下删除的方法;

3.演示三:试一下查询的方法;(查询时,涉及到了QueryWrapper查询构造器,组织查询条件)

● 开始之前,先向test_mp表里插几条数据;


● BaseMapper接口中,常用的几个select方法简述;(BaseMapper接口中还有很多其他方法,需要慢慢熟识)


(1)查询方法:第一个案例;

运行结果:


(2)查询方法:第二个案例;


(3)QueryWrapper查询构造器:组织查询条件:的一点说明;(重要!!!)

QueryWrapper查询构造器,其实就是调用QueryWrapper的方法,来组织查询条件;自然多条件查询时,可以调用多个QueryWrapper的方法

QueryWrapper查询构造器的内容还是比较多的,等到需要的时候去了解就行;


项目分析与数据库建表

说明:

(1) 本篇博客主要目的:根据项目情况,在分析后,创建数据表;

(2) 本篇博客介绍的内容虽然不难,但是【当一个新项目过来的时候,要想独立完成本篇的内容,虽然能够完成,但完成质量估计够呛】;所以,要多积累如本篇博客的这些知识,提升能力;


零:项目分析:建表前的分析;

(1)项目演示;

项目演示】介绍了项目的功能;其能够帮助理解【为什么数据表要这么设计】;

(2)项目分析;


PS:项目分析能力需要慢慢加强,以后要多看项目;尤其是结合某具体业务场景的项目;(比如,如果自己想专注于电商项目,那么就要多了解电商项目,多分析电商项目的基本情况,多总结电商项目的开发套路,多熟悉电商项目的表设计套路)


一:项目分析:建表前的分析;

1.通过项目准备的SQL文件,导入表;

2.表分析;(重点)

(1.1)book:图书表;(这是个核心表)

表结构;

具体的数据示例;


(1.2) member:会员表;(这是个核心表)

表结构;

具体的数据示例;


(1.3)evaluation:图书评价表;

表结构;

具体的数据示例;


(1.4)category:图书分类表;

表结构;

表内容;


(1.5)member_read_state:会员阅读状态表;(想看 | 看过)

表结构;

具体的数据示例;


(2)user:后台系统管理员表;

表结构;

具体的数据示例;

Bootstrap入门介绍

说明:

(1) 本篇博客的主要内容:

● 引入【项目基础资源】,【默认首页index.ftl】;

● 简单介绍了Bootstrap;

对于目前专注于后端开发来说,Bootstrap一般性掌握就行了;做到能基本能看懂前端文件,能够有效和前端开发者交流即可了;


零:引入【项目基础资源】,【默认首页index.ftl】;

1.引入项目所需的基础资源;

2.引入默认首页index.ftl;


二:Bootstrap简介;

0.引文;

但是,我们作为一个后端开发者,没必要对“如何开发前端页面”过于深究;但是,Bootstrap这个UI框架,还是有必要了解一下的;

1.Bootstrap简介;

(1) Bootstrap有Twitter开源;

(2) 响应式布局:

● 我们知道,我们可能通过PC、手机、pad等不同设备访问网页;

● 但是,PC、手机、pad这些设备不同,其屏幕尺寸也不同,即不同设备的显示区域大小也不一样;

● 为此,Bootstrap就提出了响应式布局的概念;响应式布局,可以根据屏幕的不同宽度,动态的去调整页面显示的样式;

● 即,因为整个页面的布局是随着显示设备的不同,而动态调整的:所以,就称之为响应式布局;

● 响应式布局,最常见的应用场景就是用在移动端设备上;

(3) 几乎我们能想到的常用组件,Bootstrap都有提供了对应的实现;

2.Bootstrap官网;

对于目前专注于后端开发来说,Bootstrap一般性掌握就行了;做到能基本能看懂,能够有效和前端开发者交流即可了;


注:Bootstrap和LayUI、Vue这些的关系;

也可以参考下【几种流行的前端框架(BootStrap、Layui、Element-UI、Mint UI、Angular、Vue.js、React) -幸运(● ̄(エ) ̄●) - 博客园】这篇综述性质的博客;