IDEA 使用Spring Boot 超快速搭建 SSM (进阶版)
IDEA 使用Spring Boot 超快速搭建 SSM (进阶版)
author:Cris
文章目录
零、序
不管你是编程做Coding,还是做编辑码字,你的每一行代码或者你文章的每句话,都应该像写诗一样。只有这样的程序员和编辑,才能最终成就自己
温馨提示:本篇笔记跟随上一篇 《IDEA 使用Spring Boot 超快速搭建 SSM (完整版)》
,基础环境以及场景介绍都已经在上篇笔记中详细说明,此次进阶篇的目的还是为了提高开发效率,主要是集中在 Dao
层,我们使用了 Mybatis的通用插件
以及 PageHelper分页插件
,笔者在搭建过程中遇到的问题以及细节详细记录如下,感兴趣的同学可以关注一下?以及参考一下
该项目完整代码请参考:https://github.com/zc-cris/SpringBoot_SSM
一、环境修改
首先,需要对上一篇笔记做出一点改正
上篇笔记中,笔者曾经在 Spring Boot
应用的启动类 DemoApplication
设置了 Mapper 接口扫描注解@MapperScan(basePackages = "com.cris.dao")
后,还在 Mapper 接口上
加入了 @Mapper
注解,虽然对最后的测试没有影响,但是本着 准确
以及 能少些绝不多写
的原则,在这里笔者还是修改如下:
1.1、关于插件
因为项目使用 Mybatis
来实现数据访问层,为了提高开发的效率,上篇笔记给大家介绍了 IDEA
开发插件 MybatisCodeHelperPro
,这一次主要是介绍单表操作的神级插件 Mybatis通用插件
以及分页插件 PageHelper
。
在平时的开发中,我们的大部分精力都是放在了业务层上,对于数据访问层的开发应该尽量简洁,高效。毕竟重复性的劳动就交给那些大牛们提供的插件就好?,除非是项目在后期遇到了瓶颈,需要优化,那个时候就可以从数据访问层入手,并且由于使用的是 Mybatis
这种半自动 ORM
框架,SQL
优化起来也是比较容易。
还是那句话,一切可以提高开发效率的工具我们都应该尽量熟悉乃至掌握,只有这样,才不会重复造轮子,才不会天天熬夜加班?
最后给出这两个插件的链接,感兴趣的同学建议看看,还是我们中国的开发者开发的?
1.2、数据库数据
这里简单起见,我们就新建两张最常见的 emps
表和 depts
表,值得一提的是,这两张表的创建和修改都是依托于 IDEA
的 Database
模块
depts
emps
这里并不建议在 emps
表插入 depts
的 id
作为约束。原因参见 总结
1.3、配置文件修改
先来看 pom.xml 文件,导入插件的启动器 starter
再看看 application.yml
文件
二、开始编码
2.1、entity
先来看看 Dept
再来看看 Emp
/**
* 员工表对应的实体
*
* @author zc-cris
* @version 1.0
**/
@Table(name = "emps")
@SuppressWarnings("unused")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Emp {
@Id
private Integer id;
private String name;
private Integer deptId;
private String countryName;
}
关于实体类的属性,一定要设置成 引用数据类型!!!
,否则获取出来的数据无法正确装配到实体类上,
根据阿里代码规约,实体类的属性需要统一使用引用数据类型,主要是为了防止基本数据类型的默认值造成干扰。
举个例子:一个同学因故没有参加考试,那么这趟考试是应该给他计 0
分还是设置为 null
呢?
简而言之:null
可以表示不存在,可以表示错误,但是 0
只能表示一个客观存在的数据
2.2、mapper
DeptMapper
EmpMapper
注意:以前版本的 通用mapper
,直接写我们的业务 mapper
接口继承自插件的 Mapper
接口即可,但是新版本需要一个我们自己的本地 Mapper
接口
本地 Mapper 接口如下
这个本地 Mapper
接口必须在 application.yml
文件中进行配置?,如 1.3节所示
2.3、配置类
接下来这一步非常简单,但是很关键,我们需要在应用的启动类上,将之前的 @MapperScan
注解由 Mybatis
官方提供的更换为 通用 Mapper 插件
提供的,否则会报错!
三、开始测试把~
具体的测试代码如下:
@SpringBootTest
@RunWith(SpringRunner.class)
public class EmpMapperTest {
@Autowired
EmpMapper empMapper;
/**
* 根据主键查询单条数据
*/
@Test
public void testSelectOne() {
Emp emp = empMapper.selectByPrimaryKey(1);
System.out.println("emp = " + emp);
}
/**
* 查询所有员工
*/
@Test
public void testSelectAll() {
List<Emp> emps = empMapper.selectAll();
emps.forEach(System.out::println);
}
/**
* 分页查询(借助pageHelper 插件)
*/
@Test
public void testSelectAllPage() {
// 查询第一页的两条数据
PageHelper.startPage(1, 2);
List<Emp> emps = empMapper.selectAll();
emps.forEach(System.out::println);
}
/**
* 测试保存一条数据(这里没有选择自增主键)
*/
@Test
public void testSave() {
empMapper.insert(new Emp(5, "麻花腾", 1002, "日本"));
}
/**
* 有选择性的保存数据(null值不保存到数据库,前提是数据库允许该列为空)
*/
@Test
public void testInsertSelective() {
empMapper.insertSelective(new Emp(6, "麻生希", 1001, null));
}
/**
* 有选择性的更新数据,根据id更新数据,如果为null的属性就不更新对应的列,效率更高
*/
@Test
public void testUpdateSelective() {
empMapper.updateByPrimaryKeySelective(new Emp(6, null, null, "台湾"));
}
/**
* 根据主键删除数据
*/
@Test
public void testDeleteById() {
empMapper.deleteByPrimaryKey(5);
}
/**
* 搭配使用mapper 文件来完成复杂的sql crud,当然也可以使用
* 通用mapper 插件为我们提供的 QBC 查询,个人建议使用手写sql 语句的形式
* 因为可以自己优化sql 语句的执行效率
* 同时也可以发现通用mapper插件是支持调用接口继承方法和mapper文件的sql语句的
*/
@Test
public void testDynamicSql() {
List<Emp> byCountryName = empMapper.getByCountryName(Arrays.asList("中国", "德国"));
byCountryName.forEach(System.out::println);
}
}
值得一提的是,在最后一个测试动态 sql
的方法,我们使用了 mapper
文件映射的方式,mapper
文件映射如下
<?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.cris.dao.EmpMapper">
<select id="getByCountryName" resultType="com.cris.entity.Emp">
select
id,
name,
dept_id,
country_name
from sql_primary_study.emps
<foreach collection="countryNames" item="countryName" open="where country_name in (" close=")" separator=",">
#{countryName}
</foreach>
</select>
</mapper>
之所以使用 mapper映射文件
的方式,一来是证明 通用mapper
支持两种方式(注解和文件)来开发 Mapper
,还有就是可以使用 Mapper 映射文件
的方式来代替 通用Mapper
提供的 QBC
复杂查询(书写更加容易,也更加容易优化 sql
),最后再练习练习 Mybatis
的 Dynamic sql
特性
四、总结
项目特点:
- 使用
通用 Mapper
和PageHelper
插件大大提高数据访问层的开发效率通用Mapper
插件使用两种方式来开发Mapper 接口
,其中映射文件的方式可以有效代替QBC查询
注意点:
- 实体类属性一定要是引用数据类型
- 实体类和实体类之间尽量不要
耦合
,即少写以前那种在一个实体类里面引用其他实体类的写法(例如:在Emp
中持有Dept
的引用),换种写法,将Emp
中的Dept
引用更换为deptId
(等同于Dept
的id
)会不会更好?尽量让类和类之间的引用关系简单明了,避免不必要的互相引用以及缕清类和类之间的联系是迈向高级码农的基本常识。包括从数据库的设计,表和表之间的关系能不用外键就别用,否则会给后期的维护和优化带来极大的麻烦(本例中:emps
表的dept_id
并没有引用deps
表的id
,将这种数据关联引入到业务中去,而不是让数据库来管理 )- 新版本的
通用mapper
插件引入了一个本地Mapper接口
需要自定义- 启动类的
@MapperScan
注解需要更换为通用mapper
插件提供的Mybatis
的动态sql
特性非常有利于复杂sql
的书写通用mapper
的批量操作很简单,查看MySqlMapper<T>
的源代码即可