• java框架 Mybatis介绍与入门案例


    1、MyBatis简介

    1.1、MyBatis历史

            MyBatis最初是 Apache 的一个开源项目 iBatis , 2010 6 月这个项目由 Apache Software Foundation 迁移到了Google Code 。随着开发团队转投 Google Code 旗下, iBatis3.x 正式更名为 MyBatis 。代码于2013年 11 月迁移到 Github
            iBatis一词来源于 “internet” “abatis” 的组合,是一个基于 Java 的持久层框架。 iBatis 提供的持久层框架 包括SQL Maps Data Access Objects DAO )。

    1.2、MyBatis特性

            1) MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
            2) MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
            3) MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和JavaPOJOPlain Old Java Objects,普通的Java对象)映射成数据库中的记录
            4) MyBatis 是一个 半自动的ORMObject Relation Mapping)框架

    1.3、MyBatis下载

    MyBatis下载地址:https://github.com/mybatis/mybatis-3

     

    1.4、和其它持久化层技术对比

    • JDBC
      • SQL 夹杂在Java代码中耦合度高,导致硬编码内伤
      • 维护不易且实际开发需求中 SQL 有变化,频繁修改的情况多见
      • 代码冗长,开发效率低
    • Hibernate 和 JPA
      • 操作简便,开发效率高
      • 程序中的长难复杂 SQL 需要绕过框架
      • 内部自动生成的 SQL,不容易做特殊优化
      • 基于全映射的全自动框架,大量字段的 POJO 进行部分映射时比较困难。
      • 反射操作太多,导致数据库性能下降
    • MyBatis
      • 轻量级,性能出色
      • SQL 和 Java 编码分开,功能边界清晰。Java代码专注业务、SQL语句专注数据
      • 开发效率稍逊于 HIbernate,但是完全能够接收

    2、搭建MyBatis

    2.1、开发环境

            IDE:idea 2022.1
            构建工具:maven 3.8.6
            MySQL版本:MySQL 8
            MyBatis版本:MyBatis 3.5.7
    MySQL不同版本的注意事项
            1、驱动类driver-class-name
                    MySQL 5版本使用jdbc5驱动,驱动类使用:com.mysql.jdbc.Driver
                    MySQL 8版本使用jdbc8驱动,驱动类使用:com.mysql.cj.jdbc.Driver
            2、连接地址url
                    MySQL 5版本的url
                            jdbc:mysql://localhost:3306/ssm
                    MySQL 8版本的url
                            jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
                    否则运行测试用例报告如下错误:
                     java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized orrepresents more

    2.2、物理建模

    1. CREATE DATABASE IF NOT EXISTS `ssm`;
    2. USE `ssm`;
    3. CREATE TABLE `t_user`(
    4. id INT PRIMARY KEY AUTO_INCREMENT,
    5. username VARCHAR(20),
    6. password VARCHAR(20),
    7. age INT,
    8. gender CHAR,
    9. email VARCHAR(50)
    10. );

    2.3、逻辑建模

    ① 创建Maven module

    ② 创建 Java 实体类

    1. /**
    2. * 和数据库表 t_user 对应的实体类
    3. */
    4. public class User {
    5. private Integer id;
    6. private String username;
    7. private String password;
    8. private Integer age;
    9. private String gender;
    10. private String email;
    11. public User() {
    12. }
    13. public User(Integer id, String username, String password, Integer age, String gender, String email) {
    14. this.id = id;
    15. this.username = username;
    16. this.password = password;
    17. this.age = age;
    18. this.gender = gender;
    19. this.email = email;
    20. }
    21. public Integer getId() {
    22. return id;
    23. }
    24. public void setId(Integer id) {
    25. this.id = id;
    26. }
    27. public String getUsername() {
    28. return username;
    29. }
    30. public void setUsername(String username) {
    31. this.username = username;
    32. }
    33. public String getPassword() {
    34. return password;
    35. }
    36. public void setPassword(String password) {
    37. this.password = password;
    38. }
    39. public Integer getAge() {
    40. return age;
    41. }
    42. public void setAge(Integer age) {
    43. this.age = age;
    44. }
    45. public String getGender() {
    46. return gender;
    47. }
    48. public void setGender(String gender) {
    49. this.gender = gender;
    50. }
    51. public String getEmail() {
    52. return email;
    53. }
    54. public void setEmail(String email) {
    55. this.email = email;
    56. }
    57. @Override
    58. public String toString() {
    59. return "User{" +
    60. "id=" + id +
    61. ", username='" + username + '\'' +
    62. ", password='" + password + '\'' +
    63. ", age=" + age +
    64. ", gender='" + gender + '\'' +
    65. ", email='" + email + '\'' +
    66. '}';
    67. }
    68. }

    ③ 创建mapper接口

             MyBatis中的mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要提供实现类。
    1. package com.chenyixin.ssm.mapper;
    2. public interface UserMapper {
    3. /**
    4. * 添加用户信息
    5. * @return 返回影响数据库变化的行数
    6. */
    7. int insertUser();
    8. }

    2.3、搭建框架开发环境

    ① 导入依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.mybatisgroupId>
    4. <artifactId>mybatisartifactId>
    5. <version>3.5.7version>
    6. dependency>
    7. <dependency>
    8. <groupId>junitgroupId>
    9. <artifactId>junitartifactId>
    10. <version>4.12version>
    11. <scope>testscope>
    12. dependency>
    13. <dependency>
    14. <groupId>mysqlgroupId>
    15. <artifactId>mysql-connector-javaartifactId>
    16. <version>8.0.27version>
    17. dependency>
    18. dependencies>

    ② 创建MyBatis的核心配置文件

            习惯上命名为mybatis-config.xml ,这个文件名仅仅只是建议,并非强制要求。将来整合 Spring 之后,这个配置文件可以省略,所以大家操作时可以直接复制、粘贴。
             核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息
            核心配置文件存放的位置是src/main/ resources 目录下
    1. configuration
    2. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-config.dtd">
    4. <configuration>
    5. <environments default="development">
    6. <environment id="development">
    7. <transactionManager type="JDBC"/>
    8. <dataSource type="POOLED">
    9. <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
    10. <property name="url" value="jdbc:mysql://localhost:3306/ssm?
    11. serverTimezone=UTC"/>
    12. <property name="username" value="root"/>
    13. <property name="password" value="root"/>
    14. dataSource>
    15. environment>
    16. environments>
    17. <mappers>
    18. <mapper resource="mappers/UserMapper.xml"/>
    19. mappers>
    20. configuration>

    ③ 创建MyBatis的映射文件

    相关概念:ORM(Object Relationship Mapping)对象关系映射。

    • 对象:Java的实体类对象
    • 关系:关系型数据库
    • 映射:二者之间的对应关系

    下表列举的是最简单的单表映射(一个表和一个类):

    Java概念数据库概念
    属性字段/列
    对象记录/行
    1、映射文件的命名规则:
            表所对应的实体类的类名+Mapper.xml
            例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
            因此 一个映射文件对应一个实体类,对应一张表的操作
            MyBatis映射文件用于编写SQL,访问以及操作表中的数据
            MyBatis映射文件存放的位置是src/main/ resources/mappers 目录下

     

    2、 MyBatis中可以面向接口操作数据,要保证两个一致:
             a>mapper接口的全类名和映射文件的命名空间(namespace)保持一致
            b>mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致
    1. mapper
    2. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.chenyixin.ssm.mapper.UserMapper">
    5. <insert id="insertUser">
    6. insert into t_user values (null,'张三','123456',19,'男','123456@qq.com');
    7. insert>
    8. mapper>

    2.4 通过junit测试功能

    1. public class UserMapperTest {
    2. @Test
    3. public void insertUser() throws IOException {
    4. // 读取 MyBatis 的核心配置文件 注:Resources 在 org.apache.ibatis.io 包中
    5. InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    6. // 创建 SqlSessionFactoryBuilder 对象
    7. SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    8. // 通过核心配置文件多对应的字节输入流创建工厂类 SqlSessionFactory ,生产 SqlSession 对象
    9. SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
    10. // 创建 SqlSession 对象(手动操作事务),此时通过 SqlSession 对象所操作的 sql 都必须手动提交或回滚(默认回滚)
    11. SqlSession sqlSession1 = sqlSessionFactory.openSession();
    12. // 创建 SqlSession 对象(自动操作事务)
    13. SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
    14. // 通过代理模式创建 UserMapper 接口的代理实现类对象
    15. UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
    16. UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
    17. // 调用 UserMapper 接口中的方法,就可以根据 UserMapper 的全类名匹配元素文件,
    18. // 通过调用的方法名匹配映射文件中是 SQL 标签,并执行标签中的 SQL 语句
    19. int result1 = userMapper1.insertUser();
    20. int result2 = userMapper2.insertUser();
    21. System.out.println("结果:" + result1);
    22. System.out.println("结果:" + result2);
    23. // 记得手动提交
    24. sqlSession1.commit();
    25. // 需要关闭sqlSession
    26. sqlSession1.close();
    27. sqlSession2.close();
    28. }
    29. }

    说明:

    • SqlSession:代表Java程序和数据库之间的会话。(HttpSession是Java程序和浏览器之间的会话)
    • SqlSessionFactory:是“生产”SqlSession的“工厂”。
    • 工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。

    2.5 加入log4j日志功能

    ① 目的

            在Mybatis工作过程中,通过打印日志的方式,将要执行的SQL语句打印出来。

    ② 加入依赖

    1. <dependency>
    2. <groupId>log4jgroupId>
    3. <artifactId>log4jartifactId>
    4. <version>1.2.17version>
    5. dependency>

    ③ 加入log4j的配置文件

    支持 XML 和 properties 属性文件两种形式。无论使用哪种形式,文件名是固定的:

    • log4j.xml
    • log4j.properties
    1. log4j:configuration SYSTEM "log4j.dtd">
    2. <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    3. <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
    4. <param name="Encoding" value="UTF-8" />
    5. <layout class="org.apache.log4j.PatternLayout">
    6. <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
    7. layout>
    8. appender>
    9. <logger name="java.sql">
    10. <level value="debug" />
    11. logger>
    12. <logger name="org.apache.ibatis">
    13. <level value="info" />
    14. logger>
    15. <root>
    16. <level value="debug" />
    17. <appender-ref ref="STDOUT" />
    18. root>
    19. log4j:configuration>

    ④ 日志的级别

    FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)

    从左到右打印的内容越来越详细

    ⑤ STDOUT

    是standard output的缩写,意思是标准输出。对于Java程序来说,打印到标准输出就是打印到控制台。

    ⑤ 打印效果

     

    3、MyBatis的增删改查

    3.1、优化代码

    编写工具类,直接获取获取 SqlSession 对象

    1. public class SqlSessionUtil {
    2. public static SqlSession getSqlSession() {
    3. try {
    4. // 获取核心的配置文件
    5. InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    6. // 创建 SqlSessionFactoryBuilder 对象
    7. SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    8. // 通过核心配置文件多对应的字节输入流创建工厂类 SqlSessionFactory ,生产 SqlSession 对象
    9. SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
    10. // 创建 SqlSession 对象(自动操作事务)
    11. return sqlSessionFactory.openSession(true);
    12. } catch (Exception e) {
    13. throw new RuntimeException(e);
    14. }
    15. }
    16. }

    3.2 UserMapper 接口

    1. public interface UserMapper {
    2. /**
    3. * 添加用户信息
    4. * @return 返回影响数据库变化的行数
    5. */
    6. int insertUser();
    7. /**
    8. * 修改用户信息
    9. * @return 返回影响数据库变化的行数
    10. */
    11. int updateUser();
    12. /**
    13. * 根据 id 删除用户信息
    14. * @return 返回影响数据库变化的行数
    15. */
    16. int deleteUserById();
    17. /**
    18. * 根据 id 查询用户信息
    19. * @return 返回查询到的用户信息
    20. */
    21. User selectUserById();
    22. /**
    23. * 查询所有用户信息
    24. * @return 返回查询到的用户信息
    25. */
    26. List selectAllUser();
    27. }

    3.3 编写 UserMapper.xml 文件

    1. mapper
    2. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.chenyixin.ssm.mapper.UserMapper">
    5. <insert id="insertUser">
    6. insert into t_user
    7. values (null, '张三', '123456', 19, '男', '123456@qq.com')
    8. insert>
    9. <update id="updateUser">
    10. update t_user
    11. set username = '李四',
    12. password = '123'
    13. where id = 3
    14. update>
    15. <delete id="deleteUserById">
    16. delete
    17. from t_user
    18. where id = 2;
    19. delete>
    20. <select id="selectUserById" resultType="com.chenyixin.ssm.pojo.User">
    21. select *
    22. from t_user
    23. where id = 3;
    24. select>
    25. <select id="selectAllUser" resultType="com.chenyixin.ssm.pojo.User">
    26. select *
    27. from t_user;
    28. select>
    29. mapper>
    注意:
            1、查询的标签select必须设置属性resultType或resultMap,用于设置实体类和数据库表的映射
    关系
            2、resultType:自动映射,用于属性名和表中字段名一致的情况
            3、resultMap:自定义映射,用于一对多或多对一或字段名和属性名不一致的情况

    3.4 创建测试类

    1. public class UserMapperTest2 {
    2. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    3. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    4. @Test
    5. public void insertUser() {
    6. userMapper.insertUser();
    7. }
    8. @Test
    9. public void updateUser() {
    10. userMapper.updateUser();
    11. }
    12. @Test
    13. public void deleteUserById() {
    14. userMapper.deleteUserById();
    15. }
    16. @Test
    17. public void selectUserById() {
    18. User user = userMapper.selectUserById();
    19. System.out.println(user);
    20. }
    21. // User{id=3, username='李四', password='123', age=19, gender='男', email='123456@qq.com'}
    22. @Test
    23. public void selectAllUser() {
    24. List users = userMapper.selectAllUser();
    25. for (User user : users) {
    26. System.out.println(user);
    27. }
    28. //User{id=1, username='张三', password='123456', age=19, gender='男', email='123456@qq.com'}
    29. // User{id=3, username='李四', password='123', age=19, gender='男', email='123456@qq.com'}
    30. // User{id=4, username='张三', password='123456', age=19, gender='男', email='123456@qq.com'}
    31. }
    32. }
  • 相关阅读:
    十二、CANdelaStudio入门-Security
    企业日常公关如何抵御负面信息的入侵?
    双十一屡获冠军!TCL空调的爆品密码是什么?
    软件测试项目篇
    青海特色美食制作工艺数字化保护平台
    【1day】金和协同管理平台c6系统任意文件读取漏洞学习
    文本溢出 右侧对齐 左侧显示省略号
    软考小记-软件工程
    都2022年了 你还不了解什么是性能测试?
    这份工具清单,令Python 提速N倍,简直太好用了
  • 原文地址:https://blog.csdn.net/weixin_65637841/article/details/126283332