MySQL+MyBatis-plus

数据库知识

DDL

什么是DDL

DDL(Data Definition Language)是数据库定义语言,用于定义数据库架构、表、视图、索引等数据库对象。

常用DDL指令

CREATE:用于创建数据库对象,如创建表、视图、索引等。
例如:CREATE TABLE 表名 (列名1 数据类型1, 列名2 数据类型2, …);

ALTER:用于修改数据库对象的结构,如修改表结构、添加列、删除列等。
例如:ALTER TABLE 表名 ADD 列名 数据类型;

DROP:用于删除数据库对象,如删除表、视图、索引等。
例如:DROP TABLE 表名;

TRUNCATE:用于删除表中的所有记录,但不删除表的结构。
例如:TRUNCATE TABLE 表名;

COMMENT:用于添加注释。
例如:COMMENT ON TABLE 表名 IS ‘注释’;

RENAME:用于重命名数据库对象,如重命名表、列等。
例如:RENAME TABLE 表名 TO 新表名;

GRANT:用于授权。
例如:GRANT SELECT ON 表名 TO 用户名;

REVOKE:用于收回授权。
例如:REVOKE SELECT ON 表名 FROM 用户名;

DML

什么是DML

DML(Data Manipulation Language)是数据操作语言,用于添加、修改、删除和查询数据。
CURD 是一种操作的分类,而 DML 是一种语言的分类。

常用的DML

Create(创建)
Create 操作用于向数据库中添加新的记录。CREATE 命令通常用于创建新的表、新的视图、新的索引等数据库对象。CREATE 命令的语法如下:

CREATE TABLE table_name (
    column1 datatype constraint,
    column2 datatype constraint,
    ...
);

Read(读取)
Read 操作用于从数据库中读取数据。SELECT 命令是最常用的读取操作,它的语法如下:

SELECT column1, column2, ... 
FROM table_name 
WHERE condition;

其中,column1, column2, … 是要查询的列名,table_name 是要查询的表名,condition 是查询条件。

Update(更新)
Update 操作用于修改数据库中的已有数据。UPDATE 命令的语法如下:

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

其中,table_name 是要更新的表名,column1, column2, … 是要更新的列名和对应的值,condition 是更新条件。

Delete(删除)
Delete 操作用于从数据库中删除数据。DELETE 命令的语法如下:

DELETE FROM table_name WHERE condition;

其中,table_name 是要删除的表名,condition 是删除条件。

其他操作

  1. DQL(Data Query Language):数据查询语言,用于查询数据。常见的 DQL 命令是 SELECT。

  2. DCL(Data Control Language):数据控制语言,用于控制数据库用户的访问权限。常见的 DCL 命令包括
    GRANT、REVOKE 等。

  3. TCL(Transaction Control Language):事务控制语言,用于控制事务的提交和回滚操作。常见的 TCL 命令包括
    COMMIT、ROLLBACK 等。

什么是数据库的事务,什么是脏读,不可重复读,幻读。

隔离级别特点解决问题
读未提交(Read Uncommitted)- 能够读取另一个事务未提交的数据
- 可能会出现脏读、不可重复读和幻读等问题
脏读
读已提交(Read Committed)- 只能读取另一个事务已提交的数据
- 可能会出现不可重复读和幻读等问题
- 可以避免脏读问题
脏读
可重复读(Repeatable Read)- 在执行期间多次读取同一数据行时,能够保证读取到相同的数据
- 可以避免脏读和不可重复读问题
- 可能会出现幻读等问题
不可重复读、幻读
序列化(Serializable)- 所有事务必须依次执行,每个事务都必须等待前一个事务完成后才能开始执行
- 可以避免脏读、不可重复读和幻读等问题
脏读、不可重复读、幻读

事务有四个特性 ACID:1.原⼦性,2.隔离性,3.⼀致性,4.持久性。原⼦性指的就是
事务⾥⾯执⾏的增删改操作是⼀个原⼦操作,要么全部成功,要么全部失败。隔离性
指的是两个事务之间同时操作数据库的时候有相应的隔离级别,可以限制事务与事务
之间数据的影响。⼀致性指的是事务操作前和事务操作后数据必须是正确的。持久性
指的是事务做完操作之后,数据就永久保存了,不会因为⼀些原因导致数据丢失。事
务的这些特性会保证我们项⽬中数据的安全,不会因为⼀些异常导致数据出问题。

事务的隔离级别有四个:1.未提交读,2.已提交读,3.可重复读,4.序列化。未提交
读会引起脏读问题。脏读就是指⼀个事务插⼊数据后,还没有提交事务的情况下,其
他的事务就可以读到该数据,这就是脏读问题。已提交读解决了脏读的问题,但是没
有解决不可重复读的问题。不可重复读指的是⼀个事务读两次相同的数据,发现两次
读到的数据是不⼀致的。因为中间有其他的事务修改这个数据。为了避免不可重复读
的问题,我们可以把事务的隔离级别提⾼到可重复读的级别。可重复读解决了不可重
复读的问题,但是有幻读的问题,幻读是指⼀个事务读到数据库⾥⾯没有⼀条数据,
在他插⼊该数据的时候突然发现数据库⾥⾯已经有这个数据了。数据库提供了序列化
读的隔离级别,可以解决幻读问题。隔离级别越⾼,那么数据库的性能就会越低。

Mybatis-plus

基本介绍

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

与SpringBoot项目集成

  1. 引入依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>最新版本</version>
