springboot3.0整合mybatis

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

分类: springboot 专栏: springboot3.0新教材 标签: 整合mybatis

2023-12-28 17:14:01 1325浏览

springboot3.0整合mybatis

前期回顾

  • 什么是浏览器同源策略?
  • 跨域有几种解决方案
  • 全局统一异常处理用什么注解?
  • thymeleaf模板技术常用表达式说几个
  • swagger是什么技术?有什么作用和优势?

使用注解查询

核心流程:

以下这张表作为演示案例

1.加依赖

切记:springboot版本是3.0.0的话,mybatis的版本必须是3.0.3

不过:如果你项目中用了swagger,那springboot版本用2.7.1,mybatis版本用2.1.2

 <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.16</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>3.0.3</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

其中mybatis-spring-boot-starter是重点,是MyBatis官方提供的整合包。

2.application.properties

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql:///bookstore?characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456

其中type表示使用Druid连接池数据源,如果不配置,则使用默认的连接池Hikari

book实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private Integer id;
    private String name;
    private Double price;
    private String category;
    private Integer pnum;
    private String imgurl;
    private String description;
    private String author;
    private Integer sales;
}

3.mapper接口

@Mapper
public interface BookMapper {
    @Select("select * from book")
    public List<Book> findAllBooks();  //查询所有书

    @Select("select * from book where id=#{id}")
    public Book findBookById(int id);  //根据id号查找一本书

    @Insert("insert into book values(null,#{name},#{price},#{category},#{pnum},#{imgurl},#{description},#{author},#{sales})")
    public void addBook(Book book);   //添加一本书

    @Update("update book set name=#{name},price=#{price},category=#{category}, " +
            "pnum=${pnum},imgurl=#{imgurl},description=#{description}," +
            "author=#{author},sales=#{sales} where id=#{id}")
    public void updateBook(Book book);  //修改一本书

    @Delete("delete from book where id=#{id}")
    public void deleteBook(int id);  //删除一本书

}

MyBatis项目的所有数据访问层接口都要添加@Mapper注解,也可以都不添加,但要在Spring Boot入口类中添加@MapperScan("包名")注解,这样会自动扫描所有该包下的接口。

4.前端页面核心代码

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>图书信息列表</title>
</head>
<body>
<a th:href="@{/addBook}">添加新书</a>

<table border="1" align="center">
    <tr>
        <td>编号</td>
        <td>书名</td>
        <td>价格</td>
        <td>类目</td>
        <td>库存</td>
        <td>图片</td>
        <td>说明</td>
        <td>作者</td>
        <td>已售</td>

    </tr>
    <tr th:each="book:${books}">
        <td th:text="${book.id}"></td>
        <td th:text="${book.name}"></td>
        <td th:text="${book.price}"></td>
        <td th:text="${book.category}"></td>
        <td th:text="${book.pnum}"></td>
        <td th:text="${book.imgurl}"></td>
        <td th:text="${book.description}"></td>
        <td th:text="${book.author}"></td>
        <td th:text="${book.sales}"></td>
    </tr>

</table>

</body>
</html>

5.效果

动态查询

@SelectProvider、@InsertProvider、@UpdateProvider、@DeleteProvider注解实现动态增删改查。下面以@SelectProvider注解为例进行说明。

1.添加@SelectProvider注解

@SelectProvider(method = "searchBookSql",type = SqlContext.class) //动态查询
public List<Book> searchBooks(Book book);

2.动态sql类

上述代码的@SelectProvider注解中type属性表示要调用的类,method属性表示需要调用上述类中的方法名称,该方法用于创建动态的SQL查询语句。在同一个包下创建类SqlContext,创建方法searchBookSql。

public class SqlContext {
    //构造动态查询图书的SQL语句
    public String searchBookSql(Book book){
        return new SQL(){
            { SELECT("*");
                FROM("book");
                if(book.getName()!=null&&book.getName()!=""){
                    WHERE(" name like '%' #{name} '%'");
                }
                if(book.getCategory()!=null&&book.getCategory()!=""){
                    WHERE(" category=#{category}");
                }
                if(book.getAuthor()!=null&&book.getAuthor()!=""){
                    WHERE(" author=#{author}");
                }
            }
        }.toString();
    }
}

其余步骤就是常规操作,service和controller的写法跟之前一样。

3.补充-动态sql的另一种写法

