Mybatis 默认是不支持我们的数据库字段的驼峰命名的。假如说数据库的字段名的间隔以下划线分割,那么实体类应该写成驼峰命名。那么如果我们没有配置mybatis使用驼峰命名那么我们就会查询到的数据为null。
第一种: 使用全局配置文件配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="multipleResultSetsEnabled" value="true"/> </settings> </configuration>
第二种: 使用application.yaml
mybatis: config-location: classpath:mybatis/mybatis-config.xml #指定mybatis的核心文件位置 mapper-locations: classpath:mybatis/mapper/*.xml #指定mybatis的映射文件位置 configuration: multiple-result-sets-enabled: true ⭐
注意: 全局配置文件(mybatis-config)与application.yaml中只能存在一个对mybatis进行配置。
基本步骤:
- 导入mybatis官方starter
- 编写mapper接口。标准@Mapper注解
- 编写sql映射文件并绑定mapper接口
- 在application.yaml中指定Mapper配置文件的位置,以及指定全局配置文件的信息 (建议;配置在mybatis.configuration)
(3).纯注解的配置模式
如果我们使用注解开发的话,我们就可以省略掉xml映射文件而不是xml全局配置文件(mybatis-config.xml)
package com.jsxs.mapper; import com.jsxs.bean.Admin; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; /** * @Author Jsxs * @Date 2023/7/17 11:01 * @PackageName:com.jsxs.mapper * @ClassName: AdminMapper * @Description: TODO * @Version 1.0 */ @Mapper @Repository public interface AdminMapper { // 1.查询所有的用户 public List<Admin> allAdmin(); // 2.根据id进行查找数据 ⭐⭐ @Select("select *from admin where id = #{id}") public Admin getAdminById(Long id); }
Service 接口实现类
package com.jsxs.service; import com.jsxs.bean.Admin; import com.jsxs.mapper.AdminMapper; import org.springframework.stereotype.Service; import java.util.List; /** * @Author Jsxs * @Date 2023/7/17 13:39 * @PackageName:com.jsxs.service * @ClassName: AdminService * @Description: TODO * @Version 1.0 */ public interface AdminService { public List<Admin> allAdmin(); public Admin getAdminById(Long id); }
Service接口
package com.jsxs.service.impl; import com.jsxs.bean.Admin; import com.jsxs.mapper.AdminMapper; import com.jsxs.service.AdminService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; /** * @Author Jsxs * @Date 2023/7/17 13:44 * @PackageName:com.jsxs.service.impl * @ClassName: AdminServiceImpl * @Description: TODO * @Version 1.0 */ @Service public class AdminServiceImpl implements AdminService { @Resource AdminMapper adminMapper; @Override public List<Admin> allAdmin() { return adminMapper.allAdmin(); } @Override public Admin getAdminById(Long id) { return adminMapper.getAdminById(id); } }
测试结果
package com.jsxs.service.impl; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; import static org.junit.jupiter.api.Assertions.*; /** * @Author Jsxs * @Date 2023/7/17 13:47 * @PackageName:com.jsxs.service.impl * @ClassName: AdminServiceImplTest * @Description: TODO * @Version 1.0 */ @SpringBootTest class AdminServiceImplTest { @Resource AdminServiceImpl adminService; @Test void test(){ System.out.println(adminService.allAdmin()); System.out.println(adminService.getAdminById(1L)); } }
(4).非注解和纯注解可以混合使用
我们只需要各自写各自的即可,即非注解的要写 xml映射文件和全局配置文件;非注解的不需要xml映射文件但需要全局文件
package com.jsxs.mapper; import com.jsxs.bean.Admin; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Options; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; /** * @Author Jsxs * @Date 2023/7/17 11:01 * @PackageName:com.jsxs.mapper * @ClassName: AdminMapper * @Description: TODO * @Version 1.0 */ @Mapper @Repository public interface AdminMapper { // 1.查询所有的用户 public List<Admin> allAdmin(); // 2.根据id进行查找数据 @Select("select *from admin where id = #{id}") public Admin getAdminById(Long id); // 3.xinz @Insert("insert into admin(name,password) values(#{name},#{password})") @Options(useGeneratedKeys = true,keyColumn = "id") // 指定主键是那个? public int add(String name,String password); }
最佳实践
- 引入mybatis-starter
- 配置application.yaml中,指定
mapper-location
位置即可;config-location:
核心配置文件就不需要了。核心配置文件最好直接再application.yaml中使用。 - 编写
Mapper接口并标注@Mapper注解
- 简单方法直接注解方式
- 复杂方法编写mapper.xml进行绑定映射
@MapperScan("com.atguigu.admin.mapper")
简化,其他的Mapper接口就可以不用标注@Mapper注解
4.Mybatis-Plus 操作数据库
(1).什么是MybatisPlus
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
mybatis plus 官网 https://baomidou.com/
建议安装 MybatisX 插件
(2).整合Mybatisplus
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency>
帮助我们自动引入了JDBC和Mybatis的包,所以我们不需要再引入JDBC和Mybatis了
自动配置
- MybatisPlusAutoConfiguration 配置类,MybatisPlusProperties 配置项绑定。
mybatis-plus:xxx 就是对mybatis-plus的定制
- SqlSessionFactory 自动配置好。
底层是容器中默认的数据源
mapperLocations 自动配置好的。有默认值 (3.1.2下才有默认值)
。classpath*:/mapper/**/*.xml;任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件,放在 mapper下- 容器中也自动配置好了 SqlSessionTemplate
- @Mapper 标注的接口也会被自动扫描;建议直接
@MapperScan("com.atguigu.admin.mapper") 批量扫描就行
优点:
- 只需要我们的
Mapper继承 BaseMapper
就可以拥有crud能力。
- 数据库层继承的是: BaseMapper
mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml #3.1.2版本之后有默认的值了。
实体类
为什么说:我们这里写类名为 Admin ; 然后Mybatisplus是怎么找到数据库的具体表的? 因为默认有一个注解 @TableName(“xxx”) xxx默认是写的是类名,就会通过这个类名去数据库中寻找。如果表名更改了,那么我们可以通过这个注解更改映射的关系。
package com.jsxs.bean; import com.baomidou.mybatisplus.annotation.TableField; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @Author Jsxs * @Date 2023/7/17 11:01 * @PackageName:com.jsxs.bean * @ClassName: Admin * @Description: TODO * @Version 1.0 */ @Data @AllArgsConstructor @NoArgsConstructor public class Admin { @TableField(exist = true) // 假如我们需要临时的属性,但这个属性不存在我们可以再上面添加一个注解 @TableField(exist = false)表示在表中不存在 Integer id; String name; String password; }
Mapper接口-> 需要继承一个接口
package com.jsxs.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.jsxs.bean.Admin; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Options; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; /** * @Author Jsxs * @Date 2023/7/17 11:01 * @PackageName:com.jsxs.mapper * @ClassName: AdminMapper * @Description: TODO 继承接口之后我们不需要再编写 CRUD 就自带的已经存在了 * @Version 1.0 */ @Mapper @Repository public interface AdminMapper extends BaseMapper<Admin> { // 需要继承BaseMapper,因为这个父类有很多已经分装好的方法 }
测试实现
package com.jsxs.mapper; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; import static org.junit.jupiter.api.Assertions.*; /** * @Author Jsxs * @Date 2023/7/18 11:03 * @PackageName:com.jsxs.mapper * @ClassName: AdminMapperTest * @Description: TODO * @Version 1.0 */ @SpringBootTest class AdminMapperTest { @Resource AdminMapper adminMapper; @Test void test(){ System.out.println(adminMapper.selectById(1)); } }
- 业务层接口
继承的是 IService<操作的实体类名>
; 业务层实现类继承业务层的实现类要继承ServiceImpl<要实现表的BaseMapper,操作表对应的实体类名> 且 要实现业务层的接口
实体类
package com.jsxs.bean; import com.baomidou.mybatisplus.annotation.TableField; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @Author Jsxs * @Date 2023/7/17 11:01 * @PackageName:com.jsxs.bean * @ClassName: Admin * @Description: TODO * @Version 1.0 */ @Data @AllArgsConstructor @NoArgsConstructor public class Admin { @TableField(exist = true) // 假如我们需要临时的属性,但这个属性不存在我们可以再上面添加一个注解 @TableField(exist = false)表示在表中不存在 Integer id; String name; String password; }