整合单元测试与日志
说明:
(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) -幸运(● ̄(エ) ̄●) - 博客园】这篇综述性质的博客;