文章目录
pom.xml
<build>
<!--jdk版本-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
<!--Mapper文件过滤-->
<!-- 项目打包时会将java目录中的*.xml文件也进行打包 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.3.12.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!--注意与org.springframework.boot版本兼容问题-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.15</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
application.yaml
spring:
# 配置数据源信息
datasource:
druid:
# 高并发场景下,万一遇到网络问题,可能会导致你跟数据库的Socket连接异常无法通信
connect-timeout: 1200 # 建立TCP连接的超时时间
socket-timeout: 3000 # 发送请求后 等待响应的超时时间
max-wait: 1000 # 1s以上, 大量线程获取不到连接,1s左右快速就失败
maxActive: 20 # 确实有高并发场景,可以适当增加到3~5倍,不超过 100
initial-size: 5 # 初始化大小
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.111.101:3306/mybatis_plus?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 123456
mybatis-plus:
configuration:
# 数据库字段:user_id===>实体属性:userId
map-underscore-to-camel-case: true
# 打印sql日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: ASSIGN_ID # 采用 分布式ID策略
# mapper的地址
mapper-locations: classpath*:com/xconline/mapper/xml/*.xml
线上设置多少合适
- 对于数据库连接池的设置,线上最小 连接数控制在10左右,最大连接数 控制在20-30左右即可。
- 启动一个线程来定期检测连接池中的连接是否可用,SELECT 1 FROM DUAL
计算公式:
连接数 = ( (核心数 * 2) + 有效磁盘数)
(通常不会高于2*CPU核心数
)
启动类
在Spring Boot启动类中添加@MapperScan
注解,扫描mapper包
@EnableTransactionManagement // 开启事务
@SpringBootApplication
@MapperScan("org.example.mapper") // 扫描Mapper接口,动态生成 代理类
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
添加实体
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user") // 指定 数据库中的表名
public class User {
@TableId("id") // 指定 数据库中的主键名
private Long id;
@TableField("name") // 对应数据库字段
private String userName;
@TableField("name")
private Integer age;
@TableLogic // 逻辑删除
private int isDeleted;
}
mapper
public interface UserMapper extends BaseMapper<User> {
}
创建Service接口和实现类
/**
* UserService继承IService模板提供的基础功能
*/
public interface UserService extends IService<User> {
}
/**
* ServiceImpl实现了IService,提供了IService中基础功能的实现
* 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
增删改查
查询
int page = 1;
int pageSize = 5;
// 构造分页构造器对象
Page<Dish> pageInfo = new Page<> (page, pageSize);
// 条件构造器,指定泛型
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<> ();
// 添加过滤条件,第一个是条件,为true就添加条件
// queryWrapper.like (name != null, Dish::getName, name);
// queryWrapper.likeLeft (,);
// queryWrapper.gt (,)
// queryWrapper.lt (,);
// queryWrapper.eq (, );
// queryWrapper.ne (,);
// queryWrapper.isNull (, );
// queryWrapper.isNotNull ();
// queryWrapper.select (, ); 指定查询字段
// queryWrapper.in (,);
// queryWrapper.notIn (, );
// queryWrapper.between (, );
// queryWrapper.notBetween (,,);
// 添加分组条件
// queryWrapper.groupBy (id!=null,Dish::getCategoryId);
// 添加排序条件
queryWrapper.orderByAsc (Dish::getCreateTime); // 升序
queryWrapper.orderByDesc (Dish::getUpdateTime); // 降序
dishService.getOne (queryWrapper); // 根据条件 查询一个
dishService.getById (1); // 根据id 查询一个
dishService.list (); // 查询多个
dishService.list (queryWrapper); // 根据条件 查询多个
dishService.listByIds (idList); // 根据id集合 查询多个
dishService.count (); // 统计数量
dishService.count (queryWrapper); // 根据条件 统计数量
// 执行分页查询,将结果填充到 pageInfo中
dishService.page (pageInfo); // 分页查询 不带条件
dishService.page (pageInfo, queryWrapper); // 分页查询 带条件
// 调用内置 query ()方法进行查询
dishService.query ().eq ("name", "xd").one ();// 根据name 查询一个
删除
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<> ();
queryWrapper.eq (Dish::getCategoryId, 5);
dishService.remove (queryWrapper); // 根据条件 删除
dishService.removeById (1); // 根据id 删除一个
dishService.removeById (dish); // 根据id 删除一个,传入实体对象!实体对象 必须有id值!!!
dishService.removeByIds (idList); // 根据id集合 删除多个
dishService.removeBatchByIds (idList); // 根据id集合 批量删除
更新
// 调用 dishService的 update ()方法
dishService.update ()
.set (name != null, "name", "xiaod")
.set ("age", 25)
.eq (age != null, "age", 20);
// 根据id 更新
dishService.updateById (dish);
// 批量更新,根据id
dishService.updateBatchById (dishList);
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<> ();
queryWrapper.eq (Dish::getCategoryId, 5);
// 根据条件 更新
dishService.update (dish, queryWrapper);
// 修改点赞数量
blogService.update()
// 手写sql
.setSql("liked = liked + 1").eq("id", id)
// 结束,返回boolean值
.update();
添加
// 添加
dishService.save (dish);
// 批量添加
dishService.saveBatch (dishList);
// 条件 构造器
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<> ();
queryWrapper.eq (Dish::getCategoryId, 5);
// 存在=>更新,不存在=>添加
dishService.saveOrUpdate (dish);
分页插件
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 分页插件
*/
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor ();
interceptor.addInnerInterceptor (new PaginationInnerInterceptor ());
return interceptor;
}
// 逻辑删除
@Bean
public ISqlInjector sqlInjector() {
return new DefaultSqlInjector ();
}
}
公共字段填充
User表 添加 datetime 类型的新的字段 create_time、update_time
实体类 加上 createTime、updateTime
@TableField(fill = FieldFill.INSERT)
private Date createTime; //create_time
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime; //update_time
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 自定义 元数据对象处理器
*/
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 插入操作,自动填充
*
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
metaObject.setValue ("createTime", new Date ());
metaObject.setValue ("updateTime", new Date ());
}
/**
* 更新操作,自动填充
*
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
metaObject.setValue ("updateTime", new Date ());
}
}
多数据源
pom文件
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
配置多数据源
说明:注释掉之前的数据库连接,添加新配置
spring:
# 配置数据源信息
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
# 严格 匹配数据源,默认false. true 未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://192.168.111.101:3306/mybatis_plus?characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
slave_1:
url: jdbc:mysql://192.168.111.101:3306/mybatis_plus_1?characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
创建用户service
public interface UserService extends IService<User> {
}
@DS("master") //指定所操作的数据源
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements
UserService {
}
创建商品service
public interface ProductService extends IService<Product> {
}
@DS("slave_1") //指定所操作的数据源
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product>
implements ProductService {
}
测试
@Autowired
private UserService userService;
@Autowired
private ProductService productService;
@Test
public void testDynamicDataSource(){
//System.out.println(userService.getById(1L));
System.out.println(productService.getById(1L));
}
批量插入
@Autowired
//要有 IService<User>
private UserService userService;
public void main(String[] args) {
// 批量插入提高性能!!
List<User> userList=new ArrayList<>();
userService.saveBatch(userList);
}
结果:
1、都能顺利获取对象,则测试成功
2、如果我们实现读写分离
,将写
操作方法加上主库数据源
,读
操作方法加上从库数据源
,自动切
换,是不是就能实现读写分离
?
mapper文件使用
第一步:防止加载 不到mapper,会报出异常
pom.xml配置
<build>
<!--jdk版本-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
<!--Mapper文件过滤-->
<!-- 项目打包时会将java目录中的*.xml文件也进行打包 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
第二步:配置 yaml文件
指定 mapper地址
mybatis-plus:
configuration:
# 数据库字段:user_id===>实体属性:userId
map-underscore-to-camel-case: true
# 打印sql日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# mapper的地址, 类路径
mapper-locations: classpath*:com/xconline/mapper/xml/*.xml
第三步:mapper接口
import org.apache.ibatis.annotations.Param;
public SysRole selectPage(@Param("vo") SysRole sysRole);
第四步:编写 mapper
<resultMap id="RoleMap" type="com.atguigu.model.system.SysRole" autoMapping="true">
</resultMap>
<!-- 用于select查询公用抽取的列 -->
<sql id="columns">
id,role_name,role_code,description,create_time,update_time,is_deleted
</sql>
<!-- id 与方法名相同 -->
<select id="selectPage" resultMap="RoleMap">
select <include refid="columns" />
from sys_role
<where>
<if test="vo.roleName != null and vo.roleName != ''">
and role_name like CONCAT('%',#{vo.roleName},'%')
</if>
and is_deleted = 0
</where>
order by id desc
</select>