提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Mybatis-Plus
Mybatis-Plus官方
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
1.1 特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
二、简单入门案例
2.1入门
1. pom依赖
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2. Mapper接口:我们只需要继承Mybatis-Plus给我们写好的类即可,已经写好了基础的CURD
@Mapper:声明这是一个Mapper接口
public interface UserMapper extends BaseMapper<输入想要进行操作的实体类对象类型> {
}
3. 实体类
@Data//自动帮我们生成setter and getter等繁琐的方法
@TableName("tb_user")//若表名与实体类的类名一致则不需要添加此注解
public class User {
private Integer id;
@TableField("user_name")//若数据库字段与实体类属性名不一致需要加此注解
private String username;
private String password;
}
4. 测试
@SpringBootTest
class Springboot15MybatisplusApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
//参数是一个Wrapper 条件构造器,先不用 设置为null
List<User> users = userMapper.selectList(null);
users.forEach(user -> System.out.println(user));
}
}
2.2 日志配置
#@配置日志:StdOutImpl 将执行的SQL语句输出到控制台
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
2.3 MP-增删改查
BaseMapper<>接口帮我们实现了17个常用CRUD方法,所以我们不需要再写SQL语句,简化开发
2.3.1 增
1. 实体类
@Data//自动帮我们生成setter and getter等繁琐的方法
@TableName("tb_user")//若表名与实体类的类名一致则不需要添加此注解
public class User {
//IdType.AUTO:自增策略 前提数据库主键也是自增,否则报错
@TableId(value = "id",type = IdType.AUTO)//若数据库字段与实体类属性名不一致需要加此注解
private int id;
@TableField("user_name")//若数据库字段与实体类属性名不一致需要加此注解
private String username;
private String password;
}
2. 测试
@Test
public void insert(){
User user = new User();
user.setUsername("李四");
user.setPassword("666666");
userMapper.insert(user);
//当MP执行完语句后,会把结果映射给对象
//获取主键ID,主键字段对应的get方法
System.out.println(user.getId());
}
2.3.2 删
@Test
public void delete(){
//根据主键删除
int i = userMapper.deleteById(3);
System.out.println("影响行数===>"+i);
//按照条件删除用Map
HashMap<String, Object> map = new HashMap<>();
map.put("user_name","root");
map.put("id",3);
int i1 = userMapper.deleteByMap(map);
System.out.println("删除行数===>"+i1);
//批处理方法 根据主键删除
ArrayList<Integer> data = new ArrayList<>();
data.add(1);
data.add(2);
int i2 = userMapper.deleteBatchIds(data);
System.out.println("批处理删除了===>"+i2+"条数据");
}
}
2.3.1 改
@Test
public void update(){
User user = new User();
user.setUsername("王五");
user.setPassword("root");
user.setId(3);
//更新非空的字段
int i = userMapper.updateById(user);
System.out.println("影响行数===>"+i);
}
2.3.1 查
@Test
void select() {
//参数是一个Wrapper 条件构造器,先不用 设置为null
List<User> users = userMapper.selectList(null);
users.forEach(user -> System.out.println(user));
//根据主键查询
User user = userMapper.selectById(6);
System.out.println(user);
}
三、ActiveRecord(AR)
- 每一个数据库表对应一个实体类,类的每一个对象属性对应数据库表中的一个字段
- ActiveRecord负责把自己持久化,在ActiveRecord中封装了对数据库的访问,通过对象自己实现CURD,实现优雅的操作数据库
- ActiveRecord也封装了业务逻辑,可以作为业务对象使用
3.1 MP-AR
1. 创建实体类 与数据库中的表数据字段一模一样
/**
* 使用AR,要求实体类继承MP中的Model
* Model中提供了对数据库的CRUD的操作
*/
@Data
public class Dept extends Model<Dept> {
//定义属性,属性名和表的列名一一
//指定主键 和集成策略
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String phone;
}
2. 定义实体类的Mapper接口,但是我们不需要使用该Mapper
/**
* DeptMapper是不需要使用的,MP需要使用DeptMapper获取到数据库表的信息
* 如果使用AR不定义DeptMapper,MP会报错,找不到表的定义信息
*/
@Mapper
public interface DeptMapper extends BaseMapper<Dept> {
}
3. 测试 通过对象.CRUD方法即可执行
@Test
void testAr(){
//创建实体对象
Dept dept = new Dept();
dept.setName("AR测试");
dept.setPhone("188");
//调用实体对象自己的方法,完成自身到数据库的添加
boolean insert = dept.insert();
System.out.println("AR操作添加数据===>"+insert);
}
四、主键类型策略值介绍
1. AUTO 代表主键自动增长不需要我们手动设置,前提是数据库也设置了自动增长
2. NONE 代表没有主键
3. INPUT 代表手动输入主键
4. ID_WORKER 实体类用 Long id 数据库中用 bigint id ASSIGN_ID可以代替ID_WORKER
5. ID_WORKER_STR 实体类用String id 数据库中用 varchar 50
6. UUID:实体类用String id 数据库中使用 varchar 50
ID_WORKER :Twitter 开源的雪花算法:由 机器相关信息、时间序列、服务器相关信息组合在一起的序列值,在分布式中使用较多
五、MP常用注解
1. 指定表名 如果实体类名与数据库表名相同 则可以忽略不写
@TableName(value = "指定对应数据库中的哪张表")
2. 指定主键 若实体类属性与数据库中字段名一致 可以忽略
//定义属性,属性名和表的列名一一对应
//指定主键 和集成策略
@TableId(value = "数据库中主键名称",type = IdType.ASSIGN_UUID)
3. 指定字段名 若实体类属性和数据库中的字段名一致 可以忽略
@TableField(value = "数据库中字段的名称")
六、驼峰命名规则
当我们实体类属性与数据库表中的字段值大量不同时,使用@TableField显得十分繁琐,那么我们可以遵循驼峰命名规范
mybatis是默认支持驼峰命名规范的
例: 数据库中用下划线来分割,
数据库表字段:user_name
实体类中属性:userName
七、自定义Mapper映射文件
1. Mapper接口
@Mapper
public interface StudentMapper extends BaseMapper<Student> {
Student selectById(Student student);
}
2. Mapper映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.boot.study.mapper.StudentMapper">
<select id="selectById" resultType="com.boot.study.bean.Student">
select * from student where id=#{stuId}
</select>
</mapper>
3. 实体类
@Data
public class Student {
@TableId("id")
private int stuId;
private String userName;
private int sex;
}
4. 在application核心配置文件中自定义Mapper映射文件位置
mybatis-plus.mapper-locations=classpath:mapper/*.xml
八、Wrapper
8.1 多条件查询 allEq()
1. Mapper接口
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
2. Bean实体类
@Data//自动帮我们生成setter and getter等繁琐的方法
@TableName("tb_user")//若表名与实体类的类名一致则不需要添加此注解
public class User {
//IdType.AUTO:自增策略 前提数据库主键也是自增,否则报错
@TableId(value = "id",type = IdType.AUTO)//若数据库字段与实体类属性名不一致需要加此注解
private int id;
@TableField("user_name")//若数据库字段与实体类属性名不一致需要加此注解
private String username;
private String password;
}
3. 测试
@Test
void t3(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//组装 查询条件
HashMap<String, Object> map = new HashMap<>();
map.put("id",3);
map.put("user_name","王五");
map.put("password","root");
userQueryWrapper.allEq(map);
//SELECT id,user_name,password FROM tb_user
// WHERE (password = ? AND user_name = ? AND id = ?)
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
8.2 单条件查询 eq()
@Test
void t4(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//单条件查询,若写n个条件 也可以当做多条件查询来拼接
userQueryWrapper.eq("id",3);
userQueryWrapper.eq("password","root");
//SELECT id,user_name,password FROM tb_user WHERE (id = ? AND password = ?)
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
8.3 大于gt() 大于等于ge() 小于lt() 小于等于le()
1. 大于 gt()
@Test
void t5(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//大于等于条件
userQueryWrapper.gt("id",2);
//SELECT id,user_name,password FROM tb_user WHERE (id > ?)
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
2. 大于等于 ge()
3. 小于lt()
4. 小于等于le()
8.4 范围查询between(“字段”,值1,值2) 不在范围查询 notBetween(“字段”,值1,值2)
@Test
void t6(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//between 初始值,结束值
userQueryWrapper.between("id",2,5);
//SELECT id,user_name,password FROM tb_user WHERE (id BETWEEN ? AND ?)
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
8.5 Like() 模糊查询 与 notLike()模糊查询取反
@Test
void t7(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//like 模糊查询 , 会自动给语句加上 % %
userQueryWrapper.like("user_name","四");
//SELECT id,user_name,password FROM tb_user WHERE (id BETWEEN ? AND ?)
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
void t8(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//like 模糊查询 , 会自动给语句加上 % %
userQueryWrapper.notLike("user_name","四");
//SELECT id,user_name,password FROM tb_user WHERE (id BETWEEN ? AND ?)
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
8.6 LikeRight() 与LikeLeft()
@Test
void t8(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//like 模糊查询 , 会自动给语句加上 %
userQueryWrapper.likeLeft("user_name","四");
//SELECT id,user_name,password FROM tb_user WHERE (id BETWEEN ? AND ?)
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
8.7 in(“字段”,值1,值2,…) 查看当前字段值1和值2都是符合的
@Test
void t9(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//like 模糊查询 , 会自动给语句加上 %
userQueryWrapper.in("password","123","123456");
//SELECT id,user_name,password FROM tb_user WHERE (id BETWEEN ? AND ?)
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
8.8 inSql(字段,sql语句) 子查询
先查询inSql中的语句,在把查询出来的结果赋值给字段,再去查询当前表的所有属性
@Test
void t8(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//inSql 子查询
userQueryWrapper.inSql("password","select password from tb_user where id=3");
//SELECT id,user_name,password FROM tb_user
// WHERE (password IN (select password from tb_user where id=3))
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
8.9 GroupBy() 分组
@Test
void t9(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.select("id","user_name","password");
//分组
userQueryWrapper.groupBy("user_name");
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
8.10 orderByAsc()/orderByDesc()升降序
@Test
void t9(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.select("id","user_name","password");
//升序
userQueryWrapper.orderByAsc("id","user_name");
List<User> users = userMapper.selectList(userQueryWrapper);
users.forEach(user -> System.out.println(user));
}
九、分页
9.1 配置
使用分页插件,我们需要自定义一个Configuration配置类,并且注册分页拦截器
@Configuration
public class Config {
//分页插件拦截器
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
9.2 内置分页使用
@Test
void t10(){
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.gt("id",1);
Page<User> userPage = new Page<>();
userPage.setCurrent(2);//设置从第几页开始查
userPage.setSize(5);//每页显示多少条数据
Page<User> userPage1 = userMapper.selectPage(userPage, userQueryWrapper);
records.forEach(user -> System.out.println(user));
System.out.println("总页数"+userPage.getPages());
System.out.println("总记录数"+userPage.getTotal());
System.out.println("当前页码"+userPage.getCurrent());
System.out.println("每页大小"+userPage.getSize());
}
9.3 自定义XML分页
1. 配置分页拦截器
@Configuration
public class Config {
//分页插件拦截器
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
2. 自定义Mapper接口中分页方法
@Mapper
public interface UserMapper extends BaseMapper<User> {
返回值必须是Page<T> 形参第一个必须是Page<T>
Page<User> selectByPage(Page<User> page, User user);
}
3. Mapper接口
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.boot.study.mapper.UserMapper">
<sql id="globalSql">
select * from tb_user
</sql>
sql语句中不用写分页条件,page会自动添加上分页条件
<select id="selectByPage" parameterType="com.boot.study.bean.User" resultType="com.boot.study.bean.User">
<include refid="globalSql"/>
<where>
<if test="user.username!=null">
user_name=#{user.username}
</if>
<if test="user.password!=null">
and password like '%' #{user.password} '%'
</if>
</where>
</select>
</mapper>
4. 测试
@Test
void t11(){
User user = new User();
user.setUsername("李四");
user.setPassword("6");
Page<User> userPage = new Page<>();
userPage.setCurrent(1);
userPage.setSize(5);
查询完分页信息会封装到userPage中
userMapper.selectByPage(userPage, user);
List<User> records = userPage.getRecords();
records.forEach(user1 -> System.out.println(user1));
}
9.4 PageHelper
1. pom依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
2. 定义PageHelper拦截器
//PageHelper拦截器 与Mybatis-Plus内置拦截器不冲突
public PageInterceptor pageInterceptor(){
return new PageInterceptor();
}
3. 定义Mapper接口分页方法
List<User> selectByPage2(User user);
4. Mapper映射文件
<select id="selectByPage2" parameterType="com.boot.study.bean.User" resultType="com.boot.study.bean.User">
<include refid="globalSql"/>
<where>
<if test="username!=null">
user_name=#{username}
</if>
<if test="password!=null">
and password like '%' #{password} '%'
</if>
</where>
</select>
5. 测试
@Test
void t12(){
User user = new User();
user.setUsername("李四");
user.setPassword("6");
//设置分页
PageHelper.startPage(1,5);
List<User> users = userMapper.selectByPage2(user);
//查看分页所有信息
PageInfo pageInfo = new PageInfo(users);
System.out.println(pageInfo.toString());
}
9.5 SpringBoot整合PageHelper
1. pom依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
2. Service
public PageInfo<Bill> listPage(int pageNum,int pageSize,Bill bill){
List<Bill> list = billMapper.selectBy(bill);
Page<Object> objects = PageHelper.startPage(pageNum, pageSize);
PageInfo<Bill> PageInfo = objects.doSelectPageInfo(new ISelect() {
@Override
public void doSelect() {
//将分页查询的数据传入到PageInfo中
billMapper.selectBy(bill);
}
});
// return PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> billMapper.selectBy(bill));
return PageInfo;
}