Spring 全家桶系列一一 SpringBoot 与 Mybatis 结合
本文授权 "Java 知音" 独家发布.
Mybatis 是一个持久层 ORM 框架, 负责 Java 与数据库数据交互, 也可以简易理解为中介, 相对于它, 还有个中介是 hibernate, 不过在 mybatis 中 sql 语句的灵活性, 可优化性比较强, 这也是现在大多数人选择的原因.
1. mapper.xml,dao 接口, 实体类自动生成
下载 https://pan.baidu.com/s/1JY7Xduk5E3KPm58AjnueuQ 工具包
1.1 修改配置文件 generator.xml
解压之后, 这里把文件拷贝到了 C:\resources\generator 文件夹下, 以下称为 "当前文件目录"
一次配置, 终身受益
generator.xml
<?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
- <generatorConfiguration>
- <!-- 数据库驱动包位置 也就是刚解压的文件的位置加上 mysql-connector-java-5.1.34.jar-->
- <classPathEntry location="C:\resources\generator\mysql-connector-java-5.1.34.jar" />
- <!-- 这里也适用 Oracle 数据库的自动生成 -->
- <!-- <classPathEntry location="C:\resources\generator\ojdbc6.jar" /> -->
- <context id="DB2Tables" targetRuntime="MyBatis3">
- <commentGenerator>
- <!-- 去除生成日期 -->
- <property name="suppressDate" value="true"/>
- <!-- 去除所有的注解 -->
- <property name="suppressAllComments" value="true"/>
- </commentGenerator>
- <!-- 数据库链接 URL, 用户名, 密码 -->
- <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/ceilan" userId="root" password="123456">
- <!-- <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@localhost:1521:orcl" userId="scott" password="tiger">-->
- </jdbcConnection>
- <!--java 类型处理器 -->
- <javaTypeResolver>
- <property name="forceBigDecimals" value="false" />
- </javaTypeResolver>
- <!-- 生成模型的包名和位置 -->
- <javaModelGenerator targetPackage="com.example.entity" targetProject="C:\resources\generator\src">
- <property name="enableSubPackages" value="true" />
- <property name="trimStrings" value="true" />
- </javaModelGenerator>
- <!-- 生成的映射文件包名和位置 -->
- <sqlMapGenerator targetPackage="mapping" targetProject="C:\resources\generator\src">
- <property name="enableSubPackages" value="true" />
- </sqlMapGenerator>
- <!-- 生成 DAO 的包名和位置 -->
- <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.dao" targetProject="C:\resources\generator\src">
- <property name="enableSubPackages" value="true" />
- </javaClientGenerator>
- <!-- 要生成哪个表, 更改 tableName(数据库里表名)和 domainObjectName(实体名, 一般首字母大写)就可以 -->
- <table tableName="area" domainObjectName="Area" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
- </context>
- </generatorConfiguration>
1.2 用 Java 运行自动生成
在当前目录下打开 cmd 命令, 运行如下
注 : Windows 系统可直接执行 [ 生成. bat ] 批处理文件
java -jar mybatis-generator-core-1.3.2.jar -configfile generator.xml -overwrite
然后把当前目录 src 下的 com 文件夹拷贝到项目文件夹下
把 mapping 文件拷贝到 resources 文件夹下
目录结构如上
2. 集成 Mybatis 框架
2.1 引入依赖
- compile "mysql:mysql-connector-java:5.1.39"
- compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.2.0'
2.2 启动类 DemoApplication.java 增加扫描配置
- package com.example;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.web.bind.annotation.RequestMapping;
- @SpringBootApplication
- // mapper 接口 扫描包配置
- @MapperScan(value = "com.example.dao")
- public class DemoApplication {
- public static void main(String[] args) {
- SpringApplication.run(DemoApplication.class, args);
- }
- }
2.3 添加项目首页 index.html
在 resources 的 templates 文件中新建 index.HTML
index.HTML
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Title
- </title>
- </head>
- <body>
- <h1>
- Welcome SpringBoot
- </h1>
- </body>
- </HTML>
然后在 DemoApplication 启动类中添加
- // 欢迎页面 首页
- @RequestMapping("/")
- public String index(){
- return "index";
- }
之前已经在 application.YAML 中配置了资源映射设置, 如下
- spring:
- mvc:
- view:
suffix: .HTML
- resources:
- static-locations: classpath:/templates
所以现在的项目启动访问 http://localhost:8080/ 是可以直接访问到首页的
3. 添加业务层和控制层实现 CRUD(增删改查)
增加业务逻辑层包 service 以及在其下增加 impl 包用来实现其接口
3.1 业务逻辑层接口 AreaService.java
- package com.example.service;
- import com.example.entity.Area;
- /**
- * 这里给 dao 层的代码拷贝过来先使用
- * created by cfa 2018-11-08 下午 9:56
- **/
- public interface AreaService {
- int deleteByPrimaryKey(Integer id);
- int insert(Area record);
- int insertSelective(Area record);
- Area selectByPrimaryKey(Integer id);
- int updateByPrimaryKeySelective(Area record);
- int updateByPrimaryKey(Area record);
- }
3.2 业务层实现类 AreaServiceImpl.java
- package com.example.service.impl;
- import com.example.dao.AreaMapper;
- import com.example.entity.Area;
- import com.example.service.AreaService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import java.io.Serializable;
- /**
- * 这里的 @Service 注解相当于自动注册到 Spring 的 Bean
- * 相当于原来的 Application.xml 里的 <bean id="areaServiceImpl" class="com.example.service.impl.AreaServiceImpl"/>
- * created by cfa 2018-11-08 下午 9:58
- **/
- @Service
- public class AreaServiceImpl implements AreaService, Serializable {
- private final AreaMapper areaMapper;
- @Autowired
- public AreaServiceImpl(AreaMapper areaMapper) {
- this.areaMapper = areaMapper;
- }
- @Override
- public int deleteByPrimaryKey(Integer id) {
- return areaMapper.deleteByPrimaryKey(id);
- }
- @Override
- public int insert(Area record) {
- return areaMapper.insert(record);
- }
- @Override
- public int insertSelective(Area record) {
- return areaMapper.insertSelective(record);
- }
- @Override
- public Area selectByPrimaryKey(Integer id) {
- return areaMapper.selectByPrimaryKey(id);
- }
- @Override
- public int updateByPrimaryKeySelective(Area record) {
- return areaMapper.updateByPrimaryKeySelective(record);
- }
- @Override
- public int updateByPrimaryKey(Area record) {
- return areaMapper.updateByPrimaryKey(record);
- }
- }
3.3 控制层的 AreaController.java
- package com.example.controller;
- import com.example.entity.Area;
- import com.example.service.AreaService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.Web.bind.annotation.RequestMapping;
- import org.springframework.Web.bind.annotation.RestController;
- @RestController
- @RequestMapping("area")
- public class AreaController {
- private final AreaService areaService;
- @Autowired
- public AreaController(AreaService areaService) {
- this.areaService = areaService;
- }
- @RequestMapping("query")
- public Area areaList(){
- return areaService.selectByPrimaryKey(1);
- }
- }
看到这里, 想必看到很多次 @Autowired,@Service 等注解了, 这就是 Spring 的两大核心之一的 IoC(Inversion of Control), 也就是 DI 依赖注入;
Spring 的两大核心 AOP 和 IoC 大家面试的时候也基本都有问到, 到这里你 IoC 就不用头疼了;
在 Spring 之前我们写代码, 用到某个类, 我们都需要去 new 一下, 现在有个叫 Spring, 我把控制权交给它, OK, 然后在给业务层盖上章(加注解), 然后让这个叫 Spring 的家伙开始工作的时候, 交给他去做, 控制层需要逻辑 A,OK, 之前我们已经在控制层用 DI 注入了 A,Spring 就会把 A 的调用给控制层, 下面说松紧耦合度, Spring 之前, 到处写的都是 new 新建对象, 修改一个类很难, 现在随意修改, 只需要盖个章(DI), 让 Spring 去管就可以了, 你现在要问我原理, 那些文邹邹的, 后续在研究研究, 原理相当于文言文, 只有研究透了, 才能用大家都理解的话写出来.
业务层提供的接口加实现类就是为了实现松耦合, 不然一个类就解决了, 就像一个手机, 坏了, 里面的电池, 屏幕, 主板什么的拆下来还能用, 这就是松耦合.
4. 热部署插件
问题 1: 开发人员每次修改了一个 java 文件就需要重启 tomcat, 开发效率很低是不?
答: Jrebel 热部署插件解决你的问题 https://mp.weixin.qq.com/s/4Gu5xWWnqtXAoXYDLVmXMA
问题 2: 你为什么不选择 springboot 自带的热部署插件
答: 和之前的朋友问我的一样, 问我为啥不把生成代码的插件放在项目中, 一个项目还好, 你要是写了多个项目, 一个一个去部署, 麻烦不, 所以一次配置, 一劳永逸.
5. 关于 AOP--Spring 的又一大核心
面向切面编程 (AOP 是 Aspect Oriented Program 的首字母缩写) 我们知道, 面向对象的特点是继承, 多态和封装. 而封装就要求将功能分散到不同的对象中去, 这在软件设计中往往称为职责分配. 实际上也就是说, 让不同的类设计不同的方法. 这样代码就分散到一个个的类中去了. 这样做的好处是降低了代码的复杂程度, 使类可重用. 但是人们也发现, 在分散代码的同时, 也增加了代码的重复性. 什么意思呢? 比如说, 我们在两个类中, 可能都需要在每个方法中做日志. 按面向对象的设计方法, 我们就必须在两个类的方法中都加入日志的内容. 也许他们是完全相同的, 但就是因为面向对象的设计让类与类之间无法联系, 而不能将这些重复的代码统一起来.
也许有人会说, 那好办啊, 我们可以将这段代码写在一个独立的类独立的方法里, 然后再在这两个类中调用. 但是, 这样一来, 这两个类跟我们上面提到的独立的类就有耦合了, 它的改变会影响这两个类. 那么, 有没有什么办法, 能让我们在需要的时候, 随意地加入代码呢? 这种在运行时, 动态地将代码切入到类的指定方法, 指定位置上的编程思想就是面向切面的编程.
一般而言, 我们管切入到指定类指定方法的代码片段称为切面, 而切入到哪些类, 哪些方法则叫切入点. 有了 AOP, 我们就可以把几个类共有的代码, 抽取到一个切片中, 等到需要时再切入对象中去, 从而改变其原有的行为.
这样看来, AOP 其实只是 OOP 的补充而已. OOP 从横向上区分出一个个的类来, 而 AOP 则从纵向上向对象中加入特定的代码. 有了 AOP,OOP 变得立体了. 如果加上时间维度, AOP 使 OOP 由原来的二维变为三维了, 由平面变成立体了. 从技术上来说, AOP 基本上是通过代理机制实现的.
AOP 在编程历史上可以说是里程碑式的, 对 OOP 编程是一种十分有益的补充
引自: http://xiaobashagua.iteye.com/blog/1963683 你问我为啥排这么紧, 哈哈, 好东西是留给有耐心的人看的, 如果你把这篇文章的 IoC 和 AOP 仔细看了, 你会对这俩的理解又深了一个层次
5. 小叙
本文代码已上传 GitHub:https://github.com/cuifuan/springboot-demo
如果你是来学框架怎么写 CRUD 的, 我错了, 没让你看到具体的, 我在写的是在写代码的时候, 对插件工具的使用, 和了解这些东西的作用, 提高开发效率, 并且知道自己用的是什么以及基本原理, 而不是仅仅是一个 "码农", 谢谢阅览.
来源: https://www.cnblogs.com/cvandy/p/10283440.html