本篇博客将通过 mybatis 来实现常用的数据增加、删除、修改、查询和分页功能。
1.创建项目 & 引入依赖
创建一个 spring boot 项目,并引入 mybatis 和 mysql 依赖。
<dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.mybatis.spring.boot</groupid> <artifactid>mybatis-spring-boot-starter</artifactid> <version>2.0.0</version> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-devtools</artifactid> <scope>runtime</scope> </dependency> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <scope>runtime</scope> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <optional>true</optional> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> </dependencies>
2.实现数据表的自动初始化
在项目的 resources
目录下新建 db
目录,并添加 schema.sql
文件,然后在此文件中写入创建 user
表的 sql 语句,以便进行初始化数据表。具体代码如下:
drop table if exists `user`; create table `user` ( `id` int(11) not null auto_increment, `name` varchar(255) default null, `age` int(11) default null, primary key (`id`) ) engine=innodb default charset=utf8;
在 application.properties
配置文件中配置数据库连接,并加上数据表初始化的配置。具体代码如下:
spring.datasource.initialize=true spring.datasource.initialization-mode=always spring.datasource.schema=classpath:db/schema.sql
完整的 application.properties
文件如下:
spring.datasource.url=jdbc:mysql://127.0.0.1/book?useunicode=true&characterencoding=utf-8&servertimezone=utc&usessl=true spring.datasource.username=xxxx spring.datasource.password=xxxxxx spring.datasource.driver-class-name=com.mysql.cj.jdbc.driver spring.jpa.properties.hibernate.hbm2ddl.auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.mysql5innodbdialect spring.jpa.show-sql=true spring.datasource.initialization-mode=always spring.datasource.schema=classpath:db/schema.sql spring.thymeleaf.cache=false server.port=8080
这样,spring boot 在启动时就会自动创建 user
表。
3.实现实体对象建模
用 mybatis 来创建实体,见以下代码:
package com.example.demo.entity; import lombok.data; @data public class user { private int id; private string name; private int age; }
从上述代码可以看出,用 mybatis 创建实体是不需要添加注解 @entity
的,因为 @entity
属于 jpa 的专属注解。
4.实现实体和数据表的映射关系
实现实体和数据表的映射关系可以在 mapper 类上添加注解 @mapper
,见以下代码。建议以后直接在入口类加 @mapperscan("com.example.demo.mapper")
,如果对每个 mapper 都加注解则很麻烦。
package com.example.demo.mapper; import com.example.demo.entity.user; import com.github.pagehelper.page; import org.apache.ibatis.annotations.*; import java.util.list; @mapper public interface usermapper { @select("select * from user where id = #{id}") user querybyid(@param("id") int id); @select("select * from user") list<user> queryall(); @insert({"insert into user(name,age) values(#{name},#{age})"}) int add(user user); @delete("delete from user where id = #{id}") int delbyid(int id); @update("update user set name=#{name},age=#{age} where id = #{id}") int updatebyid(user user); @select("select * from user") page<user> getuserlist(); }
5.实现增加、删除、修改和查询功能
创建控制器实现操作数据的 api,见以下代码:
package com.example.demo.controller; import com.example.demo.entity.user; import com.example.demo.mapper.usermapper; import org.springframework.beans.factory.annotation.autowired; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.restcontroller; import java.util.list; @restcontroller @requestmapping("/user") public class usercontroller { @autowired usermapper usermapper; @requestmapping("/querybyid") user querybyid(int id) { return usermapper.querybyid(id); } @requestmapping("/") list<user> queryall() { return usermapper.queryall(); } @requestmapping("/add") string add(user user) { return usermapper.add(user) == 1 ? "success" : "failed"; } @requestmapping("/updatebyid") string updatebyid(user user) { return usermapper.updatebyid(user) == 1 ? "success" : "failed"; } @requestmapping("/delbyid") string delbyid(int id) { return usermapper.delbyid(id) == 1 ? "success" : "failed"; } }
- 启动项目,访问
http://localhost:8080/user/add?name=pp&age=20
,会自动添加一个name=pp
、age=20
的数据。
- 访问
http://localhost:8080/user/updatebyid?name=pipi&age=26&id=1
,会实现对id=1
的数据的更新,更新为name=pipi
、age=26
。
- 访问
http://localhost:8080/user/querybyid?id=1
,可以查找到id=1
的数据,此时的数据是name=pipi
、age=26
。
- 访问
http://localhost:8080/user/
,可以查询出所有的数据。
- 访问
http://localhost:8080/user/delbyid?id=1
,可以删除id
为1
的数据。
6.配置分页功能
6.1 增加分页支持
分页功能可以通过 pagehelper
来实现。要使用 pagehelper
,则需要添加如下依赖,并增加 thymeleaf
支持。
<!-- 增加对pagehelper的支持 --> <dependency> <groupid>com.github.pagehelper</groupid> <artifactid>pagehelper</artifactid> <version>4.1.6</version> </dependency> <!--增加thymeleaf支持--> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-thymeleaf</artifactid> </dependency>
6.2 创建分页配置类
创建分页配置类来实现分页的配置,见以下代码:
package com.example.demo.config; import com.github.pagehelper.pagehelper; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import java.util.properties; @configuration public class pagehelperconfig { @bean public pagehelper 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; } }
代码解释如下。
@configuration
:表示 pagehelperconfig 这个类是用来做配置的。@bean
:表示启动 pagehelper 拦截器。offsetaspagenum
:设置为true
时,会将 rowbounds 第一个参数offset
当成pagenum
页码使用。rowboundswithcount
:设置为true
时,使用 rowbounds 分页会进行count
查询。reasonable
:启用合理化时,如果pagenum<1
会查询第一页,如果pagenum>pages
会查询最后一页。
7.实现分页控制器
创建分页列表控制器,用以显示分页页面,见以下代码:
package com.example.demo.controller; import com.example.demo.entity.user; import com.example.demo.mapper.usermapper; import com.github.pagehelper.pagehelper; import com.github.pagehelper.pageinfo; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.controller; import org.springframework.ui.model; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.requestparam; import java.util.list; @controller public class userlistcontroller { @autowired usermapper usermapper; @requestmapping("/listall") public string listcategory(model m, @requestparam(value="start", defaultvalue="0")int start, @requestparam(value="size", defaultvalue="5") int size) throws exception { pagehelper.startpage(start,size,"id desc"); list<user> cs = usermapper.queryall(); pageinfo<user> page = new pageinfo<>(cs); m.addattribute("page", page); return "list"; } }
start
:在参数里接收当前是第几页。默认值是0
。size
:每页显示多少条数据。默认值是5
。pagehelper.startpage(start,size,"id desc")
: 根据start
、size
进行分页,并且设置id
倒排序。list<user>
:返回当前分页的集合。pageinfo<user>
:根据返回的集合创建 pagelnfo 对象。model.addattribute("page", page)
:把page
(pageinfo
对象)传递给视图,以供后续显示。
8.创建分页视图
接下来,创建用于视图显示的 list.html
,其路径为 resources/template/list.html
。
在视图中,通过 page.pagenum
获取当前页码,通过 page.pages
获取总页码数,见以下代码:
<div class="with:80%"> <div th:each="u : ${page.list}"> <span scope="row" th:text="${u.id}">id</span> <span th:text="${u.name}">name</span> </div> </div> <div> <a th:href="@{listall?start=1}" rel="external nofollow" >[首页]</a> <a th:href="@{/listall(start=${page.pagenum-1})}" rel="external nofollow" rel="external nofollow" >[上页]</a> <a th:href="@{/listall(start=${page.pagenum+1})}" rel="external nofollow" rel="external nofollow" >[下页]</a> <a th:href="@{/listall(start=${page.pages})}" rel="external nofollow" rel="external nofollow" >[末页]</a> <div>当前页/总页数:<a th:text="${page.pagenum}" th:href="@{/listall(start=${page.pagenum})}" rel="external nofollow" ></a> /<a th:text="${page.pages}" th:href="@{/listall(start=${page.pages})}" rel="external nofollow" rel="external nofollow" ></a></div> </div>
启动项目,多次访问 http://localhost:8080/user/add?name=pp&age=26
增加数据,然后访问 http://localhost:8080/listall
可以查看到分页列表。
但是,上述代码有一个缺陷:显示分页处无论数据多少都会显示“上页、下页”。所以,需要通过以下代码加入判断,如果没有上页或下页则不显示。
<a th:if="${not page.isfirstpage}" th:href="@{/listall(start=${page.pagenum-1})}" rel="external nofollow" rel="external nofollow" >[上页]</a> <a th:if="${not page.islastpage}" th:href="@{/listall(start=${page.pagenum+1})}" rel="external nofollow" rel="external nofollow" >[下页]</a>
上述代码的作用是:如果是第一页,则不显示“上页”;如果是最后一页,则不显示“下页”。
还有一种更简单的方法:在 mapper 中直接返回 page 对象,见以下代码:
@select("select * from user") page<user> getuserlist();
然后在控制器中这样使用:
package com.example.demo.controller; import com.example.demo.entity.user; import com.example.demo.mapper.usermapper; import com.github.pagehelper.page; import com.github.pagehelper.pagehelper; import org.springframework.beans.factory.annotation.autowired; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.requestparam; import org.springframework.web.bind.annotation.restcontroller; @restcontroller public class userlistcontrollerb { @autowired usermapper usermapper; // http://localhost:8080/listall2?pagenum=1&pagesize=2 @requestmapping("/listall2") // 如果方法的参数不指定默认值,且请求地址也没有指定参数值,则项目运行时会报错。 public page<user> getuserlist(@requestparam(value="pagenum",defaultvalue="0")int pagenum, @requestparam(value = "pagesize", defaultvalue = "5") int pagesize) //public page<user> getuserlist(integer pagenum, integer pagesize) { pagehelper.startpage(pagenum, pagesize); page<user> userlist= usermapper.getuserlist(); return userlist; } }
代码解释如下。
pagenum
:页码。pagesize
:每页显示多少记录。
以上就是springboot使用mybatis实现数据的crud的详细内容,更多关于springboot mybatis数据crud的资料请关注代码网其它相关文章!
发表评论