栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis基础学习之使用注解开发

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis基础学习之使用注解开发

前言:

小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师。

这个Mybatis基础学习系列是用来记录我学习Mybatis框架基础知识的全过程 (这个系列是参照B站狂神的Mybatis最新教程来写的,由于是之前整理的,但当时没有发布出来,所以有些地方可能有错误,希望大家能够及时指正!)


之后我将尽量以两天一更的速度更新这个系列,还没有学习Mybatis3框架的小伙伴可以参照我的博客学习一下;当然学习过的小伙伴,也可以顺便跟我一起复习一下基础。最后,希望能够和大家一同进步吧!加油吧!少年们!

特别提醒:如果对Mybatis基础学习系列感兴趣,可以阅读本系列往期博客:
第一篇:Mybatis基础学习之初识Mybatis
第二篇:Mybatis基础学习之第一个Mybatis程序
第三篇:Mybatis基础学习之CRUD增删改查
第四篇:Mybatis基础学习之万能的Map和模糊查询
第五篇: Mybatis基础学习之配置解析(上篇)
第六篇: Mybatis基础学习之配置解析(下篇)
第七篇: Mybatis基础学习之使用ResultMap解决字段名不一致
第八篇: Mybatis基础学习之日志工厂的简单使用
第九篇: Mybatis基础学习之数据分页的简单使用


今天我们来到了Mybatis基础学习的第九站:使用注解开发。废话不多说,让我们开始今天的学习内容吧。

9.使用注解开发 9.1 面向接口编程

在之前的Java基础学习中,我们都知道Java语言一门面向对象的编程语言,很多相关书籍和资深程序员也会经常强调面向对象编程的重要性。在Java基础学习中,我们也接触到了接口的概念,而在真正的开发中,很多时候也会选择面向接口编程,那么为什么要选择面向接口编程呢?

9.1.1 为什么要选择面向接口编程?

选择面向接口的根本原因是:

  • 为了解耦,提高可拓展和复用性
  • 分层开发中,上层不用管具体的实现,都遵守公共的标准,使得开发变得很容易,规范性更好
9.1.2 什么是面向接口编程?

一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的;这种情况下,各个对象内部是如何实现相对来说就不那么重要了

各个对象之间的协作关系成为系统设计的关键,小到不同类之间的通信,大到各模块之间的交互,这不仅是在设计之初需要着重考虑的,也是系统设计的主要工作内容,而面向接口编程就是指按照这种思想来编程。

9.1.3 关于接口的理解
  • 接口从更深层次的理解,应是定义 (规范和约束) 与实现 (名实分离) 的分离

  • 接口的本身反映了系统设计人员对系统的抽象理解

  • 接口应有两类

    第一类:对一个个体的抽象,它可对应成为一个抽象体(abstract class)

    第二类:对一个个体某一方面的抽象,即形成一个抽象面(interface)

  • 一个个体可能有多个抽象面抽象体抽象面有区别的

9.1.4 三个面向区别
  • 面相对象:考虑问题时,以对象为单位,考虑它的属性及方法
  • 面向过程:考虑问题时,以一个具体的流程 (事务过程) 为单位,考虑它的实现
  • 面向接口接口设计非接口设计针对复用技术而言的,与面向对象 (或者面向过程) 不是一个问题,更多的体现是对系统整体的架构
9.2 使用注解开发

本质:反射机制实现

底层:动态代理

9.2.1 创建编写实体类和工具类 1.编写User实体类
// User实体类
public class User {
    
    private int id; // 用户编号
    private String name; // 用户名
    private String password; // 密码
    
    // User实体类的无参构造方法
    public User() {
    }
    