</dependency>
  1. 配置application.yaml
mybatis-plus:
    configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台标准输出运行过程
        map-underscore-to-camel-case: true # 开启小驼峰转换
        use-generated-keys: true
    global-config:
        banner: false # 关闭控制台输出logo
        db-config:
            id-type: auto
            logic-delete-value: 1 # 逻辑已删除值(默认为 1)
            logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

  1. 使用IDEA插件MybatisX快速生成domain、mapper、mapper.xml、service、serviceImpl(可继续使用EasyCode插件生成controller)
  2. 在启动类中配置Mapper的扫描器@MapperScan(“com.ac.demo.mapper”)
  3. 如需其他插件,请参考官方文档配置相关拦截器等配置

基本使用

mapper层接口

  1. 插入
// 插入一条记录
int insert(T entity);
  1. 删除
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
  1. 修改
// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
  1. 查询
// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

service层接口

  1. 插入
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);
  1. 更新或插入
// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
  1. 删除
// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);
  1. 更新
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);
  1. 查询
// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
  1. 分页
// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

条件构造器

(图片来源:尚硅谷
图片来源尚硅谷Mybatis-plus教学

  1. QueryWrapper 实现类
    QueryWrapper 用于构建 SELECT 语句的 WHERE 条件,它提供了一系列的方法用于构建常用的查询条件,如 eq、ne、gt、lt、like、in、between、isNull、orderBy 等。以下是 QueryWrapper 的一个简单示例:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "张三").between("age", 18, 30).orderByAsc("id");
List<User> userList = userMapper.selectList(queryWrapper);

上面的代码中,我们创建了一个 QueryWrapper 对象 queryWrapper,然后使用 eq 方法添加了一个 name 等于 “张三” 的查询条件,使用 between 方法添加了一个 age 在 18 到 30 之间的查询条件,使用 orderByAsc 方法添加了一个 id 升序排序的条件。最后,我们使用 selectList 方法执行查询,并获得查询结果。
2. UpdateWrapper 实现类
UpdateWrapper 用于构建 UPDATE 语句的 SET 条件,它提供了一系列的方法用于构建常用的更新条件,如 eq、ne、set、in、between、isNull、orderBy 等。以下是 UpdateWrapper 的一个简单示例:

UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "张三").set("age", 20);
int rows = userMapper.update(null, updateWrapper);

上面的代码中,我们创建了一个 UpdateWrapper 对象 updateWrapper,然后使用 eq 方法添加了一个 name 等于 “张三” 的查询条件,使用 set 方法将 age 更新为 20。最后,我们使用 update 方法执行更新操作,并获得更新结果。
3. LambdaQueryWrapper 实现类
LambdaQueryWrapper 是 QueryWrapper 的 Lambda 表达式版本,它提供了一种更加简洁易懂的方式来构建查询条件。以下是 LambdaQueryWrapper 的一个简单示例:

LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.<User>lambdaQuery();
lambdaQueryWrapper.eq(User::getName, "张三").between(User::getAge, 18, 30).orderByAsc(User::getId);
List<User> userList = userMapper.selectList(lambdaQueryWrapper);

上面的代码中,我们使用 Wrappers.lambdaQuery 方法创建了一个 LambdaQueryWrapper 对象 lambdaQueryWrapper,然后使用 eq 方法添加了一个 name 等于 “张三” 的查询条件,使用 between 方法添加了一个 age 在 18 到 30 之间的查询条件,使用 orderByAsc 方法添加了一个 id 升序排序的条件。最后,我们使用 selectList 方法执行查询,并获得查询结果。
4. LambdaUpdateWrapper 实现类
LambdaUpdateWrapper 是 UpdateWrapper 的 Lambda 表达式版本,它提供了一种更加简洁易懂的方式来构建更新条件。以下是 LambdaUpdateWrapper 的一个简单示例:

LambdaUpdateWrapper<User> lambdaUpdateWrapper = Wrappers.<User>lambdaUpdate();
lambdaUpdateWrapper.eq(User::getName, "张三").set(User::getAge, 20);
int rows = userMapper.update(null, lambdaUpdateWrapper);

上面的代码中,我们使用 Wrappers.lambdaUpdate 方法创建了一个 LambdaUpdateWrapper 对象 lambdaUpdateWrapper,然后使用 eq 方法添加了一个 name 等于 “张三” 的查询条件,使用 set 方法将 age 更新为 20。最后,我们使用 update 方法执行更新操作,并获得更新结果。

mybatis 的⼀级缓存和⼆级缓存

  1. mybatis中默认带了一级缓存,自动就使用了一级缓存。一级缓存是跟sqlSession相关的缓
    存。当我们使用同样的sqlSession去执行相同的查询sql那么一级缓存就会生效。一级缓存应用
    场景不多,几乎用不到。
  2. mybatis的二级缓存不是默认打开的,需要我们手动设置开启二级缓存。二级缓存是跟SqlSe
    ssionFactory相关的缓存。只要是同一个sqlSessionFactory创建的sqlSession对象执行的
    sql语句都共用这个二级缓存。

mybatis 中取值⽅式有⼏种?各⾃的区别是什么?

#{}和${}的区别

  1. #{}相当于sql语句的占位符,他的执行效率和安全性都比字符串拼接要好。
  2. ${}相当于字符串拼接,更加灵活。可以应用在sql中的关键字。

select * from 表 order by ?

这个场景可以应用在${}上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值