Springboot整合Mybatis

1.传统配置

①导入mybatis官方start依赖

②编写mapper接口,标注@Mapper注解

③编写SQL映射文件并绑定mapper接口

④在applicaiton.yml中指定mapper配置文件的位置,以及指定全局配置文件的信息(建议:配置在mybatis.configuration)

引入mybatis依赖

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>

resources.mybatis.mybatis-config.xml (mybatis配置文件)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--    <environments default="development">-->
<!--        <environment id="development">-->
<!--            <transactionManager type="JDBC"/>-->
<!--            <dataSource type="POOLED">-->
<!--                <property name="driver" value="${driver}"/>-->
<!--                <property name="url" value="${url}"/>-->
<!--                <property name="username" value="${username}"/>-->
<!--                <property name="password" value="${password}"/>-->
<!--            </dataSource>-->
<!--        </environment>-->
<!--    </environments>-->
<!--    <mappers>-->
<!--        <mapper resource="org/mybatis/example/BlogMapper.xml"/>-->
<!--    </mappers>-->
<!--    设置驼峰命名-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>

resources.mybatis.mapper.CourseMapper.xml (编写SQL语句)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.laj.admin.mapper.CourseMapper">
    <select id="getCourse" resultType="com.laj.admin.bean.Course">
        select * from Course where cid=#{cid}
    </select>
</mapper>

mapper.CourseMapper.java (编写SQL语句的mapper接口并标注@Mapper注解)

@Mapper
public interface CourseMapper {
    public Course getCourse(Long cid);
}

service.CourseService.java (编写service层,实现mapper接口方法 注入mapper接口)

@Service
public class CourseService {
    @Autowired
    CourseMapper courseMapper;

    public Course getCourseById(Long cid){
        return courseMapper.getCourse(cid);
    }
}

controller.CourseController.java (返回service层的方法)

/**
 * 测试打印SQL
 * @return
 */
@ResponseBody
@GetMapping("/Course")
public Course course(@RequestParam("cid") Long cid){
    return courseService.getCourseById(cid);
}

2.注解配置

@Mapper
public interface CityMapper {
    @Select("select * from city where id = #{id}")
    public City getCityById(Long id);

    @Insert("insert into city(name,state,country) values (#{name},#{state},#{country})")
    @Options(useGeneratedKeys = true,keyProperty = "id")//useGeneratedKeys:获取数据库自动生成的主键id keyProperty:将自增的值赋值给bean的属性id
    public void insertCity(City city);
}

省去了配置SQL的xml文件,直接在mapper接口中通过注解写SQL语句 【遇到复杂的SQL 语句还是使用xml映射会更好】

useGeneratedKeys:获取数据库自动生成的主键id

keyProperty:将自增的值赋值给bean的属性id

@MapperScan("xx.xxx.mapper") 简化,其他的接口就可以不用标注@Mapper

注意:注解和xml文件的SQL不能同时兼容,只能写其中一个

3.混合配置

一些比较复杂的SQL语句通过xml文件映射会更清晰,方便后期维护,在config.xml中配置好映射的路径,以及驼峰命名等配置信息

4.整合Mybatis-Plus

官方文档 https://mp.baomidou.com/guide/

引入相关依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.1</version>
</dependency>

该依赖内置了jdbc-starter的依赖、mybatis的依赖

更简洁地开发

entity实体类: 【@TableField(exist = false) //表示该字段不是数据库内的】

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@TableName("user")
public class User {
    @TableField(exist = false)   //表示该字段不是数据库内的
    private String username="123";
    @TableField(exist = false)
    private String password="123";

    //以下是数据库字段
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

mapper文件不需要再写xml映射,也不需要写SQL语句注解 【仅限于单表查询】

通过继承BaseMapper 将实体类放入参数

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

service中 接口继承IService

public interface UserService extends IService<User> {
}

实现类 实现接口外,继承ServiceImpl<UserMapper, User>

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}

测试类:将mapper自动注入容器,调用方法进行数据库操作

