1.导包/依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
2.配置数据源
spring:
datasource:
username: root
password: Liu128041384
url: jdbc:mysql://localhost:3306/mybatis_plus?
useSSL=false&useUnicode=true&
characterEncoding=utf-8&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
3.快速入门
1.编写bean
2.编写mapper接口,继承BaseMapper
package com.liucc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liucc.bean.User;
import org.springframework.stereotype.Repository;
@Repository //代表持久层的
public interface UserMapper extends BaseMapper<User> {
}
3.在主类里面扫描包
//扫描Mapper
@MapperScan("com.liucc.mapper")
4.使用
package com.liucc;
import com.liucc.bean.User;
import com.liucc.mapper.UserMapper;
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
class SpringbootApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
//查询全部用户
//参数是一个条件构造器wrapper,先不用就用null
List<User> users = userMapper.selectList(null);
//语法糖
users.forEach(System.out::println);
}
}
注意更新操作时使用的userMapper.updateById(user);此处虽然名字叫ById,但参数是一个对象
在插入时,实体类名和数据库字段之间的关系
实体类驼峰命名法 createTime 数据库中create_time 是可以自动识别的
如果不一致,可以在实体类中添加注释
@TableField( value = “create_time/数据库中的字段名/”)
4.注解
https://baomidou.com/pages/223848/#tablename
1.@TableName
- 描述:表名注解,标识实体类对应的表
- 使用位置:实体类
2.@TableId
- 描述:主键注解
- 使用位置:实体类主键字段
INPUT //手动输入
一般使用 ID_WORKER
使用 : @TableId(type=IdType.AUTO)
3.@TableField
- 描述:字段注解(非主键)
//字段添加填充内容
@TableField(fill= FieldFill.INSERT)
private Date createTime;
@TableField(fill= FieldFill.INSERT_UPDATE)
private Date updateTime;
使用:在实体类中添加
@TableField(fill= FieldFill.INSERT)
private Date createTime;
@TableField(fill= FieldFill.INSERT_UPDATE)
private Date updateTime;
创建MyMetaHandle,注意@Component//记得加入到IOC中
@Slf4j
@Component//记得加入到IOC中
public class MyMetaHandle implements MetaObjectHandler {
//插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("开始执行插入填充......");
//设置字段参数
//setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
//更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("开始执行更新填充......");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
5.锁—乐观锁/悲观锁
乐观锁:顾名思义,乐观锁就是持比较乐观态度的锁。就是在操作数据时非常乐观,认为别的线程不会同时修改数据,所以不会上锁,但是在更新的时候会判断在此期间别的线程有没有更新过这个数据。
悲观锁:就是持悲观态度的锁。就在操作数据时比较悲观,每次去拿数据的时候认为别的线程也会同时修改数据,所以每次在拿数据的时候都会上锁,这样别的线程想拿到这个数据就会阻塞直到它拿到锁。
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前 version
- 更新时,带上这个 version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
6.常用查询
@Test
void test查询() {
//查询一条
User user = userMapper.selectById(1L);
System.out.println(user);
//查询批量 //数组工具类,转成集合
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
//条件查询 Map
HashMap<String, Object> map = new HashMap<>();
map.put("name","Jack");
List<User> users1 = userMapper.selectByMap(map);
users1.forEach(System.out::println);
}
7.MyBatis-Plus核心插件使用
https://blog.csdn.net/weixin_43313391/article/details/127040779
8.association 一对一联表
<association property="实体类中的键" column="后面那个select需要传入的值" select="哒哒哒"/>
column格式:
传入一个值:直接写就行column="commodity_id"
传入多个值:column="{commodityId=commodity_id,imgId=img_id}"
9.collection 一对多
<collection property="imgList" ofType="Img" column="{commodityId=commodity_id,imgId=img_id}" select="getImgList"/>
ofType: 是什么呢?---> 返回的List<ofType>
迭代联表调用案例
<select id="getCategoryList" resultMap="getCategoriesMap">
SELECT category_id,`name`,category_level,is_base FROM tab_category WHERE parent_category_id=0
</select>
<!--嵌套查询-->
<select id="getCategories" resultMap="getCategoriesMap">
SELECT category_id,`name`,category_level,is_base FROM tab_category WHERE parent_category_id=#{categoryId}
</select>
<resultMap id="getCategoriesMap" type="Category">
<id property="categoryId" column="category_id"/>
<result property="name" column="name"/>
<result property="categoryName" column="category_name"/>
<result property="categoryLevel" column="category_level"/>
<result property="isBase" column="is_base"/>
<collection property="childrenList" ofType="Category" column="{categoryId=category_id}" select="getCategories"/>
</resultMap>