@Mapper
public interface EtStuMapper {
	
		
	@Select("select * from et_stu where id = #{0}")
    public EtStu getById(String  id);   
	
	@Insert("insert into et_stu (upass,realname,stu_no,sex,sys_id,major_id) values (#{upass},#{realname},#{stu_no},#{sex},#{sys_id},#{major_id}) ")
	public void insert(EtStu o); 
	
	
	@Update("<script>update et_stu "
			+"<trim prefix=\"set\" suffixOverrides=\",\">"
			+"<if test=\"realname != null and realname != ''\">realname = #{realname},</if>"
			+"<if test=\"stu_no != null and stu_no != ''\">stu_no = #{stu_no},</if>"
			+"<if test=\"sex != null and sex != ''\">sex = #{sex},</if>"
			+"<if test=\"upass != null and upass != ''\">upass = #{upass},</if>"
			+"<if test=\"sys_id != null and sys_id != ''\">sys_id = #{sys_id},</if>"
			+"<if test=\"major_id != null and major_id != ''\">major_id = #{major_id},</if>"
			+"</trim> where id=#{id}</script>")
    public void update(EtStu o);
	
	@Select("<script>select s.*,y.sys_name,m.major_name from et_stu s left join et_system y on y.id=s.sys_id "
			+ "left join et_major m on m.id=s.major_id where 1=1"
			+"<if test=\"realname != null and realname !='' \"> and  realname  like concat('%',#{realname},'%') </if>"
			+"<if test=\"stu_no != null and stu_no !='' \"> and  stu_no = #{stu_no} </if>"
			+"<if test=\"sys_id != null and sys_id !='' \"> and  sys_id = #{sys_id} </if>"
			+"<if test=\"major_id != null and major_id !='' \"> and  major_id = #{major_id} </if>"
			+"<if test=\"upass != null and upass !='' \"> and  upass = #{upass} </if>"
			+"</script>")
    public List<EtStu> list(EtStu o);
	
	
	@Delete("delete from et_stu where id = #{0}")
	public void delete(String id);
	 
}

分页查询

1.导入依赖

<!--pagehelper分页插件-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper-spring-boot-starter</artifactId>
      <version>2.0.0</version>
    </dependency>

2.配置分页属性

pagehelper:
  helper-dialect: mysql  #指明当前查询的是MySQL数据库
  reasonable: true  #启用合理化,当pageNum小于1时查询第1页,当pageNum大于页数时查询最后一页
  support-methods-arguments: true #是否自动分页,依据的是入参,如果参数中有pageNum,pageSize分页参数,则会自动分页
  params: count=countSql #如果POJO或者Map中发现了countSql属性,就作为count参数使用

3.后端分页核心代码

 @GetMapping("/booksPage")
    public ModelAndView booksPage(@RequestParam(value="start",defaultValue = "1")int start,
                                  @RequestParam(value="size",defaultValue = "3") int size){ //默认查询第1页,每页显示3条
        PageHelper.startPage(start,size,"id asc"); //表示起始页为start每页显示size条根据id升序排序进行分页
        List<Book> books=bookService.findAllBooks();
        PageInfo<Book> page=new PageInfo<>(books);
        ModelAndView mv=new ModelAndView();
        mv.addObject("page",page);
        mv.setViewName("bookslistPage");
        return mv;
    }

4.前端分页核心代码

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>图书信息列表</title>
</head>
<body>

<table border="1" align="center">
    <tr>
        <td>编号</td>
        <td>书名</td>
        <td>库存</td>
        <td>价格</td>
        <td>类目</td>
        <td>说明</td>
        <td>图片</td>
        <td>作者</td>
        <td>已售</td>

    </tr>
<tr th:each="book:${page.list}">
        <td th:text="${book.id}"></td>
        <td th:text="${book.name}"></td>
        <td th:text="${book.pnum}"></td>
        <td th:text="${book.price}"></td>
        <td th:text="${book.category}"></td>
        <td th:text="${book.description}"></td>
        <td th:text="${book.imgurl}"></td>
        <td th:text="${book.author}"></td>
        <td th:text="${book.sales}"></td>
</tr>

</table>
<br/>
总页数:<span th:text="${page.pages}"></span>
总记录数:<span th:text="${page.total}"></span>
页面尺寸:<span th:text="${page.pageSize}"></span>
当前页记录数:<span th:text="${page.size}"></span>
<span th:if="${page.hasPreviousPage}">
    <a th:href="@{/book/page(pageNum=${page.pageNum-1})}">上一页</a>
