说在前面:
对于持久层的操作,一般多用于Mybatis框架,对于Mybatis的使用,需要书写大量的mapper映射文件,在进行业务修改的同时还有大量的SQL语句的变化。而且,如果要是数据库表字段发生变化,就需要改变对应的实体类和SQL语句,使得开发效率变得低下。从而通用的持久层mapper就出现了,现在有很多进行对持久层的框架,像Hibernate、Spring Data JPA、还有其他,都是对基本的数据库操作的封装;
此篇文章对通用mapper,tk.mapper进行简单描述:
什么是通用mapper:
通用mapper就是为了解决单表的增删改查,基于Mybatis的插件。开发人员不需要编写SQL语句,不需要在持久层书写方法,只需要写好实体类,就能够支持响应的增删查改方法。
以前如何使用
//比如一个实体类
private Integer userId;
private String userName;
private String userPassword;
private String userEmail;
private Date userBirthday;
private String userHobbys;
private Integer userSex;
private String userAddress;
private String userPhoto;
//对应一个Dao 有许多方法
public interface UserDao {
findByxx();
deleteByxxx();
addxxx();
updatexxx();
}
//在一个实体类Mapper.xml文件 里面书写和Dao对应的方法的sql语句 十分繁琐
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxx.mapper.UserMapper">
如何使用现在的
先引入依赖
Maven下载
<!-- 通用Mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.1.5</version>
</dependency>
在对通用mapper进行配置
<!-- 通用 Mapper
当然还有很多参数,一般使用不到,需要的话可以参考使用手册,此处我就不过多去说明
-->
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.com.bluemoon.bd.service.spider.dao"/>
<property name="properties">
<value>
mappers=tk.mybatis.mapper.common.Mapper
</value>
</property>
</bean>
现在的如何使用
实体类的写法
@Table(name = "tbl_user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "JDBC")
private Long id;
@Transient //此注解是映射对属性进行忽略
private String userId;
private String name;
private Timestamp createTime;
private String createUserId;
private Timestamp updateTime;
private String updateUserId;
private Integer isDelete;
// 省略get、set方法...
}
/**
字段的命名规则
1.推荐命名规则使用驼峰式
2.对应数据库的字段主键上面使用@Id注解,如果是Mysql数据库主键默认自增的话 后面加上主键生成策略@GeneratedValue(generator = “JDBC”)即可,其他数据库可参考使用手册
3.使用 @Transient 注解,表明忽略此属性,数据库表不会使用此字段。
4.
**/
DAO的写法
public interface UserDao extends Mapper<User> {
}
//继承通用Mapper 必须指定泛型
通用Mapper下的方法
继承了此接口,就拥有了此接口的通用方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JKG5P4EK-1618730108039)(C:\Users\肖森波\AppData\Roaming\Typora\typora-user-images\image-20210418145940288.png)]
Select
方法:
List<T> select(T record);
说明:根据实体中的属性值进行查询,查询条件使用等号
方法:
T selectByPrimaryKey(Object key);
说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号
方法:
List<T> selectAll();
说明:查询全部结果,select(null)方法能达到同样的效果
方法:
T selectOne(T record);
说明:根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号
方法:
int selectCount(T record);
说明:根据实体中的属性查询总数,查询条件使用等号
Insert
方法:
int insert(T record);
说明:保存一个实体,null的属性也会保存,不会使用数据库默认值
方法:
int insertSelective(T record);
说明:保存一个实体,null的属性不会保存,会使用数据库默认值
Update
方法:
int updateByPrimaryKey(T record);
说明:根据主键更新实体全部字段,null值会被更新
方法:
int updateByPrimaryKeySelective(T record);
说明:根据主键更新属性不为null的值
Delete
方法:
int delete(T record);
说明:根据实体属性作为条件进行删除,查询条件使用等号
方法:
int deleteByPrimaryKey(Object key);
说明:根据主键字段进行删除,方法参数必须包含完整的主键属性
Example方法
方法:
List<T> selectByExample(Object example);
说明:根据Example条件进行查询
重点:这个查询支持通过Example类指定查询列,通过selectProperties方法指定查询列
方法:
int selectCountByExample(Object example);
说明:根据Example条件进行查询总数
方法:
int updateByExample(@Param("record") T record, @Param("example") Object example);
说明:根据Example条件更新实体record包含的全部属性,null值会被更新
方法:
int updateByExampleSelective(@Param("record") T record, @Param("example") Object example);
说明:根据Example条件更新实体record包含的不是null的属性值
方法:
int deleteByExample(Object example);
说明:根据Example条件删除数据
代码中使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xmPPbPjw-1618730108042)(C:\Users\肖森波\AppData\Roaming\Typora\typora-user-images\image-20210418150326401.png)]
//增
int insert = userDao.insert(user);
//删
int delete = userDao.delete(user);
//改
User user1 = userDao.selectOne(user);
//查
int i = userDao.updateByPrimaryKey(user);
总的来说:
优点:
通用Mapper的原理是通过反射获取实体类的信息,构造出相应的SQL,因此我们只需要维护好实体类即可,对于应付复杂多变的需求提供了很大的便利。
上文叙述的只是通用Mapper的简单用法,在实际项目中,还是要根据业务,在通用Mapper的基础上封装出粒度更大、更通用、更好用的方法。
缺点:
继承了很多不必要使用的方法,使代码变的繁琐起来,相对这一点跟实现ORM思想的Hibernate、JPA的框架还有所差别,