课时二十七、Spring Boot MyBatis升级篇-注解
缘起:在一节视频中,有这么一段留言:“会不会推出SpringBoot整合Mybaits配置文件sqlMapConfig.xml搭配mapper.xml的视频呢??? 看到有这个整合直接付款来看,结果是急速开发模式,sql都写在类中了,想看配置方式的 ,大神出一个吧。”粉丝需求,那才是真的需求。
(1)MyBatis介绍
来源:MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
介绍:MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
(2)注解思路
在Spring Boot中使用注解集成MyBatis的话,那么核心的文件就是实体类和SQL的映射类,比如DemoMapper,在此类当中就是方法和对应的注解sql语句,那么要怎么能够识别到DemoMapper类呢,在Spring Boot中就特别的简单,在启动类App中加入一个注解@MapperScan(指定Mapper包路径)。
(3)新建project以及添加依赖包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
(4)创建启动类App.java
@SpringBootApplication
@MapperScan("com.kfit.*.mapper")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
(5)编写实体类Demo
public class Demo {
private int id;
private String name;
//省略getter and setter
}
(6)编写映射接口DemoMapper
public interface DemoMapper {
@Insert("insert into Demo(name) values(#{name})")
public void save(Demo demo);
}
(7)编写service类DemoService
@Service
public class DemoService {@Autowired
private DemoMapper demoMapper;
@Transactional//添加事务.
public void save(Demo demo){
demoMapper.save(demo);
}
}
(8)编写控制类DemoController
@RestController
public class DemoController {
@Autowired
private DemoService demoService;
@RequestMapping("/save")
public Demo save(){
Demo demo = new Demo();
demo.setName("张三");
demoService.save(demo);
return demo;
}
}
(9)配置数据库连接池
########################################################
###datasource -- mysql的数据库配置.
########################################################
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10
(10)测试
好了,到这里就可以启动App.java进行访问测试了,访问地址:
http://127.0.0.1:8080/save在访问之前需要注意:
(1)确保创建了数据库test;
(2)确保创建了表demo,建表语句如下:
CREATE TABLE demo (
id int NOT NULL AUTO_INCREMENT ,
name varchar(100) NULL ,
PRIMARY KEY (id)
);
访问之后,在浏览器端会看到数据:
{"id":0,"name":"张三"}
课时二十八、Spring Boot MyBatis升级篇-注解-自增ID
1、引言
在上一篇文章中,我们已经会集成MyBatic并且完成了保存数据的动作,但是现在如果你细心观察的话,在浏览器看到的数据中id=0。有人说:我不需要返回id呀,id返回我也用不到,返回为0的话,无所谓了。但是在实际项目中,我们是有很多场景需要用到返回的id的
场景
(2)场景2:在题库管理的时候,我们需要录入题目信息以及题库的选项,对于题库的选项是可以多个,如下:
题目:你最喜欢的是技术是?
A: Java语言 B: PHP语言 C: python语言 D:C语言
那么对于题目信息我们会保存到一张表中Question,对于选项,我们会保存到另外一张表QuestionOption,对于表QuestionOption会有一个外键qid,也就是question的主键。对于Question和QuestionOption的保存是在同一个请求就完成的(如果是题目的保存和选项的保存是两个请求才完成的,那么流程不一样)。在保存QuestionOption的时候,需要用到Question的主键,这时候后台的保存代码是这样的:
Question question = Question();
int qid = save(Question);
QuestionOption qo = new QuestionOption();
qo.setQid(qid);
int qid = save(QuestionOption);
2、示例代码
public interface DemoMapper {
@Insert("insert into Demo(name) values(#{name})")
@Options(keyProperty="id",keyColumn="id",useGeneratedKeys=true)
public void save(Demo demo);
}
在xml编写的时候,看看能不能加
3、@Options解说
@Options注解中的工作就比较有意思,我们在插入记录时,一般是定义主键自增(auto_increment),但是在某些情况下,我们插入一条记录后,还想得到这条记录的自增主键ID,useGeneratedKeys=true就是定义数据库返回主键ID的,常用的属性如下:
useCache=true,
flushCache=false,
resultSetType=FORWARD_ONLY,
statementType=PREPARED,
fetchSize= -1,timeout=-1 ,
useGeneratedKeys=false ,
keyProperty=”id“。
KeyProperty是实体类中定义的主键字段名;
KeyColumn是表中主键对应的字段;
useGeneratedKeys=true定义数据库返回主键ID;
注解中的useCache还可以设置缓存相关的选项:
useCache = true表示本次查询结果被缓存以提高下次查询速度,flushCache = false表示下次查询时不刷新缓存,timeout = 10000表示查询结果缓存10000秒。
参考spring-boot-mybatis
课时二十九、Spring Boot MyBatis升级篇-注解-增删改查
(1)update:修改操作
在原先的代码基础上进行编码,在DemoMapper类中加入:
@Update("update Demo set name=#{name} where id=#{id}")
public int update(@Param("id")int id,@Param("name")String name);使用@Update标明这是一个update语句,注意:在这里返回了int值,这个是值返回成功修改的数量,比如:成功找到了5条数据,并且修改成功了,那么返回值就是5。
(2)delete:查询操作
@Delete("delete from Demo where id=#{id}")
public int delete(int id);
(3)select all: 查询全部
@Select("select *from Demo")
public List<Demo> selectAll();
(4)select by id:根据id查询操作
@Select("select *from Demo where id=#{id}")
public Demo selectById(int id);
参考spring-boot-mybatis
课时三十、Spring Boot MyBatis升级篇-注解-分页查询
(1)集成原理说明
MyBatis提供了拦截器接口,我们可以实现自己的拦截器,将其作为一个plugin装入到SqlSessionFactory中。
(2)PageHelper介绍
PageHelper是Github上有位开发者写了一个分页插件,可以很方便的添加到MyBatis的拦截器接口中。
(3)集成准备
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.0</version>
</dependency>
(4)配置文件编写
@Configuration
public class MyBatisConfiguration {
/**
* 注册MyBatis分页插件PageHelper
* @return
*/
@Bean
public PageHelper pageHelper() {
System.out.println("MyBatisConfiguration.pageHelper()");
PageHelper pageHelper = new PageHelper();
Properties p = new Properties();
p.setProperty("offsetAsPageNum", "true");
p.setProperty("rowBoundsWithCount", "true");
p.setProperty("reasonable", "true");
pageHelper.setProperties(p);
return pageHelper;
}
}
(5)编码测试
这个使用起来特别的简单,只是在原来查询全部的代码之前加入一句:
PageHelper.startPage(1,2);
第一个参数是第几页;第二个参数是每页显示条数。
参考spring-boot-mybatis
课时三十一、Spring Boot MyBatis升级篇-注解-分页PageHelper不生效
开发步骤
在MyBatis中集成了PageHelper,然后也在需要使用分页的地方加入了如下代码:
PageHelper.startPage(1,2);
1、需要在pom.xml文件中添加PageHelper依赖;
2、需要配置一个MyBatisConfiguration -->注入了PageHelper;
3、需要在需要分页的查询前面使用PageHelper.startPage(pageNum,pageSize);分页
(1)原因1:mybatis-spring-boot-starter版本有误
这个可能你使用错了版本号,主要是pom.xml文件中的版本的引入,错误的版本引入:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>我在博客中已经写的很详细了,但是还是有人会掉进坑里,之所以会有这篇文章的出现就是因为已经有人已经掉进坑里了。那么正确的配置是:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
请不要使用1.0.0版本,因为还不支持拦截器插件,
1.3.0 是博主写帖子时候的版本,大家使用最新版本即可
(2)原因2:重新定义了SqlSessionFactory配置
第二种不好使的情况就是重新定义了SqlSessionFactory但是并没有配置对应的PageHelper插件,所以导致使用PageHelper.startPage(1,1); 无效,那么如果要重新定义SqlSessionFactory 的话
@Bean
public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Interceptor[] plugins = new Interceptor[]{pageHelper()};
sqlSessionFactoryBean.setPlugins(plugins);
// 指定mybatisxml文件路径
&