通用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進行分頁查詢