文章目录
官方文档: https://baomidou.com/introduce/
参考文档:https://www.cnblogs.com/diffx/p/10611082.html
参考教程:https://www.quanxiaoha.com/mybatis-plus/mybatisplus-quick-start.html
JDBC
Java为关系数据库定义了一套标准的访问接口:JDBC(Java Database Connectivity)
使用Java程序访问数据库时,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而JDBC接口则通过JDBC驱动来实现真正对数据库的访问。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCTest {
public static void main(String[] args) throws Exception {
Connection connection = null;
PreparedStatement prepareStatement = null;
ResultSet rs = null;
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/ssmdemo";
String user = "root";
String password = "123456";
connection = DriverManager.getConnection(url, user, password);
// 获取statement,preparedStatement
String sql = "select * from tb_user where id=?";
prepareStatement = connection.prepareStatement(sql);
// 设置参数
prepareStatement.setLong(1, 1l);
// 执行查询
rs = prepareStatement.executeQuery();
// 处理结果集
while (rs.next()) {
System.out.println(rs.getString("userName"));
System.out.println(rs.getString("name"));
System.out.println(rs.getInt("age"));
System.out.println(rs.getDate("birthday"));
}
} finally {
// 关闭连接,释放资源
if (rs != null) {
rs.close();
}
if (prepareStatement != null) {
prepareStatement.close();
}
if (connection != null) {
connection.close();
}
}
}
}
Mybatis
整体架构
- 配置mybatis-config.xml 全局的配置文件 (1、数据源,2、外部的mapper)
- 创建SqlSessionFactory
- 通过SqlSessionFactory创建SqlSession对象
- 通过SqlSession操作数据库 CRUD
- 调用session.commit()提交事务
- 调用session.close()关闭会话
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class MybatisTest {
public static void main(String[] args) throws Exception {
// 指定全局配置文件
String resource = "mybatis-config.xml";
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
// 操作CRUD,第一个参数:指定statement,规则:命名空间+“.”+statementId
// 第二个参数:指定传入sql的参数:这里是用户id
User user = sqlSession.selectOne("MyMapper.selectUser", 1);
System.out.println(user);
} finally {
sqlSession.close();
}
}
}
Mybatis-plus
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
基本用法
目录结构
添加实体类
前面已经建好了用户表,下面编写用户表对应的数据库实体类 User.java
:
@Data
@Builder
@TableName("t_user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private Integer gender;
}
@TableName("t_user")
注解用于指定表名;@TableId(type = IdType.AUTO)
注解指定了字段id
为表的主键,同时指定主键为自增类型。@Data
和@Builder
是 Lombok 注解,偷懒用的,加上它即可编译自动生成 getXXX/setXXX 等相关方法
常用注解
【@TableName 】
@TableName 用于定义表名
注:
常用属性:
value 用于定义表名
【@TableId】
@TableId 用于定义表的主键
注:
常用属性:
value 用于定义主键字段名
type 用于定义主键类型(主键策略 IdType)
主键策略:
IdType.AUTO 主键自增,系统分配,不需要手动输入
IdType.NONE 未设置主键
IdType.INPUT 需要自己输入 主键值。
IdType.ASSIGN_ID 系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)。
IdType.ASSIGN_UUID 系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)。
【@TableField】
@TableField 用于定义表的非主键字段。
注:
常用属性:
value 用于定义非主键字段名
exist 用于指明是否为数据表的字段, true 表示是,false 为不是。
fill 用于指定字段填充策略(FieldFill)。
字段填充策略:(一般用于填充 创建时间、修改时间等字段)
FieldFill.DEFAULT 默认不填充
FieldFill.INSERT 插入时填充
FieldFill.UPDATE 更新时填充
FieldFill.INSERT_UPDATE 插入、更新时填充。
【@TableLogic】
@TableLogic 用于定义表的字段进行逻辑删除(非物理删除)
注:
常用属性:
value 用于定义未删除时字段的值
delval 用于定义删除时字段的值
【@Version】
@Version 用于字段实现乐观锁
字段类型处理器TypeHandler
- MyBatis 中的 TypeHandler 类型处理器用于 JavaType 与 JdbcType 之间的转换,假设我们用户表中有一个联系方式字段,类型为字符串:
- 们通过 @TableField 注解将 FastjsonTypeHandler 这个类型处理器快速注入到 mybatis 容器中
- 使用字段类型处理器时,必须开启映射注解 @TableName(autoResultMap = true)。否则插入没问题,但查询时该字段会为空。
@Data
@TableName(autoResultMap = true)
public class UserInfo {
private Integer id;
private String userName;
private String passWord;
private Integer age;
@TableField(typeHandler = FastjsonTypeHandler.class)
private Map<String, String> contact;
}
CRUD
添加 Mapper 类
在项目根目录下创建 mapper
包,并新建 UserMapper
接口,同时继承自 BaseMapper
, 代码如下:
public interface UserMapper extends BaseMapper<User> {
}
BaseMapper
接口由 Mybatis Plus 提供,封装了一些常用的 CRUD 操作,使得我们无需像 Mybatis 那样编写 xml
文件,就拥有了基本的 CRUD 功能
public interface BaseMapper<T> extends Mapper<T> {
// 新增数据
int insert(T entity);
// 根据 ID 删除
int deleteById(Serializable id);
// 删除数据
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
// 删除数据
int delete(@Param("ew") Wrapper<T> queryWrapper);
// 根据 ID 批量删除数据
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);
// 根据 ID 更新
int updateById(@Param("et") T entity);
// 更新数据
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
// 根据 ID 查询
T selectById(Serializable id);
// 根据 ID 批量查询
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
// 查询数据
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
// 查询一条数据
T selectOne(@Param("ew") Wrapper<T> queryWrapper);
// 查询记录总数
Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);
// 查询多条数据
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
// 查询多条数据
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);
// 查询多条数据
List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);
// 分页查询
<E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);
// 分页查询
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param("ew") Wrapper<T> queryWrapper);
}
service接口方法(CRUD)
通用 Service CRUD 封装IService接口,进一步封装 CRUD。首先,新建一个接口,继承IService
public interface UserService extends IService<User> {
}
创建这个接口的实现类,并继承ServiceImpl
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserDAO, User> implements UserService {
}
条件构造器queryWrapper
上面介绍的 接口方法的参数中,会出现各种 wrapper,比如 queryWrapper、updateWrapper 等。wrapper 的作用就是用于定义各种各样的查询条件(where)。
- Wrapper : 条件构造抽象类,最顶端父类,抽象类中提供4个方法
- AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
- AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
- LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper : Lambda 更新封装Wrapper
- QueryWrapper : Entity 对象封装操作类,不是用lambda语法
- UpdateWrapper : Update 条件封装,用于Entity对象更新操作
Wrapper 条件构造抽象类
-- AbstractWrapper 查询条件封装,用于生成 sql 中的 where 语句。
-- QueryWrapper Entity 对象封装操作类,用于查询。
-- UpdateWrapper Update 条件封装操作类,用于更新。
-- AbstractLambdaWrapper 使用 Lambda 表达式封装 wrapper
-- LambdaQueryWrapper 使用 Lambda 语法封装条件,用于查询。
-- LambdaUpdateWrapper 使用 Lambda 语法封装条件,用于更新。
public void testQueryWrapper() {
// Step1:创建一个 QueryWrapper 对象
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// Step2: 构造查询条件
queryWrapper
.select("id", "name", "age")
.eq("age", 20)
.like("name", "j");
// Step3:执行查询
userService
.list(queryWrapper)
.forEach(System.out::println);
// 查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name").isNotNull("create_time").gt("age",12);
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}