文章目录
- JDBC
- Mybatis
- Mybatis-plus
- 基本用法
- 目录结构
- 常用注解
- 字段类型处理器TypeHandler
- CRUD
- service接口方法(CRUD)
- 条件构造器queryWrapper
- QueryWrapper的方法
官方文档: 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,preparedStatementString 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);// 构建sqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 获取sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();try {// 操作CRUD,第一个参数:指定statement,规则:命名空间+“.”+statementId// 第二个参数:指定传入sql的参数:这里是用户idUser 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);}