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

Mybatis

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

Mybatis

Mybatis

环境:

  • JDK1.8
  • Mysql5.7
  • maven 3.6.1
  • IDEA

回顾

  • JDBC

  • Mysql

  • Java基础

  • Maven

  • Junit

1. 简介

1.1 什么是Mybatis

  • MyBatis 是一款优秀的持久层框架
  • 它支持自定义 SQL、存储过程以及高级映射
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录

获取Mabatis?

  • maven 仓库
  • Github:
  • 中文文档:https://mybatis.org/mybatis-3/zh/index.html

1.2 持久化(动作)

数据持久化

  • 持久化就是将程序的数据在持久化状态和顺时状态转化的过程
  • 内存:断电即失
  • 数据库(JDBC),Io文件持久化
  • 生活:冷藏、罐头

为什么需要持久化?

  • 有一些对象,不能丢掉
  • 内存太贵

1.3 持久层(名词)

Dao层、 Service层、Controller层

  • 完成持久化工作的代码
  • 层界限十分明显

1.4 为什么要用Mybatis

  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql
2.Mybatis程序(mybatis-01)

思路:搭建环境->导入Mybatis ->编写->测试

2.1 搭建环境

搭建数据库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r2EmA9U2-1634717837867)(Mybatis.assets/image-20210718153253955.png)]

新建项目

  1. 新建一个普通的Maven项目
  2. 删除src目录
  3. 导入maven依赖

    
    
        mysql
        mysql-connector-java
        5.1.47
    
    
    
        org.mybatis
        mybatis
        3.5.2
    
    
    
        junit
        junit
        4.12
    

2.2 创建一个模块
  • 编写mybatis核心配置文件(连接DB)





    
        
            
            
                
                
                
                
            
        
    

  • 编写mybatis工具类
//sqlSessionFactory->sqlSession
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;//提升作用域

    static{
        try {
            //使用Mybatis第一步:获取sqlSessionFactory对象
            String  resources = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resources);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //有了SqlSessionFactory,就可以从中获得到SqlSession的实例了
    //SqlSession 完全包含了面向数据库执行SQL命令所需的所有方法
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}
2.3 编写代码
  • 实体类
public class User {
    private int id;
    private  String name;
    private  String pwd;
}
  • Dao接口
public interface UserDao {
    List getUserList();
}
  • 接口实现类(由原来的UserDaoImpl转变成一个Mapper配置文件)最后调用接口实现类,来操作实体类

    namespace绑定类型、resultMap返回的是一个集合、resultType返回一个类型






     
        select  * from mybatis.user
   

2.4 测试

注意点

org.apache.ibatis.binding.BindingException: Type interface com.jyz.dao.UserDao is not known to the MapperRegistry.

MapperRegistry是什么? 核心配置文件中注册mappers

maven 由于它的约定大于配置,我们之后可能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:

不想导入,则可以把UserMapper.xml 放在resources 下面,但是那样就结构分离了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m4kpRjah-1634717837882)(Mybatis.assets/image-20210718174736871.png)]

  • junit测试

    public class UserDaoTest extends TestCase {
        @Test
        public void test(){
            //第一步:获得SqlSesision对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try {
                //方法1:getMapper执行Sql
                UserDao userDao = sqlSession.getMapper(UserDao.class);
                List userList = userDao.getUserList(); //我们可以执行接口里面的方法
                //方法2:List userList = sqlSession.selectList("com.jyz.dao.UserDao.getUserList");
                for (User user : userList) {
                    System.out.println(user);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭SqlSession
                sqlSession.close();;
            }
        }
    }
    

遇到的问题:

  1. 配置文件没有注册
  2. 绑定接口错误
  3. 方法名不对
  4. 返回类型不对
  5. Maven导出资源问题
3.CRUD
  1. namespace

namespace中的包名要和Dao/mapper接口的包名一致

 **2 . selecet**
  • id:就是对应的namespace中的方法名
  • resultType:Sql语句执行的返回值
  • parameterType: 参数类型与你传的参数有关