</span>
&nbsp;
<span th:each="p:${#numbers.sequence(1,page.pages)}">
    <a  th:href="@{/book/page(pageNum=${p})}" th:text="${p}"></a>
</span>
   <span th:if="${page.hasNextPage}">
    <a th:href="@{/book/page(pageNum=${page.pageNum+1})}">下一页</a>
</span>
</body>
</html>

5.效果

使用XML映射文件查询

使用注解的方式进行单表的查询非常方便,但多表查询,结果映射等复杂应用情形仍然推荐使用XML映射文件的方式进行查询。

mybatis:
    type-aliases-package: com.jf3q.mybatis.entity   #扫描别名包
    mapper-locations: classpath:mappers/*.xml   #加载此路径下的映射文件

具体写法,咱们在ssm阶段已经学习过了,这里就不赘述了

备注:另外就是把sql映射文件直接放到跟dao接口同一目录下,编译后sql映射文件没打进去,需要修改一下pom.xml文件

  <build>
    <finalName>boot-mybatis</finalName>
<!--    <plugins>-->
<!--      <plugin>-->
<!--        <groupId>org.springframework.boot</groupId>-->
<!--        <artifactId>spring-boot-maven-plugin</artifactId>-->
<!--      </plugin>-->
<!--    </plugins>-->
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>
  </build>

动态更新

用xml的方式操作最简单,ssm写过了

批量删除

使用MyBatis的<foreach>循环,也是用XML映射文件来处理

<delete id="deleteBooks">
    delete from book where id in
    <foreach collection="array" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>
</delete>

页面上怎么写??

提示:复选框

书上的写法

<input type="button" value="删除所选" onclick="dels()"/>
function dels() {
        if (confirm("你确定要删除所选吗")) {
            var ids = "";
            $(".ids").each(function (i, e) {
                if ($(e).is(":checked")) {
                    var id = $(e).val();
                    ids += id + ",";
                }
            });

            if (ids.length == 0) {
                alert("请选择删除项!");
            } else {
                // alert(ids);
                //去除最后一个,号
                ids = ids.substr(0, ids.length - 1);
                location.href = "deleteBooks?id=" + ids;//构造出类似deleteBooks?id=1,2,3这样的URL,后台可用数组接收
            }
        }
    }

有没有好的想法?

用form表单的形式提交行不行?思考下

    <form th:action="@{/book}" method="post" onsubmit="return submitForm()">
    <tr th:each="book:${page.list}">



        <td >
            <input type="checkbox" name="ids"  th:value="${book.id}">
        </td>
      ……
         <input type="submit" value="删除"  onsubmit="return submitForm()">

    </form>

<script src="/js/jquery-3.1.0.min.js"></script>

<script>
    function submitForm() {
        if ($("input[name='ids']:checked").length == 0) {
            alert("必须选择一个记录删除")
            return false
        }
        if (confirm("确定要删除吗?")) {



        }else{
            alert("已取消删除")
            return false
        }
    }
</script>

一对多关联查询

以班级为主表,一个班级下有多个学生

有两种方案:

1两表连查

2.子查询的方式

多对一关联查询

以学生为主表,多个学生对应一个班级

也是有两种方案

1.两表联查的方式

2.子查询的方式

自连接查询

多对一自连接查询

员工表employee中每个员工,包括经理都有个编号,每个员工都有对应的上司的员工编号(老板除外),查询某个编号的员工信息及其对应的上司信息。由于上司也是同一个表中的员工,所以这属于自连接查询。

1.实体类加属性

2.sql映射文件

一对多自连接查询

员工表employee中每个员工,包括经理都有个编号,每个员工都有对应的上司的员工编号(老板除外),查询某个编号的员工信息及其所有的下属信息

1.修改实体类

2.sql映射

不等连接查询

查询各个员工的信息及其工资等级。

1.数据库准备。新建一个工资等级表salarylevel

2.修改实体类Employee。在实体类Employee中添加一个表示工资等级的属性

3.sql映射文件

这个就是不等连接的重点,这里两表连接查询条件不再是外键相等,而是一个范围。

作业

1.将掌上游戏app项目改成springboot整合mybatis的架构

2.把书籍demo完善增删改查

在此基础上继续完善。

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695