出处地址:https://www.cnblogs.com/V1haoge/p/9971036.html
SpringBoot整合Mybatis步骤第一步:添加必要的jar包第二步:添加必要的配置org.mybatis.spring.boot mybatis-spring-boot-starter1.3.1
application.properties
##配置数据源spring.datasource.url = jdbc:h2:mem:dbtest spring.datasource.username = sa spring.datasource.password = sa spring.datasource.driverClassName =org.h2.Driver第三步:添加配置类
// 该配置类用于配置自动扫描器,用于扫描自定义的mapper接口,MyBatis会针对这些接口生成代理来调用对应的XMl中的SQL@Configuration@MapperScan("com.example.springbootdemo.mapper")public class MyBatisConfig {
}第四步:定义实体类型这个注解必须手动配置是因为mapper接口的位置完全就是用户自定义的,自动配置的时候也不可能找到还不存在的位置。
@Data@NoArgsConstructor@AllArgsConstructor@ToString@EqualsAndHashCode@Builder@ApiModel("书籍模型")public class Book { @ApiModelProperty(value = "书籍ID", notes = "书籍ID",example = "1") private Integer bookId; @ApiModelProperty(value = "书籍页数", notes = "书籍页数",example = "100") private Integer pageNum; @ApiModelProperty(value = "书籍名称", notes = "书籍名称",example = "Java编程思想") private String bookName; @ApiModelProperty(value = "书籍类型", notes = "书籍类型",hidden = false) private BookType BookType; @ApiModelProperty(value = "书籍简介") private String bookDesc; @ApiModelProperty(value = "书籍价格") private Double bookPrice; @ApiModelProperty(value = "创建时间",hidden = true) private LocalDateTime createTime; @ApiModelProperty(value = "修改时间",hidden = true) private LocalDateTime modifyTime;
}还有一个枚举类型
public enum BookType {
TECHNOLOGY,//技术
LITERARY,//文学
HISTORY//历史
;
}第五步:定义mapper接口实体类中使用了swagger2和Lombok中的注解,需要添加对应的jar包
public interface BookRepository { int addBook(Book book); int updateBook(Book book); int deleteBook(int id); Book getBook(int id); List getBooks(Book book);
} 第六步:定义mapper配置INSERT INTO BOOK( PAGE_NUM, BOOK_TYPE, BOOK_NAME, BOOK_DESC, BOOK_PRICE, CREATE_TIME, MODIFY_TIME) VALUES (#{pageNum}, #{bookType}, #{bookName}, #{bookDesc}, #{bookPrice}, sysdate,sysdate)UPDATE BOOK SET PAGE_NUM = #{pageNum}, BOOK_TYPE = #{bookType}, BOOK_DESC = #{bookDesc}, BOOK_PRICE = #{bookPrice}, BOOK_NAME = #{bookName}, MODIFY_TIME=sysdate WHERe 1=1and BOOK_ID = #{bookId} delete from BOOK where BOOK_id=#{bookId}
在这个配置文件中我们使用了MyBatis的动态SQL和参数映射
第七步:再次添加必要的配置application.properties
#配置Xml配置的位置mybatis.mapper-locations=classpath*:/mapper
@Override
public void setNonNullParameter(PreparedStatement ps, int i, BookType parameter, JdbcType jdbcType) throws SQLException { int j = 0; for (BookType bookType : BookType.values()){ if(bookType.equals(parameter)){
ps.setString(i, j +""); return;
}
j++;
}
}
@Override
public BookType getNullableResult(ResultSet rs, String columnName) throws SQLException { int j = Integer.valueOf(rs.getString(columnName)); if(j >= BookType.values().length) { return null;
} int i = 0; for(BookType bookType:BookType.values()){ if(j == i){ return bookType;
}
i++;
} return null;
}
@Override
public BookType getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return null;
}
@Override
public BookType getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return null;
}
}使用@Mapper(不常用,可不看)第一步:定义实体类注意:使用@Mapper注解的时候是不需要添加xml配置Mapper文件的,SQL脚本在接口方法的注解内部定义
@Data@Builder@ToString@EqualsAndHashCode@NoArgsConstructor@AllArgsConstructorpublic class Tree { private Integer treeId; private String treeName; private Integer treeAge; private Double treeHight; private TreeType treeType; private TreeState treeState; private String treeDesc;
}第二步:定义持久层@Mapperpublic interface TreeRepository {
@Insert("INSERT INTO TREE (TREE_NAME,TREE_AGE,TREE_HIGHT,TREE_TYPE,TREE_STATE,TREE_DESC) VALUES (#{treeName},#{treeAge},#{treeHight},#{treeType},#{treeState},#{treeDesc}) ") int addTree(Tree tree);
// 此处treeState是一个枚举,此处执行一直报错
@Update("UPDATE TREE SET TREE_STATE=#{treeState} WHERe TREE_ID=#{treeId}") int updateState(final int treeId, final TreeState treeState);
@Delete("DELETE FROM TREE WHERe TREE_ID=#{treeId}") int deleteTree(final int treeId);
@Results({ @Result(id = true, column = "TREE_ID",property = "treeId"), @Result(column = "TREE_NAME",property = "treeName"), @Result(column = "TREE_AGE", property = "treeAge"), @Result(column = "TREE_HIGHT",property = "treeHight"), @Result(column = "TREE_TYPE",property = "treeType",typeHandler = EnumOrdinalTypeHandler.class), @Result(column = "TREE_STATE",property = "treeState",typeHandler = EnumOrdinalTypeHandler.class), @Result(column = "TREE_DESC", property = "treeDesc")
}) @Select("SELECT * FROM TREE WHERe TREE_ID=#{treeId}") Tree getTree(final int treeId);
@Results({ @Result(id = true, column = "TREE_ID",property = "treeId"), @Result(column = "TREE_NAME",property = "treeName"), @Result(column = "TREE_AGE", property = "treeAge"), @Result(column = "TREE_HIGHT",property = "treeHight"), @Result(column = "TREE_TYPE",property = "treeType",typeHandler = EnumOrdinalTypeHandler.class), @Result(column = "TREE_STATE",property = "treeState",typeHandler = EnumOrdinalTypeHandler.class), @Result(column = "TREE_DESC", property = "treeDesc")
}) @Select("SELECT * FROM TREE") List getTrees(RowBounds rowBounds);
} 第三步:定义service和controller注意:重点就在这个接口中,我们添加接口注解@Mapper,表示这是一个持久层Mapper,它的实例化依靠SpringBoot自动配置完成。
在接口方法上直接添加对应的执行注解,在注解中直接定义SQL,这种SQL仍然可以使用表达式#{}来获取参数的值。
注意@Result注解中定义的两个关于枚举的类型处理器EnumOrdinalTypeHandler,其实其为MyBatis内部自带的两种枚举处理器之一,
用于存储枚举序号,还有一个EnumTypeHandler用于存储枚举名称。
@Service@Log4j2public class TreeService {
@Autowired
private TreeRepository treeRepository;
public ResponseEntity addTree(final Tree tree){
treeRepository.addTree(tree); return ResponseEntity.ok(tree);
}
public ResponseEntity updateTree(final int treeId, final TreeState treeState){
treeRepository.updateState(treeId,treeState); return ResponseEntity.ok(Tree.builder().treeId(treeId).treeState(treeState).build());
}
public ResponseEntity deleteTree(final int treeId){ return ResponseEntity.ok(treeRepository.deleteTree(treeId));
}
public ResponseEntity getTree(final int treeId){ return ResponseEntity.ok(treeRepository.getTree(treeId));
}
public ResponseEntity> getTrees(final int pageId,final int pageSize){
List trees = treeRepository.getTrees(new RowBounds(pageId,pageSize));
MyPage treeMyPage = new MyPage<>();
treeMyPage.setPageId(pageId);
treeMyPage.setPageSize(pageSize);
treeMyPage.setBody(trees); return ResponseEntity.ok(treeMyPage);
}
} @RestController@RequestMapping("/tree")@Api(description = "树木接口")public class TreeApi {
@Autowired
private TreeService treeService;
@RequestMapping(value = "/addTree",method = RequestMethod.PUT) @ApiOperation(value = "添加树木",notes = "添加新树木",httpMethod = "PUT") public ResponseEntity addTree(final Tree tree){ return treeService.addTree(tree);
}
@RequestMapping(value = "/updateTree",method = RequestMethod.POST) @ApiOperation(value = "更新状态",notes = "修改树木状态",httpMethod = "POST") public ResponseEntity updateTree(final int treeId,final TreeState treeState){ return treeService.updateTree(treeId,treeState);
}
@ApiOperation(value = "获取树木",notes = "根据ID获取一棵树",httpMethod = "GET") @RequestMapping(value = "/getTree",method = RequestMethod.GET) public ResponseEntity getTree(final int treeId){ return treeService.getTree(treeId);
}
} 注意:这个例子中更新状态的时候还是无法成功,这个状态是枚举值