@Slf4j
@SpringBootTest
class SpringbootWebAdminApplicationTests {
    @Autowired
    UserMapper userMapper;

    @Test
    void testMapper(){
        User user = userMapper.selectById(1L);
        log.info("用户信息{}",user);
    }

}
使用Thymeleaf结合mybatis-plus进行页面开发

使用分页 【补充:PageHelper插件也可以进行分页】https://pagehelper.github.io/docs/howtouse/

configuration配置分页插件:

//Spring boot方式
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {

    // 旧版
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
    
    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }
    
}

controller:

  • 根据不同的url地址跳转到不同的页面,所以通过改变url的参数进行页面跳转,默认为第一页;
  • 通过userService调用list() 获取数据库的所有数据
  • 使用model 将获取的数据放到users中
@GetMapping("/dynamic_table")
    public String dynamic_table(@RequestParam(value = "pn",defaultValue = "1")Integer pn, Model model){
        //从数据库中查出user表中的用户进行展示
        List<User> list = userService.list();
        model.addAttribute("users",list);
        //分页查询数据
        Page<User> userPage = new Page<>(pn,2);
        //分页查询的结果
        Page<User> page = userService.page(userPage, null);

//        long current = page.getCurrent();
//        long pages = page.getPages();
//        long total = page.getTotal();


        model.addAttribute("page",page);//使用model存放数据
        return "table/dynamic_table";
    }

前端页面1:结合Thymeleaf将数据返回页面

th:each="{user,stat:{users}}" 遍历数据

<div class="adv-table">
    <table class="display table table-bordered table-striped" id="dynamic-table">
        <thead>
        <tr>
            <th>#</th>
            <th>id</th>
            <th>name</th>
            <th>age</th>
            <th>email</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody role="alert" aria-live="polite" aria-relevant="all">
        <tr class="gradeX" th:each="user,stat:${page.records}">
            <td th:text="${stat.count}">Trident</td>
            <td th:text="${user.id}">id</td>
            <td th:text="${user.name}">Internet
                Explorer 4.0
            </td>
            <td th:text="${user.age}">Win 95+</td>
            <td class="center hidden-phone" th:text="${user.email}">4</td>
            <td class="center hidden-phone">X</td>
        </tr>
        </tbody>
    </table>
</div>

前端页面2:进行分页

page.current:当前页数

page.pages:所有页

page.total:记录总条数

page.records:遍历集合显示当前页的数据

th:class="${num == page.current?'active':''}" 进行三元运算:若是当前页码,标签高亮

th:each="num:${#numbers.sequence(1,page.pages)}" 生成从1到总页码的序列

th:href="@{/dynamic_table(pn=${num})}" 通过页码url

<div class="row-fluid">
    <div class="span6">
        <div class="dataTables_info" id="dynamic-table_info">当前第 [[${page.current}]] 页,总计 [[${page.pages}]] 页,共[[${page.total}]]条记录
        </div>
    </div>
    <div class="span6">
        <div class="dataTables_paginate paging_bootstrap pagination">
            <ul>
                <li class="prev disabled"><a href="#">← 上一页</a></li>
                <li th:class="${num == page.current?'active':''}" th:each="num:${#numbers.sequence(1,page.pages)}">
                    <a th:href="@{/dynamic_table(pn=${num})}">[[${num}]]</a>
                </li>
                <li class="next disabled"><a href="#">下一页 → </a></li>
            </ul>
        </div>
    </div>
</div>

删除页面: 利用mybatis-plus通过id删除数据

@GetMapping("/user/delete/{id}")
public String deleteUser(@PathVariable("id") Long id,
                         @RequestParam(value = "pn",defaultValue = "1") Integer pn,
                         RedirectAttributes ra){
    userService.removeById(id);
    ra.addAttribute("pn",pn);//作用:在重定向的时候获取当前页的pn,让页面还在留在当前页
    return "redirect:/dynamic_table";
}
<td>
    <a th:href="@{/user/delete/{id}(id=${user.id},pn=${page.current})}" class="btn btn-danger btn-sm" type="button">删除</a>
</td>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容