    // User实体类的有参构造方法
    public User(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }
    
    
    
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    // 生成对应的toString方法
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", password='" + password + ''' +
                '}';
    }
    
}
2.编写MyBatisUtils工具类
public class MybatisUtils {
    
    // 获取静态变量sqlSessionFactory
    private static SqlSessionFactory sqlSessionFactory;
    
    // 静态方法体
    static {
        try {
            String resource = "mybatis-config.xml";
            // 读取配置文件
            InputStream inputStream = Resources.getResourceAsStream(resource); 
            // 获取工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
   
   public static SqlSession getSqlSession() {
       return sqlSessionFactory.openSession();
   }
    
}
9.2.2 编写接口和核心配置文件 1.编写UserMapper接口
  • 注解在接口的方法上实现
public interface UserMapper {
    
    
    @Select("Select * from user")
    List getUsers();
    
}
2.编写db.properties配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
pwd=123456
3.编写mybatis-config.xml配置文件

注意:我们必须要将接口注册绑定到我们的核心配置文件中!





    
    
    
    
        
    
    
    
    
        
    
    
    
    
        
        
            
            
            
            
                
                
                
                
            
        
    
    
    
    
        
    
    

9.2.3 编写测试类和查看测试结果 1.编写UserMapperTest测试类
public class UserMapperTest {
    
    @Test
    public void test() {
        // 获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // 获取mapper接口类: 底层主要使用反射,通过反射来获取包的全类名
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //调用getUsers方法
        List users = mapper.getUsers();
        // 使用foreach循环遍历数组
        for (User user : users) {
            System.out.println(user);
        }
        // 关闭sqlSession
        sqlSession.close();
    }
    
}
2.测试结果

结果:虽然测试成功,并没有报错,但仔细观察结果后发现password的值却为null!

9.2.4 注解开发的优缺点

优点:使用注解来映射简单语句,会使代码显得更加简洁

缺点:对于稍微复杂一点的语句,Java注解就力不从心了,并且会显得更加混乱

因此,如果需要完成很复杂的事情,最好使用xml来映射语句

9.2.5 使用断点解析原理 1.设置断点和Debug测试
  • 首先在获取用户信息这行设置断点,然后在test()方法旁右击选择Debug测试

2.测试结果分析

通过sqlSession获取变量后,mapper再次获取调用sqlSession,而mapper中的mapperInterface就是mapper接口,在mapperInterface下找到了com.kuang.dao.UserMapper

sqlSession拿到数据库配置

mapperInterface获取接口对象

methodCache缓存

9.3 拓展知识 9.3.1 代理模式

9.3.2 MyBatis执行流程

9.4 使用注解实现增删改查 9.4.1 使用注解实现查询用户 1.修改MyBatisUtils工具类
  • 可以在工具类创建的时候实现自动提交
public class MybatisUtils {
    
    // 获取静态变量sqlSessionFactory
    private static SqlSessionFactory sqlSessionFactory;
    
    // 静态方法体
    static {
        try {
            String resource = "mybatis-config.xml";
            // 读取配置文件
            InputStream inputStream = Resources.getResourceAsStream(resource); 
            // 获取工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
   
   public static SqlSession getSqlSession() {
       // 设置参数为true,实现自动提交
       return sqlSessionFactory.openSession(true);
   }
    
}
2.修改UserMapper接口 2-1 正常测试
public interface UserMapper {
    
    
    @Select("Select * from user where id = #{id}")
    User getUserById(@Param("id") int id);
    
}
2-2 将id改为id2
  • @Param注解中的值id修改为id2
public interface UserMapper {
    
    
    @Select("Select * from user where id = #{id}")
    User getUserById(@Param("id") int id2);
}
  • 方法参数中的id修改为id2
public interface UserMapper {
    
    
    @Select("Select * from user where id = #{id}")
    User getUserById(@Param("id2") int id);
    
}
3.编写UserMapperTest测试类
public class UserMapperTest {
    
    @Test
    public void getUserById() {
        // 获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // 获取mapper接口类(底层主要使用反射,通过反射来获取包的全类名)
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        // 调用getUserById方法获取用户信息
        User userById = mapper.getUserById(1);
        // 打印查询到的用户信息
        System.out.println(userById);
        // 关闭sqlSession
        sqlSession.close();
    }
    
}
4.测试结果 4-1 正常测试结果

4-2 将id改为id2
  • @Param注解中的值id修改为id2

测试结果报错:参数id找不到!

  • 方法参数中的id修改为id2

结果:测试成功!

因此,@Select注解中的id与@Param注解中的id要一致!

9.4.2 使用注解实现增加用户 1.修改UserMapper接口
public interface UserMapper {
    
    
    @Insert("Insert into user(id,name,pwd) values(#{id},#{name},#{password})")
    int addUser(User user);
    
}
3.编写UserMapperTest测试类
public class UserMapperTest {
    
    @Test
    public void addUser() {
        // 获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // 获取mapper接口类:底层主要使用反射,通过反射来获取包的全类名
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        // 调用addUser方法并设置返回的结果集:实现用户信息的增加
        int result = mapper.addUser(new User(6,"陈奕迅","cyx123456"));
        // 判断结果集的值是否大于0
        if (result>0) {
            System.out.println("插入成功!");
        }
        // 关闭sqlSession
        sqlSession.close();
    }
    
}
4.正常测试结果
  • 查看控制台输出
  • 查看数据库信息

结果:成功插入一条用户信息!

5.Debug测试结果
  • int result这行设置断点,点击addUser()方法旁的Debug测试

  • 可以看到autoCommit的值由默认的false变为了true

因为在Mybatis工具类中已经设置了自动提交事务,因此测试方法中就不需要再次设置了,但是一般不建议设置自动提交事务,因为这样容易出现错误!

9.4.3 使用注解实现修改用户 2.修改UserMapper接口
public interface UserMapper {
    
    
    @Update("Update user set name = #{name},pwd = #{password} where id = #{id}")
    int updateUser(User user);  
    
}
3.编写UserMapperTest测试类
public class UserMapperTest {
    
    @Test
    public void updateUser() {
        // 获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // 获取mapper接口类(底层主要使用反射,通过反射来获取包的全类名)
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        // 调用updateUser方法, 实现插入用户信息
         mapper.updateUser(new User(6,"张惠妹","zhm123456"));
        // 关闭sqlSession
        sqlSession.close();
    }
    
}
4.测试结果
  • 查看控制台输出

  • 查看数据库信息

结果:成功更新一条用户信息!

9.4.4 使用注解实现删除用户 2.修改UserMapper接口
public interface UserMapper {
    
    
    @Delete("Delete from user where id = #{uid}")
    int deleteUser(@Param("uid") int id);
    
}
3.编写UserMapperTest测试类
public class UserMapperTest {
    
    @Test
    public void deleteUser() {
        // 获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // 获取mapper接口类(底层主要使用反射,通过反射来获取包的全类)
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        // 调用updateUser方法, 实现插入用户信息
        mapper.deleteUser(4);
        // 关闭sqlSession
        sqlSession.close();
    }
    
}
4.测试结果
  • 查看控制台输出

  • 查看数据库信息

结果:成功删除id为4的用户信息!

9.5.5 关于@Param()注解
  • 基本类型的参数或者String类型,需要加上
  • 引用类型不需要加
  • 如果只有一个基本类型的话,可以忽略,但是建议加上
  • 在SQL中引用就是这里的@Param注解中设定的属性名!
9.5.6 #{} 和 ${} 区别
  • 一般使用 #{},能够很大程度上防止SQL注入!
  • ${} 方式无法防止SQL注入
  • $ 一般用于传入数据库对象,比如数据库表名
  • 能用 #{} 时尽量用 #{}

好了,今天的有关 使用注解开发 的学习就到此结束啦。欢迎小伙伴们积极学习和讨论,喜欢的可以给蜗牛君点个关注,顺便来个一键三连。我们下期见,拜拜啦!


参考视频链接:【狂神说Java】Mybatis最新完整教程IDEA版通俗易懂

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/425038.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号