文章目录
查看jar包版本
https://www.mvnrepository.com/
一、SpringBoot整合Mybatis
- 1.跳过测试类打包
- - 1.1 需求说明
说明: maven执行打包命令时, 默认条件下,会执行测试类中的方法. 并且这些方法都要执行. 隐患 可能某些测试方法由于种种原因 执行报错. 则install的操作执行失败.
矛盾点: 项目打包与test类之间的问题.
解决方案: 要求install时 不要执行test方法,
- - 1.2 跳过测试类打包
<properties>
<!--指定JDK版本-->
<java.version>1.8</java.version>
<!--跳过测试类打包-->
<skipTests>true</skipTests>
</properties>
- 2.创建项目
- - 2.1 新建Maven项目
1.选择maven新建项目
2.编辑maven 坐标
3.导入pom.xml文件
<!--
定位: SpringBoot主要的作用整合SSM,使得框架的使用更加简化
原则: "开箱即用"
parent主要的作用:
1.SpringBoot在内部兼容了当下几乎所有的第三方框架
2.SpringBoot官网已经将所有兼容的版本进行了定义
(几乎解决了版本冲突问题)以后几乎不写版本号
概括: parent标签中管理其他的项目版本信息.
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/>
</parent>
<properties>
<!--指定JDK版本-->
<java.version>1.8</java.version>
<!--跳过测试类打包-->
<skipTests>true</skipTests>
</properties>
<!--按需导入
历史说明: 2010 原来SSM 需要手动的编辑大量的的配置文件
思想: SpringBoot使用体现了"开箱即用"的思想
-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<!--Springboot的启动器 在内部已经将整合的配置写好,实现拿来就用-->
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--支持热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--引入插件lombok 自动的set/get/构造方法插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<!--SpringBoot项目与Maven整合的一个插件
可以通过插件 执行项目打包/测试/文档生成等操作
注意事项: 该插件不能省略
项目发布时: java -jar xxxx.jar 报错:没有主清单信息!!!!
-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.3</version>
</plugin>
</plugins>
</build>
- - 2.2 编辑主启动类
@SpringBootApplication
public class RunAPP {
public static void main(String[] args) {
SpringApplication.run(RunAPP.class,args);
}
}
- 3.导入数据库
- - 3.1 链接数据库
- - 3.2 导入数据库
说明: 导入数据库之后,需要刷新数据库即可.
注意事项: 使用资料中提供的版本.
- 4.整合mybatis
步骤:
- 添加jar包文件依赖
- SpringBoot整合Mybatis 添加配置文件 1.连接数据库 2.SpringBoot整合Mybatis
- 创建Mapper接口
- 创建XML映射文件.
- - 4.0 序列化作用
序列化:保证了数据传输的完整性
序列号作用:一般如果需要对象进行传递时,要求POJO对象必须实现序列化接口.否则数据传输必然报错.
说明: 一般实体对象只需要添加get/set/toString等方法,无需添加构造方法.
- - 4.1 导入jar包
导入3个jar包
- mybatis包
- 数据库驱动包
- JDBC包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/>
</parent>
<properties>
<!--指定JDK版本-->
<java.version>1.8</java.version>
<!--跳过测试类打包-->
<skipTests>true</skipTests>
</properties>
<!--按需导入
历史说明: 2010 原来SSM 需要手动的编辑大量的的配置文件
思想: SpringBoot使用体现了"开箱即用"的思想
-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<!--Springboot的启动器 在内部已经将整合的配置写好,实现拿来就用-->
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--支持热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--引入插件lombok 自动的set/get/构造方法插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--引入数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--springBoot数据库连接 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--spring整合mybatis 暂时 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
</dependencies>
<!--build标签
springboot项目在打包部署发布时,需要依赖maven工具API
如果不添加该插件,则直接影响项目发布
-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.3</version>
</plugin>
</plugins>
</build>
- - 4.2 编辑YML文件
编辑 1.数据源 2.整合mybatis
#端口配置
server:
port: 8090
#配置数据源
spring:
datasource:
#如果使用高版本驱动 则添加cj
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#Spring整合Mybatis
mybatis:
#定义别名包
type-aliases-package: com.jt.pojo
#导入映射文件
mapper-locations: classpath:/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
- - - 4.2.1 在yml文件中进行 数据源的配置
#配置数据源
spring:
datasource:
#如果使用高版本驱动 则添加cj
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
数据库配置参数:
1.serverTimezone=GMT%2B8& 时区
2.useUnicode=true& 是否使用unicode编码
3.characterEncoding=utf8& 字符集使用utf-8
4.autoReconnect=true& 自动重连
5.allowMultiQueries=true 运行批量操作
- - - 4.2.2 在yml文件中 整合mybatis
#Spring整合Mybatis
mybatis:
#定义别名包
type-aliases-package: com.jt.pojo
#导入映射文件
mapper-locations: classpath:/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
- - 4.3 编辑映射文件
关键词: namespace id 标签 别名 resultType resultMap
<?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.com.jt.mapper.UserMapper">
<!-- Oracle中;号必定报错,所以以后;就不加了
resultType:
1.如果有别名包,则自动拼接 com.User
2.如果根据别名找不到,则使用默认规则
-->
<select id="findAll" resultType="User">
select * from demo_user
</select>
<!-- select 查询age < 18岁 性别 = "女"
xml文件中有特定的字符需要转移,查询文档即可
-->
<select id="findList" resultType="User">
select * from demo_user
where
age < #{age}
and
sex = #{sex}
</select>
<!--
查询: sex="男" age > 18岁
取值符号: #号 有预编译效果 能用#号不用$
自动的为参数添加一对 引号""
#号用法: #{属性/key}
-->
<select id="findWhere" resultType="User">
select * from demo_user
where
sex = #{sex}
and
age > #{age}
</select>
<!--
age < 18 or age > 100
-->
<select id="findAge" resultType="User">
select * from demo_user
where
age < #{minAge}
or
age > #{maxAge}
</select>
<!--说明: 如果只有一个参数(不是对象/map),则名称可以任意
Mybatis认为只有一个参数,不会有错.
-->
<select id="findName" resultType="User">
select * from demo_user where name = #{name}
</select>
<!--驼峰规则说明:
Mybatis 功能1:可以实现结果集于实体对象的映射!!!
对象与表 一一对应,
对象中的属性与表中的字段 一一对应。
User(userId,userName)
user表(user_id,user_name)
resultType:不能映射。
resultMap:自己是手动编辑
简化上述操作:引入驼峰规则。
思考:开启驼峰规则如下,是否可以映射?
User(user_id,user_name)
user表(user_id,user_name)
字段user_id~~userid~~userId
setId()
规则:如果开启了驼峰规则,必须按照要求编辑否则报错
-->
</mapper>
- - 4.4 编辑主启动类
关键词: mapper/dao(接口) Spring为接口创建对象
- - - 4.4.1 Spring管理Mapper接口(方式一)
说明:@Mapper注解 一般标识在接口中,如果有多个接口,则应该标识多次。
优化:可以采用 @MapperScan(“接口的路径”)进行优化.
package com.jt.mapper;
import com.jt.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper //将该接口交给Spring容器管理
public interface UserMapper {
//查询所有的user用户
List<User> findAll();
//整理方法参数
List<User> findList(Integer age,String sex);
/**
* 规则:
* 1.Mybatis 原生只支持单值传参
* 2.如果是多值,则想办法封装为单值
* 方法: 1.封装为对象
* 2.封装为Map集合<K,V> ={minAge: 18,maxAge:100}
* 补充说明: 现在mybatis版本 如果多值传参 则自动封装为Map集合
* Key:参数名称 value: 参数的值
*/
//List<User> findWhere(String name,Integer age,String sex);
List<User> findWhere(User user);
List<User> findAge(int minAge,int maxAge);
//List<User> findAge(@Param("minAge") int minAge,@Param("maxAge") int maxAge);
List<User> findName(String name);
}
- - - 4.4.2 Spring管理Mapper接口(方式二)
说明:删掉Mapper接口中的@Mapper注解,在启动类中加入@MapperScan(“com.jt.mapper”)
package com.jt;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.jt.mapper")
public class RunApp {
public static void main(String[] args) {
SpringApplication.run(RunApp.class, args);
}
}
- - 4.5 编辑测试类
package com.jt.test;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class TestMybatis {
@Autowired
private UserMapper mapper;
@Test
public void test01(){
List<User> userList = mapper.findAll();
System.out.println(userList);
}
/**
* Mybatis 参数传递说明
* 查询: sex="男" age > 18岁
*/
@Test
public void testMybatis(){
//参数使用对象进行封装
User user = new User();
user.setSex("男").setAge(18);
List<User> userList = mapper.findWhere(user);
System.out.println(userList);
}
/**
* Mybatis 参数传递说明
* 查询: age < 18 or age > 100
* 思考: 1.是否可以封装为对象?? 不可以!!
*
*/
@Test
public void testMybatis2(){
int minAge = 18;
int maxAge = 100;
List<User> userList = mapper.findAge(minAge,maxAge);
System.out.println(userList);
}
/**
* Mybatis 参数传递说明
* 查询name="王昭君"
*/
@Test
public void testMybatis3(){
String name = "王昭君";
List<User> userList = mapper.findName(name);
System.out.println(userList);
}
}
- 5.关于整合的BUG
- - 5.1 关于xml映射文件位置说明
说明: 如果xml的映射文件在根目录下(不建议), 则加载时采用classpath*😗.xml的结构.
强制加载根目录下的所有的xml文件.
- - 5.2 关于路径问题
- 6.IDEA关于Mapper注入问题
说明: 通过包扫描的路径,在运行期间实现对象的创建,实现了数据的绑定。所以下边的红线属于误报…
解决方案(一):
修改IDEA 数据校验 将√号去除即可.
解决方案(二):
如果是最新版本的IDEA 则修改如下的选项
二、MybatisPlus学习
- 1.ORM思想
对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。如今已有很多免费和付费的ORM产品,而有些程序员更倾向于创建自己的ORM工具。
宗旨: 以面向对象的方式操作数据库。
1.要求查询的结果集可以自动的封装为对象 (读)
2.利用对象封装数据,之后(自动)动态的生成SQL语句执行相关操作. (更新)
知识升华:
- 以对象的方式实现数据库CRUD操作.
- 要求通过某种机制将对象动态的转化为SQL,之后实现数据库操作。(自己不写SQL)
- 2.Mybatis优点/缺点
SpringBoot整合Mybatis流程
1.导入依赖jar包 数据库驱动、JDBC包、Spring整合Mybatis包
2.编辑application.yml文件 配置数据源、配置Spring整合Mybatis
3.编辑Mybatis 接口文件、编辑xxx.xml映射文件
4.通过@MapperScan为接口创建代理对象.
优点:
1.Mybatis 内部整合了JDBC, 简化了持久层开发.
2.Mybatis可以自动的封装结果集的对象 满足ORM中的一个条件.所以将Mybatis称之为半自动化的ORM映射框架.
3.Mybatis有缓存机制 一级缓存/二级缓存.提高用户得查询效率.
4.Mybatis支持多种类型的数据库. 整合简单.
缺点:
1.实现数据的封装 resultMap 封装复杂!!!
2.针对于单表的CRUD的操作 不够便捷. Sql都需要手写!!!
3.个别的情况下二级缓存配置不生效!!!
- 3.MybatisPlus介绍
- - 3.1什么是MP
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性:
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
- 4.MP入门案例
核心思想: 利用对象操作数据库 单表查询几乎不写SQL
- - 4.1 在pom.xml文件中 导入jar包
说明:MybatisPlus对Mybatis的增强(包含),所有jar包只需要导入MP的即可.原有的Mybatis需要删除.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jt</groupId>
<artifactId>springboot_demo3</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<!-- 指定jdk版本 -->
<java.version>1.8</java.version>
<!-- 跳过测试类打包 -->
<skipTests>true</skipTests>
</properties>
<!--按需导入:
历史说明:2010 原来SSM 需要手动的编辑大量的配置的文件
思想:SpringBoot使用体现了“开箱即用”的思想
-->
<dependencies>
<!--添加web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<!--springboot启动项(器)在包的内部SpringBoot
已经完成了项目的"整合"(配置) 用户拿来就用
web导入SpringMVC
-->
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加测试类支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--添加属性注入依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--引入插件lombok 自动的set/get/构造方法插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--支持热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--引入数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--springBoot数据库连接 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--spring整合mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- - 4.2 在pojo包中的实体类User.java里 使用注解实现映射
关键词:对象 表 属性 字段 一一映射
对象关系映射:
1.User对象需要与demo_user表绑定
2.User对象中的属性与表中的字段一一对应
package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
//1.将对象与表进行关联
//规则1:如果表明与对象名一致,则名称可以省略
//规则2:如果字段名与属性名一致,则注解可以省略
@TableName("demo_user")
//序列化接口的作用:保证对象网络传输的有效性!!!
public class User implements Serializable {
//2.主键 --- 主键自增[AUTO]、非空、UUID[ASSIGN_UUID](生成唯一编号)
@TableId(type = IdType.AUTO) //主键的意思
private Integer id;
//3.标识属性与字段的映射
// @TableField("name")
private String name;
private Integer age;
private String sex;
}
- - 4.3 在mapper包中的接口UserMapper.java里 继承特定的接口BaseMapper
关键字:封装 — 多态 — 继承
说明:MP在内部准备了一个BaseMapper的接口BaseMapper内部几乎将单表的CRUD操作都进行了编辑,用户自己的Mapper
package com.jt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 1.规则1:继承BaseMapper时,必须添加泛型对象,否则映射表报错
* 2.规则2:自己的方法不要与接口方法重名
*/
public interface UserMapper extends BaseMapper<User> {
//MP规则:以对象的方式操作数据库,CURD操作
//查询所有的user用户
List<User> findAll();
}
- - 4.4 编辑xml映射文件 UserMapper.xml(如果自己不需要写SQL语句,则不需要创建)
<?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.jt.mapper.UserMapper">
<!-- Oracle中;号必定报错,所以以后;就不加了
resultType:
1.如果有别名包,则自动拼接 com.User
2.如果根据别名找不到,则使用默认规则
-->
<select id="findAll" resultType="User">
select * from demo_user
</select>
<!-- select 查询age < 18岁 性别 = "女"
xml文件中有特定的字符需要转移,查询文档即可
-->
<select id="findList" resultType="User">
select * from demo_user
where
age < #{age}
and
sex = #{sex}
</select>
<!--驼峰规则说明:
Mybatis 功能1:可以实现结果集于实体对象的映射!!!
对象与表 一一对应,
对象中的属性与表中的字段 一一对应。
User(userId,userName)
user表(user_id,user_name)
resultType:不能映射。
resultMap:自己是手动编辑
简化上述操作:引入驼峰规则。
思考:开启驼峰规则如下,是否可以映射?
User(user_id,user_name)
user表(user_id,user_name)
字段user_id~~userid~~userId
setId()
规则:如果开启了驼峰规则,必须按照要求编辑否则报错
-->
</mapper>
- - 4.5 编辑yml文件 application.yml
说明:将mybatis改成mybatis-plus
# 端口配置
Server:
port: 8090
#配置数据源
spring:
datasource:
#如果使用高版本驱动 则添加cj
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#Spring整合MP
mybatis-plus:
#定义别名包
type-aliases-package: com.jt.pojo
#导入映射文件
mapper-locations: classpath:/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
#为com.jt.mapper包下的SQL执行打印日志
logging:
level:
com.jt.mapper: debug
- - 4.6 测试类 TestMP .java
package com.jt.test;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@SpringBootTest
public class TestMP {
@Autowired
private UserMapper mapper;
//MP底层原理
// insert into 表名 (字段名...) value (属性值...);
// @Test
// public void test(){
// // 获取user的类型
// Class<? extends User> userClass = user.getClass();
// // 通过反射获取User类里的@TableName("demo_user")注解
// TableName tablename = userClass.getAnnotation(TableName.class);
// // 获取表名
// String name = tablename.value();
// // 获取字段名
// Field[] fieldsname = userClass.getFields();
// //获取属性值 -- 用get方法
// }
/**
* 0.完成数据的入库操作
* 新增user数据(name="张三",age=23,sex="男")
* SQL:insert into demo_user values(xxx,xxx,xxx)
*/
@Test
public void insert(){
User user = new User();
user.setName("张三").setAge(23).setSex("男");
//以对象的方式操作数据!!!
mapper.insert(user);
System.out.println("入库操作成功");
}
/**
* 1.根据Id查询数据库 id= 231
*/
@Test
public void selectById(){
int id = 231;
User user = mapper.selectById(id);//模拟用户参数
System.out.println(user);
System.out.println("查询成功");
}
/**
* 2.查询 name = "小乔" 并且 性别 = "女"
* 思路:如果将来有多个结果,则使用List参数进行接收
* SQL:where name = "xx" and sex = "xx"
* 注意事项:默认的连接符是 and
*/
@Test
public void select01(){
//1.通过对象封装数据
User user = new User();
user.setName("小乔").setSex("女");
//2.构建条件构造器 根据对象中不为null的属性充当where条件!
QueryWrapper<User> queryWrapper = new QueryWrapper(user);
//3.根据条件构造器 实现数据查询
List<User> userList = mapper.selectList(queryWrapper);//Wrapper<T> queryWrapper 条件构造器
System.out.println(userList);
System.out.println("查询成功");
}
/**
* 3.查询 name="小乔" 并且 性别 ="女"
* 逻辑运算符: = eq, > gt, < lt
* >= ge, <= le
* != ne
*/
@Test
public void select02(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name","小乔")
.eq("sex","女");
List<User> userList = mapper.selectList(queryWrapper);
System.out.println(userList);
}
/**
* 4.案例: select 查询age < 18岁 性别="女"
* 方式1: 利用mybatis方式实现
* 方式2: 利用MP方式实现
*/
@Test
public void select03(){
//1.mybatis 写法
List<User> userList = mapper.findList(18,"女");
System.out.println(userList);
//2.MP写法
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.lt("age", 18)
.eq("sex", "女");
List<User> userList2 = mapper.selectList(queryWrapper);
System.out.println(userList2);
}
/**
* 5.select 查询 name包含 '君'字的数据
* 关键字: like "%xxx%"
* 以君字开头:likeRight "君%"
* 以君字结尾:likeLeft "%君"
*/
@Test
public void select04(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "君");
List<User> userList = mapper.selectList(queryWrapper);
System.out.println(userList);
QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
queryWrapper1.likeRight("name", "君");
List<User> userList2 = mapper.selectList(queryWrapper1);
System.out.println(userList2);
QueryWrapper<User> queryWrapper2 = new QueryWrapper<>();
queryWrapper2.likeLeft("name", "君");
List<User> userList3 = mapper.selectList(queryWrapper2);
System.out.println(userList3);
}
/**
* 6.select 查询 sex = "女" 按照年龄倒序排序
*/
@Test
public void select05(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("sex", "女")
.orderByDesc("age");
List<User> userList = mapper.selectList(queryWrapper);
System.out.println(userList);
}
/**
* 7.需求:动态SQL查询:如果有值,则拼接where条件
* 如果数据为null,则不拼接where条件
*
* 语法:condition:true 则拼接条件where条件
* false 则不拼接where条件
*/
@Test
public void select06(){
String name = "貂蝉";
int age = 18;
boolean nameFlag = name == null ? false : true;
boolean ageFlag = age == 0 ? false : true;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(nameFlag,"name", name)
.eq(ageFlag, "age", age);
List<User> userList = mapper.selectList(queryWrapper);
System.out.println(userList);
}
/**
* 8.批量查询 查询id = 1,4,5,6...的数据
* 有两种写法
*/
@Test
public void selectIn(){
//1.传统的in方法
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", 1,4,5,6);
List<User> userList = mapper.selectList(queryWrapper);
System.out.println(userList);
//2.特有的方法
//数组在未来有用户负责传递。
Integer[] array = new Integer[]{1,4,5,6};
//数组转List集合??
List<Integer> ids = Arrays.asList(array);
List<User> userList1 = mapper.selectBatchIds(ids);
System.out.println(userList1);
}
/**
* 9.查询性别为男的用户ID
* selectObjs(); 只查询第一个字段(主键)
* 实际用途:根据业务只需要主键的查询
*/
@Test
public void selectObjs(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("sex", "男");
List<Object> ids = mapper.selectObjs(queryWrapper);
System.out.println(ids);
}
/**
* 10.将ID = 232 的数据 name 改为 "皮皮虾"
* SQL:update demo_user set name = "皮皮虾" where id = 232
*/
@Test
public void update(){
User user = new User();
user.setId(232).setName("皮皮虾");
//buId 表示ID只当作where条件
//其他不为null的属性 当作set条件
mapper.updateById(user);
System.out.println("修改成功");
}
/**
* 11.将name = "泡泡老师" 改为 name = "泡泡" age = 25 sex = "男"
* .update(arg1,arg2)
* arg1:实体对象 set条件的数据
* arg2:updateWrapper 动态拼接where条件
*/
@Test
public void update01(){
User user = new User();
user.setName("泡泡").setAge(25).setSex("男");
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "泡泡老师");
mapper.update(user,updateWrapper);
System.out.println("更新成功");
}
}
- - - 4.6.1 MP中关于查询总结
MP核心:以对象的方式操作数据库
条件构造器:new QueryWrapper<>(); 动态拼接where条件。
拼接规则:根据对象中不为null的属性充当where条件。
特殊转义字符:= --> eq、> --> gt、 < --> lt、 >= --> ge 、<= --> le 、!= --> ne
xml文件中的万能的转义字符:<![CDATA[ sql语句]]>
关键字:like 、order by ...
动态SQL语法:
condition:true 拼接where条件
false 不拼接where条件
- 5.MP操作原理
问题:用户操作对象,如何实现数据库操作!!!
分析问题:对象如何转化为SQL?
- - 5.1 核心理论
例子:mapper.insert(user);
mapper.insert(dog);
SQL:
1.insert into 表名(字段名称...) value(属性的值...);
总结:MP将常规的操作进行抽取,采取公共的接口进行定义,之后只需要按照用户的参数动态的拼接SQL即可
- - 5.2 MP理论流程
重点: 对java反射机制 有一定的了解
- mapper.insert(user); 用户调用接口方法,完成业务。
- 根据用户传递的对象,通过user.getClass() – 获取的是类型。Class userClass = user.getClass();
- 根据class类型,通过反射动态获取User类中指定的@TableName(“demo_user”)注解; TableName tableName = (TableName)
userClass.getAnnotation(TableName.class); - 获取表名 String 表名 = tableName.value();
- 根据User的类型可以获取User类中属性的名称,根据属性名称,可以获取User类属性前的@TableField(“name”)注解,最终获取字段的名称。
- 拼接SQL: insert into demo_user(id,age,name,sex) value (user.getId()…)
- 最终将SQL由MP交给Mybatis执行SQL,最终实现数据的入库操作。
三、前后端交互
- 1.框架之间的关系
1.SpringBoot (工具/框架的框架) 2.Spring(整合第三方)
3.SpringMVC(实现前后端交互) 4.Mybatis/MP(实现持久化操作)
- 2.完成后端层级代码
说明: MVC思想主要的目的实现代码的解耦. 根据MVC思想 演化出层级代码结构 Controller/Service /Dao/Mapper
编码顺序:
1.编辑POJO
2.编辑Mapper接口
3.编辑Service层
4.编辑Controller
- 3.查询案例
- - 1.业务需求
用户浏览器输入地址: http://localhost:8090/findAll,
要求: 利用MP查询数据库,返回集合的JSON数据.
- - 2.编辑UserController
package com.jt.controller;
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController // 获取请求+响应json数据
//@Controller // 和上面的@RestController注解基本无差别,唯一少了一个@ResponseBody注解
//@ResponseBody // 将服务端数据转换给JSON串返回
public class UserController {
@Autowired
//编码规则:面向接口编程 解耦
private UserService userService;
/**
* 查询所有的数据
* URL: http://localhost:8090/findAll
* 参数:没有参数
* 返回值:List<User>
*/
@RequestMapping("findAll")
public List<User> findAll(){
return userService.findAll();
}
}
- - 3.编辑UserServiceImpl
package com.jt.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper userMapper;
//查询所有数据,没有where条件的查询全部数据
@Override
public List<User> findAll() {
return userMapper.selectList(null);
}
}