• 15Spring Boot整合MyBatis


           MyBatis 是一个半自动化的 ORM 框架,所谓半自动化是指 MyBatis 只支持将数据库查出的数据映射到 POJO 实体类上,而实体到数据库的映射则需要我们自己编写 SQL 语句实现,相较于Hibernate 这种完全自动化的框架,Mybatis 更加灵活,我们可以根据自身的需求编写 sql 语句来实现复杂的数据库操作。

           随着 Spring Boot 越来越流行,越来越多的被厂商及开发者所认可,MyBatis 也开发了一套基于 Spring Boot 模式的 starter:mybatis-spring-boot-starter。本节我们就介绍下如何在 Spring Boot 项目中整合 MyBatis。

    引入依赖

           Spring Boot 整合 MyBatis 的第一步,就是在项目的 pom.xml 中引入 mybatis-spring-boot-starter 的依赖,示例代码如下。

    1. <dependency>
    2. <groupId>org.mybatis.spring.bootgroupId>
    3. <artifactId>mybatis-spring-boot-starterartifactId>
    4. <version>2.2.0version>
    5. dependency>

    配置 MyBatis

           在 Spring Boot 的配置文件(application.properties/yml)中对 MyBatis 进行配置,例如指定 mapper.xml 的位置、实体类的位置、是否开启驼峰命名法等等,示例代码如下。

    1. ###################### MyBatis 配置#########################
    2. mybatis:
    3. # 指定 mapper.xml 的位置
    4. mapper-locations: classpath:mybatis/mapper/*.xml
    5. #扫描实体类的位置,在此处指明扫描实体类的包,在 mapper.xml 中就可以不写实体类的全路径名
    6. type-aliases-package: net.biancheng.www.bean
    7. configuration:
    8. #默认开启驼峰命名法,可以不用设置该属性
    9. map-underscore-to-camel-case: true

    注意:使用 MyBatis 时,必须配置数据源信息,例如数据库 URL、数据库用户型、数据库密码和数据库驱动等。否则报错。

    1. #数据源连接信息
    2. spring:
    3. datasource:
    4. username: root
    5. password: root
    6. url: jdbc:mysql://localhost:3306/tyut?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    7. driver-class-name: com.mysql.cj.jdbc.Driver

    创建实体类

           在指定的数据库内创建一个 user 表,并插入一些数据,如下。

    id  user_id  user_name  password sex  age   address        qq               email
    1    12        老张             123456      男     24    重庆大学     324234         324234@qq.com
    2    13        刘丽             123456      女     23    重庆大学    34543532     34543532@qq.com
    4    14        张丽             123456      女    19     重庆大学    346756543   346756543@qq.com
    5    15        王芳             123456      女    20     重庆大学   353453354    353453354@qq.com
    7    16        李迪             123456     男     26     tyut            313370741   313370741@qq.com
    8    17        杨科             123456     男     24     tyut            313370741   313370741@qq.com
    9    18        张美             123456     女     23     tyut            313370741   313370741@qq.com

      DROP TABLE IF EXISTS user;
      CREATE TABLE `user`(
          `id` int(20) NOT NULL AUTO_INCREMENT,

          `user_id` int(20) DEFAULT NULL,
          `user_name` varchar(32) DEFAULT NULL,

          `password` varchar(32) DEFAULT NULL,
          `sex` varchar(32) DEFAULT NULL,
          `age` int(20) DEFAULT NULL,
          `address` varchar(32) DEFAULT NULL,
          `qq` varchar(32) DEFAULT NULL,
          `email` varchar(32) DEFAULT NULL,
           PRIMARY KEY (`id`)
      ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;


    insert into `user`(id,user_id,user_name,password,sex,age,address,qq,email)values(1,12,'老张','123456','男',24'重庆大学','324234','324234@qq.com')
    insert into `user`(id,user_id,user_name,password,sex,age,address,qq,email)values(2,13,'刘丽','123456','女',23'重庆大学','34543532','34543532@qq.com')
    insert into `user`(id,user_id,user_name,password,sex,age,address,qq,email)values(4,14,'张丽','123456','女',19'重庆大学','346756543','346756543@qq.com')
    insert into `user`(id,user_id,user_name,password,sex,age,address,qq,email)values(5,15,'王芳','123456','女',20'重庆大学','353453354','353453354@qq.com')
    insert into `user`(id,user_id,user_name,password,sex,age,address,qq,email)values(7,16,'李迪','123456','男',26'tyut','313370741','313370741@qq.com')
    insert into `user`(id,user_id,user_name,password,sex,age,address,qq,email)values(8,17,'杨科','123456','男',24'tyut','313370741','313370741@qq.com')
    insert into `user`(id,user_id,user_name,password,sex,age,address,qq,email)values(9,18,'张美','123456','女',23'tyut','313370741','313370741@qq.com')
      

           根据数据库 user 表,创建相应的实体类 User,代码如下。

    1. public class User implements Serializable {
    2. private Integer id;
    3. private Integer userId;
    4. private String userName;
    5. private String password;
    6. private String sex;
    7. private Integer userAge;
    8. private String address;
    9. private String qq;
    10. private String email;
    11. 省略 getter setter toString 和构造方法
    12. }

    创建 Mapper 接口

           在com.hwadee.mapper 中创建一个 UserMapper 接口,并在该类上使用 @Mapper 注解,代码如下。

    1. package com.hwadee.mapper;
    2. import com.hwadee.entity.User;
    3. import org.apache.ibatis.annotations.Mapper;
    4. @Mapper
    5. public interface UserMapper {
    6. //通过用户名密码查询用户数据
    7. User getByUserNameAndPassword(User user);
    8. }

    当 mapper 接口较多时,我们可以在 Spring Boot 主启动类上使用 @MapperScan 注解扫描指定包下的 mapper 接口,而不再需要在每个 mapper 接口上都标注 @Mapper 注解。

    创建 Mapper 映射文件

           在配置文件 application.properties/yml 通过 mybatis.mapper-locations 指定的位置mybatis/mapper/ 中创建 UserMapper.xml,代码如下。

    1. "1.0" encoding="UTF-8"?>
    2. mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3. <mapper namespace="com.hwadee.dao.UserMapper">
    4. <resultMap id="BaseResultMap" type="User">
    5. <id column="id" property="id">id>
    6. <result column="user_id" property="userId">result>
    7. <result column="user_name" property="userName">result>
    8. <result column="password" property="password">result>
    9. <result column="sex" property="sex">result>
    10. <result column="age" property="userAge">result>
    11. <result column="address" property="address">result>
    12. <result column="qq" property="qq">result>
    13. <result column="email" property="email">result>
    14. resultMap>
    15. <sql id="Base_Column_List">
    16. id, user_id, password, user_name, sex, age, address, qq, email
    17. sql>
    18. <select id="getByUserNameAndPassword" resultType="User">
    19. select *
    20. from user
    21. where user_name= #{userName,jdbcType=VARCHAR}
    22. and password= #{password,jdbcType=VARCHAR}
    23. select>
    24. mapper>

           使用 Mapper 进行开发时,需要遵循以下规则:

    • mapper 映射文件中 namespace 必须与对应的 mapper 接口的完全限定名一致。
    • mapper 映射文件中 statement 的 id 必须与 mapper 接口中的方法的方法名一致
    • mapper 映射文件中 statement 的 parameterType 指定的类型必须与 mapper 接口中方法的参数类型一致。
    • mapper 映射文件中 statement 的 resultType 指定的类型必须与 mapper 接口中方法的返回值类型一致。

    创建 Mapper 映射文件

    1. 在 spring-boot项目中com.hwadee.service 包中创建一个名为 UserService 的接口,代码如下。

    1. import net.biancheng.www.bean.User;
    2. public interface UserService {
    3. public User getByUserNameAndPassword(User user);
    4. }

    2. 在com.hwadee.service.impl 包中创建 UserService 接口的实现类,并使用 注解@Service 将其以组件的形式添加到容器中,代码如下。

    1. @Service("userService")
    2. public class UserServiceImpl implements UserService {
    3. @Autowired
    4. UserMapper userMapper;
    5. @Override
    6. public User getByUserNameAndPassword(User user) {
    7. User loginUser = userMapper.getByUserNameAndPassword(user);
    8. return loginUser;
    9. }
    10. }

    3. 创建 LoginController 并编写 doLogin() 方法 ,代码如下。

    1. @Slf4j
    2. @Controller
    3. public class LoginController {
    4. @Autowired
    5. UserService userService;
    6. @RequestMapping("/user/login")
    7. public String doLogin(User user, Map map, HttpSession session) {
    8. //从数据库中查询用户信息
    9. User loginUser = userService.getByUserNameAndPassword(user);
    10. if (loginUser != null) {
    11. session.setAttribute("loginUser", loginUser);
    12. log.info("登陆成功,用户名:" + loginUser.getUserName());
    13. //防止重复提交使用重定向
    14. return "redirect:/main.html";
    15. } else {
    16. map.put("msg", "用户名或密码错误");
    17. log.error("登陆失败");
    18. return "login";
    19. }
    20. }
    21. }

    4. 启动springboot主体类,进行测试

           访问“http://localhost:8080/user/login?ussername=xxx&password=123456”



    注解方式

           通过上面的学习,我们知道 mapper 映射文件其实就是一个 XML 配置文件,它存在 XML 配置文件的通病,即编写繁琐,容易出错。即使是一个十分简单项目,涉及的 SQL 语句也都十分简单,我们仍然需要花费一定的时间在mapper 映射文件的配置上。

           为了解决这个问题,MyBatis 针对实际实际业务中使用最多的“增伤改查”操作,分别提供了以下注解来替换 mapper 映射文件,简化配置:

    • @Select
    • @Insert
    • @Update
    • @Delete

           通过以上注解,基本可以满足我们对数据库的增删改查操作,示例代码如下。

    1. @Mapper
    2. public interface UserMapper {
    3. @Select("select * from user where user_name = #{userName,jdbcType=VARCHAR} and password = #{password,jdbcType=VARCHAR}")
    4. List getByUserNameAndPassword(User user);
    5. @Delete("delete from user where id = #{id,jdbcType=INTEGER}")
    6. int deleteByPrimaryKey(Integer id);
    7. @Insert("insert into user ( user_id, user_name, password, email)" +
    8. "values ( #{userId,jdbcType=VARCHAR}, #{userName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR})")
    9. int insert(User record);
    10. @Update(" update user" +
    11. " set user_id = #{userId,jdbcType=VARCHAR},\n" +
    12. " user_name = #{userName,jdbcType=VARCHAR},\n" +
    13. " password = #{password,jdbcType=VARCHAR},\n" +
    14. " email = #{email,jdbcType=VARCHAR}\n" +
    15. " where id = #{id,jdbcType=INTEGER}")
    16. int updateByPrimaryKey(User record);
    17. }

    注意事项

           mapper 接口中的任何一个方法,都只能使用一种配置方式,即注解和 mapper 映射文件二选一,但不同方法之间,这两种方式则可以混合使用,例如方法 1 使用注解方式,方法 2 使用 mapper 映射文件方式。

    我们可以根据 SQL 的复杂程度,选择不同的方式来提高开发效率。

    • 如果没有复杂的连接查询,我们可以使用注解的方式来简化配置;
    • 如果涉及的 sql 较为复杂时,则使用 XML (mapper 映射文件)的方式更好一些。

    16Spring Boot整合日志框架

    https://blog.csdn.net/qq_41946216/article/details/127106166?spm=1001.2014.3001.5502

  • 相关阅读:
    软件测试/测试开发丨Python文件操作 学习笔记
    恶劣条件下GNSS定位的鲁棒统计
    扫码挪车小程序源码专业版上线了
    腾讯云16核服务器配置有哪些?CPU型号处理器主频性能
    学编程的第二十二天
    微服务简单理解与快速搭建
    (续)SSM整合之spring笔记(AOP 基于注解的AOP切点表达式的语法,获取连接点的信息, 重用切入点表达式)(P102)
    Java高级学习篇之网络编程
    Java线程面试题
    CH11_重构API
  • 原文地址:https://blog.csdn.net/qq_41946216/article/details/127100048