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="{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>