ORM思想
对象关系映射ORM,是一种程序设计技术,用于面向对象编程语言里不同类型的系统的数据之间的转换
总结:以面向对象的方式,操作数据库
知识升华:
以对象的方式实现数据库CRUD操作
要求通过某种机制将对象动态的转化为SQL,实现数据库操作(自己不写sql)
mybatis优点和缺点
优点:
1.mybatis内部整合了JDBC,简化了持久层开发
2.mybatis可以自动封装结果集的对象,满足ORM中任何一个条件,所以将Mybatis称之为半自动化的ORM映射框架。
3.mybatis有缓存机制,一级缓存/二级缓存,提高查询效率
4.mybatis支持多种类型的数据库。整合简单
缺点:
1.实现数据的封装 resultMap封装复杂
2.针对单表的CRUD操作,不够便捷,SQL需要手写
3.个别情况下二级缓存不生效
mybatis-plus
是一个mybatis的增强工具,在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 操作智能分析阻断,也可自定义拦截规则,预防误操作
导入jar包
<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-plus 删除mybatis的包 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
</dependencies>
实现映射 继承内置SQL的BaseMapper接口
关键词: 对象 表 属性 字段 一一映射
规则:
1.对象名称与表的名称一一对应.
2.对象的属性与表中的字段一一对应.
1.表名与对象名:
@TableName("demo_user") //注解
public class User implements Serializable{}//固定写法 //创建对象
如果表名与类中的名一致,则注解中的表名可省略不写
2.主键自增/非空/UUID( UUID生成唯一编号)
@TableId(type = IdType.AUTO,value = "id")
private Integer id;
3.标识属性与字段的映射
规则,对项名与属性名如果一直,则注解可以省略不写。
//标签名user_id
private Integer userId;
驼峰规则自动转换为userId,可以不写注解
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.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.stereotype.Component;
import java.io.Serializable;
//lombok注解,自动实现get,set,toString等方法
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@Component
//序列化作用,保证对象网络传输的有效性!!!!
//1.将对象与表进行关联
//规则,1.如果表名与类中的名一致,则注解中的表名可省略不写
// 2.对项名与属性名如果一直,则注解可以省略不写
@TableName("demo_user")
public class User implements Serializable{//固定写法
//2.主键自增/非空/UUID
//UUID生成唯一编号
@TableId(type = IdType.AUTO,value = "id")
private Integer id;
//3.标识属性与字段的映射
//@TableField("name")
private String name;
private Integer age;
private String sex;
}
YML文件的改变
说明: 将mybatis 修改为mybatis-plus
mabatis是一个特殊文件,格式(k,v)非常严格,一般不会手敲,直接复制即可
#是一个特殊的文件,特殊在这个文件将被springboot框架自动加载-开箱即用
#格式非常严格,k: v
#端口配置
server:
port: 8090
#配置数据源
#SpringBoot配置mysql信息
spring:
datasource:
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
#SpringBoot整合Mybatis配置
mybatis-plus:
#定义别名包
type-aliases-package: com.jt.pojo
#指定UserMapper.xml文件的位置
#地址位置要填入相对对应地址
mapper-locations: classpath:/mappers/*.xml
#mapper-locations: classpath*:/*.xml 强制扫描外面的包的配置文件
#开启驼峰映射
#mybatis 功能1:可以实现结果集和实体对象的映射
#对象与表一一对应
#对象中的属性对象与表中的字段 一一对应
#User(userId,userName)
#User表(user_id,user_name)
#resulttype:不能映射
#resultMap金可以映射
#简化上述操作引入驼峰规则
#思考,开启驼峰规则如下是否可以映射?
#User(user_id,user_name)
#ser表(user_id,user_name)
configuration:
map-underscore-to-camel-case: true
logging: #日志
level: #等级
com.jt.mapper: debug #为com.jt.mapper的执行打印日志
继承特定接口
面向对象三大基本特征:继承,封装,多态
说明:MP在内部准备了一个BaseMapper储存SQL语句,利用多态继承的方法内置了大部分的常用SQL语句
package com.jt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.User;
import java.util.List;
//规则1:继承basemap时,不许添加面向目标的泛型对象
//规则2:自己的方法不要与接口方法重名
public interface UserMapper extends BaseMapper<User> {
//@Mapper //将该接口交给Spring管理,spring创建对象
User find(User user);
List<User> find();
demo测试BaseMapper的17中内置sql
package com.jt;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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 org.yaml.snakeyaml.events.Event;
import java.util.*;
@SpringBootTest
public class TestMybatis {
@Autowired
private UserMapper userMapper;
//完成数据入库的操作
//name="阿富汗",age=40,sex=男
//sql:inset into demo_user value(xx,xx,xx,xx)user
//入库(name=阿富汗,age=40,sex=男)返回插入数量1
@Test
public void testadd(){
User user = new User();
user.setName("阿富汗").setAge(40).setSex("男");
System.out.println(userMapper.insert(user));
System.out.println("入库成功");
}
//最后才执行 返回修改数量
@Test
public void testupdate01(){
User user = new User();
user.setId(666).setAge(22).setSex("男");
System.out.println(userMapper.updateById(user));//返回修改数量
System.out.println("修改成功");
}
//最后才执行 返回修改数量
@Test
public void testupdate02(){
User user = new User();
user.setAge(22);
user.setName("sayhi");
UpdateWrapper<User> updatewrapper=new UpdateWrapper<User>();
updatewrapper.eq("name", "111");
System.out.println(userMapper.update(user,updatewrapper));//返回修改数量
System.out.println("修改成功");
}
//删除(name=阿富汗,age=40,sex=男)返回删除数量
@Test
public void testdelete01(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("name", "阿富汗");
System.out.println(userMapper.delete(queryWrapper));//返回删除数量
System.out.println("删除成功");
}
//删除id值为1,2,3,4的对象,返回删除数量
@Test
public void testdelete02(){
List ids = new ArrayList();
ids.add(1);
ids.add(2);
ids.add(3);
ids.add(4);
System.out.println(userMapper.deleteBatchIds(ids));//返回删除数量
System.out.println("删除成功");
}
//删除id=5的对象,返回删除数量
@Test
public void testdelete03(){
System.out.println(userMapper.deleteById(5));//返回删除数量
System.out.println("删除成功");
}
//删除name=sayhi的对象,返回删除数量
@Test
public void testdelete04(){
Map map =new HashMap();
map.put("name", "sayhi");
System.out.println(userMapper.deleteByMap(map));//返回删除数量
System.out.println("删除成功");
}
//查询列表,id为5~9的对象返回查询的对象
//[User(id=6, name=孙悟空, age=200, sex=男), User(id=7, name=白龙驴, age=200, sex=男), User(id=8, name=八戒, age=200, sex=男)]
@Test
public void testselect01(){
List<Integer> ids =new ArrayList<>();
ids.add(5);
ids.add(6);
ids.add(7);
ids.add(8);
ids.add(9);
System.out.println(userMapper.selectBatchIds(ids));//返回查询的列表
System.out.println("查询成功");
}
//查询对应id的对象 User(id=11, name=小乔, age=200, sex=男)
@Test
public void testselect02(){
System.out.println(userMapper.selectById(11));//返回查询的目标
System.out.println("查询成功");
}
//查询对应目标的对象 [User(id=227, name=小法, age=200, sex=男)]
@Test
public void testselect03(){
Map map =new HashMap();
map.put("name", "小法");
System.out.println(userMapper.selectByMap(map));//返回查询的目标
System.out.println("查询成功");
}
//查询对应目标的数量 返回查询到的数量
@Test
public void testselect04(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("sex", "男");
System.out.println(userMapper.selectCount(queryWrapper));//返回查询到的数量
System.out.println("查询成功");
}
//查询满足要求的对象,返回查询到的对象[User(id=6, name=孙悟空, age=200, sex=男), User(id=7, name=白龙驴, age=200, sex=男)]
@Test
public void testselect05(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("age", "200");
System.out.println(userMapper.selectList(queryWrapper));//返回查询到的列表
System.out.println("查询成功");
}
//查询满足要求的对象,返回查询到的对象数组
//[{sex=男, name=孙悟空, id=6, age=200}, {sex=男, name=白龙驴, id=7, age=200}, {sex=男, name=八戒, id=8, age=200}]
@Test
public void testselect06(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("age", "200");
System.out.println(userMapper.selectMaps(queryWrapper));//返回查询到的列表
System.out.println("查询成功");
}
//查询满足要求的对象,返回查询到的对象数组
//[{sex=男, name=孙悟空, id=6, age=200}, {sex=男, name=白龙驴, id=7, age=200}, {sex=男, name=八戒, id=8, age=200}]
@Test
public void testselect07(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("age", "200");
System.out.println(userMapper.selectMaps(queryWrapper));//返回查询到的对象数组
System.out.println("查询成功");
}
//查询满足要求的对象,返回查询到的id列表[6, 7, 8, 9, 11, 12, 16, 17, 18, 21, 22, 23, 24, 49]
@Test
public void testselect08(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("age", "200");
System.out.println(userMapper.selectObjs(queryWrapper));//返回查询到的id列表
System.out.println("查询成功");
}
//查询目标所在的包 com.baomidou.mybatisplus.extension.plugins.pagination.Page@3b42121d
@Test
public void testselect09(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("name", "小法");
Page page = new Page();
System.out.println(userMapper.selectMapsPage(page,queryWrapper));
//返回查询目标所在的包
System.out.println("查询成功");
}
//返回查询到的目标(只能查一个)
//User(id=173, name=年兽, age=200, sex=男)
@Test
public void testselect10(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("name", "年兽");
Page page = new Page();
System.out.println(userMapper.selectOne(queryWrapper));
//返回查询到的目标(只能查一个)
System.out.println("查询成功");
}
}
同时运行,实验结果修改语句居然会最后执行!!!
条件构造器wapper
可以存储一些判断条件,将a和b的关系存储在wapper中。数据结构是一个Entrl(K,V),依靠一些方法,可以存储一些可以更改的条件语句
继承关系:
常用的方法:
!= ne, == eq, < lt, > gt, <= le, >= ge % like
加入泛型设置,以实现链式设置
Querywapper<User> querywapper = newQuerywapper();
querywapper .eq(判断对象A,判断对象B).ne(判断条件c ,判断条件d) a == b 且 c != d
多个条件默认为且(and),如果想用或:
querywapper .eq(判断对象A,判断对象B).or().ne(判断条件c ,判断条件d) a == b 或c != d