通用mapper的使用步骤:
1、添加依赖:mapper-spring-boot-starter
<!-- 通用Mapper启动器 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2、配置连接数据库的四个参数
server: port: ${port:9091} spring: application: name: user-service datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/springcloud username: root password: 123456 mybatis: type-aliases-package: com.zwhxpp.user.pojo
因为用了Common Mapper,所以要指定别名包的扫描
3、编写启动类,在启动类中通过@MapperScan配置包扫描,扫描mapper包中的UserMapper接口
@SpringBootApplication @MapperScan("com.zwhxpp.user.mapper") @EnableDiscoveryClient public class UserApplication { public static void main(String[] args) { SpringApplication.run(UserApplication.class, args); } }
注意:@MapperScan是tk.mybatis包下的。import tk.mybatis.spring.annotation.MapperScan;
4、编写实体类
@Data @Table(name = "tb_user") public class User{ @Id @KeySql(useGeneratedKeys = true)//开启主键自动回填 private Long id; private String userName;// 用户名 private String password;// 密码 private String name;// 姓名 private Integer age;// 年龄 private Integer sex;// 性别,1男性,2女性 private Date birthday; // 出生日期 private Date created;// 创建时间 private Date updated;// 更新时间 private String note;// 备注 }
由于是直接与数据库交互,所以要用到Common Mapper中的注解:@Table、@Id、@KeySQL
import tk.mybatis.mapper.annotation.KeySql;
@KeySql(useGeneratedKeys = true)//开启主键自动回填
当主键是自增的情况下,添加一条记录的同时,其主键是不能使用的,但是有时我们需要该主键,我们设置useGeneratedKeys="true",这样在之后的java代码中我们就可以获取该主键对应的对象的属性值。useGeneratedKeys 取值范围true|false 默认值是:false。 含义:设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。
在springboot项目中相应的配置为:
#允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。 default:false
mybatis.configuration.use-generated-keys=true
插入数据后返回自增ID的方法
1、使用last_insert_id
<insert id="saveUser" parameterType="USER"> <!-- 配置保存时获取插入的 id -->
<selectKey keyColumn="id" keyProperty="id" resultType="int"> select last_insert_id(); </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert>
2、使用 JDBC 方式获取主键,即配置@KeySql(useGeneratedKeys = true)
boolean useGeneratedKeys() default false;
是否使用 JDBC 方式获取主键,优先级最高,设置为 true 后,不对其他配置校验
3、order()和取主键的 SQL配合使用
String sql() default "";
ORDER order() default ORDER.DEFAULT;
如:
@KeySql(sql = "select OUTPUT_SEQ.nextval from dual", order = ORDER.BEFORE)
xml的方式
<selectKey keyProperty="rptqueryId" order="before" resultType="long"> select rpt_seq$seq.nextval from dual </selectKey>
5、编写UserMapper接口,去操作数据库
import com.zwhxpp.user.pojo.User; import tk.mybatis.mapper.common.Mapper; public interface UserMapper extends Mapper<User> { }
6、编写UserService类,调用Mapper接口的方法进行数据库操作
@Service public class UserService { @Autowired private UserMapper userMapper; public User queryById(Long id){ User user = userMapper.selectByPrimaryKey(id); System.out.println(user); return user; } }
7、编写UserController
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public User queryById(@PathVariable Long id){ /*try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }*/ User user = userService.queryById(id); return user; } }
通用Mapper的方法:
BaseMapper
@RegisterMapper public interface Mapper<T> extends BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>, Marker { }
@RegisterMapper
public interface BaseMapper<T> extends BaseSelectMapper<T>, BaseInsertMapper<T>, BaseUpdateMapper<T>, BaseDeleteMapper<T> {
}
@RegisterMapper
public interface BaseSelectMapper<T> extends SelectOneMapper<T>, SelectMapper<T>, SelectAllMapper<T>, 、SelectCountMapper<T>,
SelectByPrimaryKeyMapper<T>,ExistsWithPrimaryKeyMapper<T> {
}
在BaseMapper的增删改查方法中,insert和update时一般使用带selective的方法。select和delete可以根据主键进行查询或删除,也可以根据一个对象进行查询或删除。
1、BaseSelectMapper的方法:
Mapper继承BaseMapper(基础Mapper),BaseMapper继承BaseSelectMapper(基础selectMapper)
1)、接口:`SelectByPrimaryKeyMapper<T>`
方法:`T selectByPrimaryKey(Object key);`
说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号(参数为主键,只能查出一条记录)
User _user = (User) _rs.getData(); Enterprise enterprise = enterpriseMapper.selectByPrimaryKey(u.getEnterpriseId());
2)、接口:`SelectMapper<T>`
方法:`List<T> select(T record);`
说明:根据实体中的属性值进行查询,查询条件使用等号(参数为对象,可以查出多条记录)
User user1 = new User(); user1.setEnterpriseId(user.getEnterpriseId()); user1.setDelFlag(0); List<User> list1 = userMapper.select(user1);
3)、接口:`SelectAllMapper<T>`
方法:`List<T> selectAll();`
说明:查询全部结果,select(null)方法能达到同样的效果(五参数,查询所有记录)
public List<User> getUsers() { return userMapper.selectAll(); }
4)、接口:`SelectOneMapper<T>`
方法:`T selectOne(T record);`
说明:根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号(参数为对象,只能查出一条记录)
Output output = new Output(); output.setEnterpriseId(p.getEnterpriseId()); output.setMesNodeNo(materialType); Output selectOne = traceabilityOutputMapper.selectOne(output);
5)、接口:`SelectCountMapper<T>`
方法:`int selectCount(T record);`
说明:根据实体中的属性查询总数,查询条件使用等号(参数为对象)
ProductFeedBK checkExisted = new ProductFeedBK(); checkExisted.setTransactionId(productFeedERPDetailInfo.getTransactionId()); if (org.apache.commons.lang3.StringUtils.isNotBlank(productFeedERPDetailInfo.getInLotNum())) { checkExisted.setInLotNum(productFeedERPDetailInfo.getInLotNum()); } if (org.apache.commons.lang3.StringUtils.isNotBlank(productFeedERPDetailInfo.getOutLotNum())) { checkExisted.setOutLotNum(productFeedERPDetailInfo.getOutLotNum()); } int count = productFeedBKMapper.selectCount(checkExisted);
2、BaseInsertMapper的方法:
Mapper继承BaseMapper(基础Mapper),BaseMapper继承BaseInsertMapper(基础InsertMapper)
1)、接口:`InsertMapper<T>`
方法:`int insert(T record);`
说明:保存一个实体,null的属性也会保存,不会使用数据库默认值
2)、接口:`InsertSelectiveMapper<T>`
方法:`int insertSelective(T record);`(参数为对象)
UserRole userRole = new UserRole(); userRole.setDelFlag(0); userRole.setCreateBy(user.getUserName()); userRole.setCreateTime(new Date()); userRole.setRoleId(Integer.parseInt(list.get(i).toString())); userRole.setUserId(user.getUserId()); userRoleMapper.insertSelective(userRole);
说明:保存一个实体,null的属性不会保存,会使用数据库默认值
3、BaseUpdateMapper的方法:
1)、接口:`UpdateByPrimaryKeyMapper<T>`
方法:`int updateByPrimaryKey(T record);`
说明:根据主键更新实体全部字段,null值会被更新
2)、接口:`UpdateByPrimaryKeySelectiveMapper<T>`
方法:`int updateByPrimaryKeySelective(T record);`
说明:根据主键更新属性不为null的值(参数为对象,除了有主键作为一个条件外,还需要其他属性作为条件)
public boolean changePassword(Integer userId) { User user = new User(); user.setUserId(userId); user.setPwdUpdateFlag("1"); int i = userMapper.updateByPrimaryKeySelective(user); if (i != 0) { return true; } return false; }
4、BaseDeleteMapper的方法
1)、接口:`DeleteMapper<T>`
方法:`int delete(T record);`
说明:根据实体属性作为条件进行删除,查询条件使用等号
ExtractProduct tmp = new ExtractProduct(); tmp.setProductId(traceabilityProduct.getId()); extractProductMap.delete(tmp);
2)、接口:`DeleteByPrimaryKeyMapper<T>`
方法:`int deleteByPrimaryKey(Object key);`
说明:根据主键字段进行删除,方法参数必须包含完整的主键属性(参数为对象,主键作为唯一条件)
AtomicInteger a = new AtomicInteger(); String[] idArr = ids.split(","); for (int i = 0; i < idArr.length; i++) { ErpProductInfo productInfo = new ErpProductInfo(); productInfo.setProductId(Integer.parseInt(idArr[i])); a.set(productMapper.deleteByPrimaryKey(productInfo)); }
ExampleMapper
@RegisterMapper public interface Mapper<T> extends BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>, Marker { }
@RegisterMapper
public interface ExampleMapper<T> extends SelectByExampleMapper<T>, SelectOneByExampleMapper<T>, SelectCountByExampleMapper<T>,
DeleteByExampleMapper<T>,UpdateByExampleMapper<T>, UpdateByExampleSelectiveMapper<T> {
}
示例:
Example placeExample = new Example(Place.class); Example.Criteria placeCriteria = placeExample.createCriteria(); placeCriteria.andEqualTo("delFlag", "0"); List<Place> places = placeMapper.selectByExample(placeExample);
常用selectByExample、updateByExampleSelective、deleteByExample这三个方法,没有insertByExample。
ExampleMapper的方法:
1)、接口:`SelectByExampleMapper<T>`
方法:`List<T> selectByExample(Object example);`
说明:根据Example条件进行查询
重点:这个查询支持通过`Example`类指定查询列,通过`selectProperties`方法指定查询列
Example example = new Example(IntelDrugStore.class); example.createCriteria().andEqualTo("equipmentCode", equipmentCode1) .andEqualTo("equipmentType",equipmentType) .andEqualTo("hospitalName",hospitalName); intelDrugStores = intelDrugStoreMapper.selectByExample(example);
2)、接口:`SelectOneByExampleMapper<T>`
方法:`T selectOneByExample(Object example);`
说明:根据Example条件进行查询一条记录
Example example = new Example(User.class); example.createCriteria() .andEqualTo("userName", user.getUserName()) .andEqualTo("delFlag", 0); User curUser = userMapper.selectOneByExample(example); if (null == curUser) { rs.setSuccess(false); rs.setMsg("用户名不存在!"); rs.setCode(ResultCode.SUCCESS); return rs; }
3)、接口:`SelectCountByExampleMapper<T>`
方法:`int selectCountByExample(Object example);`
说明:根据Example条件进行查询总数
public int queryCount(String enterpiseType, String enterpriseName, String enterpiseCode, String organizationCode) { Example example = new Example(Enterprise.class); Example.Criteria criteria = example.createCriteria(); criteria.andEqualTo("delFlag", 0); if (!StringUtils.isEmpty(enterpiseType)) { criteria.andEqualTo("enterpiseType", enterpiseType); } if (!StringUtils.isEmpty(enterpriseName)) { criteria.andLike("enterpriseName", "%" + enterpriseName + "%"); } if (!StringUtils.isEmpty(enterpiseCode)) { criteria.andLike("enterpiseCode", "%" + enterpiseCode + "%"); } if (!StringUtils.isEmpty(organizationCode)) { criteria.andLike("organizationCode", "%" + organizationCode + "%"); } return enterpriseMapper.selectCountByExample(example); }
4)、接口:`UpdateByExampleMapper<T>`
方法:`int updateByExample(@Param("record") T record, @Param("example") Object example);`
说明:根据Example条件更新实体`record`包含的全部属性,null值会被更新
5)、接口:`UpdateByExampleSelectiveMapper<T>`
方法:`int updateByExampleSelective(@Param("record") T record, @Param("example") Object example);`
说明:根据Example条件更新实体`record`包含的不是null的属性值
TraceabilityExtract traceabilityExtract = new TraceabilityExtract(); traceabilityExtract.setMaterialName(medSeed.getMaterialCommonName()); Example example = new Example(TraceabilityExtract.class); example.createCriteria().andEqualTo("materialCode", medSeed.getMaterialCode()); traceabilityExtractMapper.updateByExampleSelective(traceabilityExtract, example);
6)、接口:`DeleteByExampleMapper<T>`
方法:`int deleteByExample(Object example);`
说明:根据Example条件删除数据
//查询设备名称1是否存在,如果存在则删除,如果不存在则新增 List<IntelDrugStore> intelDrugStoreList1 = new ArrayList<>(); Example example = new Example(IntelDrugStore.class); example.createCriteria().andEqualTo("equipmentCode", equipmentCode1) .andEqualTo("equipmentType",equipmentType) .andEqualTo("hospitalName",hospitalName); intelDrugStoreList1 = intelDrugStoreMapper.selectByExample(example); if(CollectionUtils.isNotEmpty(intelDrugStoreList1)){ intelDrugStoreMapper.deleteByExample(example); }
RowBoundsMapper
@RegisterMapper public interface Mapper<T> extends BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>, Marker { } @RegisterMapper public interface RowBoundsMapper<T> extends SelectByExampleRowBoundsMapper<T>, SelectRowBoundsMapper<T> { }
1)、接口:`SelectRowBoundsMapper<T>`
方法:`List<T> selectByRowBounds(T record, RowBounds rowBounds);`
说明:根据实体属性和RowBounds进行分页查询
2)、接口:`SelectByExampleRowBoundsMapper<T>`
方法:`List<T> selectByExampleAndRowBounds(Object example, RowBounds rowBounds);`
说明:根据example条件和RowBounds进行分页查询