UserMapper userMapper = new UserMapperImpl()//原来
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//现在,相当与原来的上面操作

  1. 编写接口

    //根据ID查询用户
    User getUserById(int id);  //int id 基本类型参数
    
  2. 编写对应的mapper中的sql语句

     
     
        select * from mybatis.user where id = #{helloId} and name = #{name};
    
    
    //传个map即可
    HashMap map = new HashMap();
    map.put("helloId", 1);
    userMapper.getUserById2(map);
    
    1. 注意

    parameterType="int" 基础类型可以省略

    
        select  * from mybatis.user where  name like #{value}
    
    

    1.Java代码执行的时候,传递通配符%%(通过参数传递)

    List userlist = userMapper.getUserLike("%张%");  
    for (User user : userlist) {
        System.out.println(user);
    }
    

    2.在mapper.xml里面拼接%%(在sql里面拼接)

    List userlist = userMapper.getUserLike("张");  //应该在李这个地方用%拼接
    
      
         select  * from mybatis.user
    
    

    2.指定一个包名(扫描实体类的包,它的默认别名就为这个类的类名,首字母小写)

    
        
    
    
      
         select  * from mybatis.user
    
    
    5.设置

    这是MyBatis中极为重要的调整,会改变它的运行时行为

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8yHIqx5T-1634717837894)(Mybatis.assets/image-20210719230152335.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mvPCM9BL-1634717837896)(Mybatis.assets/image-20210719230226885.png)]

    6.映射器(mappers)

    MapperRegistry: 注册绑定我们的Mapper文件;(每写一个Dao文件,都会写一个mappe.xmlr文件)

    每一个Mapper.xml文件都需要在Mybatis核心配置文件中注册

    1.通过xml注册(推荐)

    
        
    
    

    2.通过类来注册

    
        
    
    

    方法二注意点

    • 接口和它的Mapper配置文件必须同名
    • 接口和它的Mapper配置文件必须在同一个包下 (而使用resources则是随便)

    3.使用扫描包进行注入绑定

    
        
    
    

    方法三注意点

    • 接口和它的Mapper配置文件必须同名
    • 接口和它的Mapper配置文件必须在同一个包下
    7.生命周期

    生命周期、作用域至关重要,因为错误的使用会导致非常严重的并发问题

    SqlSessionFactoryBuilder:

    • 一旦创建了SqlSessionFactory,就不再需要它了
    • 局部变量
    5.解决属性名和字段名不一致的问题(mybatis-03) 1.问题

    数据库中的字段

    public class User {
        private int id;
        private  String name;
        private  String password;......//与数据库中的pwd不一致
    }
    
    
            select * from mybatis.user where id = #{id}
        
    
    

    User{id=1, name=‘jyz’, password=‘123456’}

    • resultMap元素是MyBatis中最重要的元素
    • resultMap的设计思想是,对于简单的语句根本不需要配置显示的结果集映射,而对于复杂一点(字段名不一样)的语句,只需要描述它们的关系就行了

    id , name一致,则不用映射,只用映射不一样的字段即可

    
        
        
        
    
    
    6.日志(mybatis-04) 1.日志工厂

    如果有一个数据库操作,出现了异常,我们需要排查,需要日志

    曾今:sout、 debug

    现在: 日志工厂,掌握LOG4j STDOUT_LOGGING

    在mybatis具体使用哪个日志实现,在设置中设定

    标准日志工厂,什么均不用配

    
    
        
    
    

    2.Log4j
    • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
    • 我们也可以控制每一条日志的输出格式
    • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程
    • 通过一个配置文件来灵活地进行配置,而不需要修改应用的代码
    1. 导入log4j的包
    
            
                log4j
                log4j
                1.2.17
            
        
    
    

    2.log4j.properties

    #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
    1og4j.rootLogger=DEBUG,console,file
    #控制台输出的相关设置
    1og4j.appender.console.= org.apache.log4j.ConsoleAppender
    1og4j.appender.console.Target = System.out
    1og4j.appender.console.Threshold=DEBUG
    1og4j.appender.console.layout = org.apache.0g4j.PatternLayout
    1og4j.appender.console.layout.ConversionPattern=[%c] -%m%n
    #文件输出的相关设置
    1og4j.appender.file = org.apache.1og4j.RollingFileAppender
    
    #日志存放的位置
    1og4j.appender.file.File=./1og/jyz.log
    1og4j.appender.file.MaxFileSize=10mb
    1og4j.appender.file.Threshold=DEBUG
    1og4j.appender.file.layout=org.apache.1og4j.PatternLayout
    1og4j.appender.file.layout.ConversionPattern=[%p][%d{yy~MM-dd}][%c]%m%n
    #日志输出级别(只有DEBUG才会打印日志)
    1og4j.logger.org.mybatis=DEBUG
    1og4j.1ogger.java.sq1=DEBUG
    1og4j.logger.java.sq1.Statement=DEBUG
    1og4j.logger.java.sq1.ResultSet=DEBUG
    1og4j.logger.java.sq1.PreparedStatement=DEBUG
    
    #注意可用版本
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
    

    3.mybatis-config中配置log日志的实现

    
        
        
    
    

    4.直接测试运行刚才的查询

    简单使用

    1.在使用Log4j的类中,导入包import org.apache.log4j.Logger;

    2.日志对象,参数为当前类的class

    public class UserMapperTest extends TestCase {
        //一个日志可在多个方法中使用,提升作用域
        static Logger logger = Logger.getLogger(UserMapper.class);......
    

    3.日志级别

    logger.info("info:进入了testLog4j");
    logger.info("debug:进入了testLog4j");
    logger.info("error:进入了testLog4j");
    
    
    7.分页 1.使用Limit分页(Sql)



    使用Mybatis实现分页,核心sql

    1.接口

    //分页至少用两个参数,公司查用map
    List getUserByLimit(Map map);
    

    2.Mapperxml

    
            select * from student
        
    
        
            
            
            
            
            
        
        
        
        select  s.id sid, s.name sname, t.name tname
        from student s, teacher t
        where s.tid = t.id;
    
    
    
    
        
        
        
             
        
    
    

    回顾Mysql多对一查询方式:

    • 子查询
    • 连表查询
    11. 一对多处理(mybatis-07)

    一个老师拥有多个学生。对于老师而言,就是一对多的关系

    new 一个Module

    mybatis-07
    
    
        
            org.projectlombok
            lombok
            1.18.10
        
    
    
    @Data
    public class Student {
        private int id;
        private String name;
        //学生只有一个老师
        private int tid;
    }
    
    @Data
    public class Teacher {
        private  int id;
        private  String name;
        //要改为一对多,一个老师拥有多个学生
        private List students;
    }
    
    public interface TeacherMapper {
        //获取老师
        List getTeacher();
    }
    
    
        
            select  s.id sid, s.name sname, t.name tname, t.id tid
            from student s, teacher t
            where s.tid = t.id and t.id = #{tid};
        
    
        
            
            
            
            
            
                
                
                
            
        
    
    
    public class MyTest {
        public static void main(String[] args) {
            SqlSession sqlSession = MybatisUtils.getSqlSession();
                TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
                Teacher teacher = mapper.getTeacher(1);
                System.out.println(teacher);
                sqlSession.close();;
        }
    }
    
    
    按照查询嵌套处理

    改变

    
        select * from mybatis.student where tid = #{tid}
    
    

    小结

    1.关联-association (多对一)

    2.集合-collecton(一对多)

    3.javaType @ ofType

    1. JavaType用来指定实体类中属性的类型

    2. ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型

      注意一对多和多对一中,属性名和字段的问题!

      面试高频:Mysql引擎, innoDB底层原理, 索引, 索引优化

    12.动态SQL(mybatis-08)

    动态SQL:就是根据不同的条件,生成不同的SQL语句(建议先在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL,实现通用 即可)

    • if
    • choose (when, otherwise)
    • trim (where, set)
    • foreach

    创建一个基础工程:

    1. 导包

    2. 编写配置文件

    3. 编写实体类

    4.编写实体类对应Mapper接口和Mapper.XML文件

    public interface BlogMapper {
        //插入数据
        int addBlog(Blog blog);
    }
    
    
        
            insert into mybatis.blog (id, title, author, create_time, views)
            values (#{id},#{title},#{author},#{createTime},#{views})
        
    
    

    mybatis-config.xml

    
        
    
    
    @SuppressWarnings("all")  //抑制警告
    public class IDutils {
        public static String  getId(){
            return UUID.randomUUID().toString();
        }
        @Test
        public void test(){
            System.out.println(IDutils.getId());
        }
    }
    //77d88580-7ef3-45f4-92ce-96d368d9c515
    

    
            
            
            
            
    
    
    public class MyTest {
        @Test
        public void addInitBlog(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    
            Blog blog = new Blog();
            blog.setId(IDutils.getId());
            blog.setTitle("Mybatis如此简单");
            blog.setAuthor("江老师");
            blog.setCreateTime(new Date());
            blog.setViews(9999);
            mapper.addBlog(blog);
    
            blog.setId(IDutils.getId());
            blog.setTitle("Java如此简单");
            mapper.addBlog(blog);
    
            blog.setId(IDutils.getId());
            blog.setTitle("Spring如此简单");
            mapper.addBlog(blog);
    
            blog.setId(IDutils.getId());
            blog.setTitle("微服务如此简单");
            mapper.addBlog(blog);
            
            sqlSession.close();
        }
    

    if
    public interface BlogMapper {
        //插入数据
        int addBlog(Blog blog);
        //查询博客
        List queryBlogIF(Map map);
    }
    
    
        
            insert into mybatis.blog (id, title, author, create_time, views)
            values (#{id},#{title},#{author},#{createTime},#{views})
        
    
        
        select  * from mybatis.blog
        
        
            
                title = #{title}
            
            
                and author = #{author}
            
        
    
    

    采用set标签

    public interface BlogMapper {
        //更新博客
        int updateBlog(Map map);
    }
    
    
        update mybatis.blog
        
            
                title = #{title},
            
            
                author = #{author}
            
        
        where id = #{id}
    
    

    所谓的动态SQL,本质上还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码

    Foreach
    select * from user where 1=1 and (id =1 or id =2 or id=3)
    -- 改变
    
    select * from user where 1=1 and
    	
    	
    
    

    public interface BlogMapper {
        //查询1.2.3号记录的博客
        List queryBlogForeach(Map map);
    }
    
    
        select * from mybatis.blog
        
            
                id = #{id}
            
        
    
    

    SQL片段

    有的时候,我们可能将一些功能的部分抽取出来,方便复用

    1.使用SQL标签抽取公共的部分

    
        
            title = #{title}
        
        
            and author = #{author}
        
    
    

    2.在需要使用的地方使用include标签即可

    
    

    注意

    • 最好基于单表来定义SQL片段
    • 不要存在where标签
    13.缓存
    1. 什么是缓存(Cache)

      • 存在内存中的临时数据
      • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上查询。从缓存中查询,从而提高查询效率,解决了高并发的性能问题

      2.为什么使用缓存

    • 减少和数据库交互的次数,减少系统开销,提高系统效率

      3.什么样的数据库能使用缓存

    • 经常查询并且不经常改变的数据

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

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

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