MyBatis入门

1、MyBatis 是优秀的持久层框架
2、MyBatis 使用 XML 将 SQL 与程序解耦,便于维护
3、MyBatis 学习简单,执行高效,是 JDBC 的延伸

中文参考网址:https://mybatis.net.cn/

一、mybatis-config.xml




    
        
        
    
    
    
        
        
        
            
            
            
            
            
            
                
                
                
                
                
                
                
                
            
        

        
        
            
            
            
            
                
                
                
                
                
                
                
                
            
        
    

二、初始化工具类 MyBatisUtils

/**
 * MyBatis工具类,创建全局唯一的 SqlSessionFactory 对象
 */
public class MyBatisUtils {

    // 利用 static(静态) 属于类不属于对象,且全局唯一
    private static SqlSessionFactory sqlSessionFactory = null;

    // static块用于初始化静态变量
    // 利用静态块在初始化类时实例化 sqlSessionFactory 对象
    static {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            // 初始化错误时,通过抛出 ExceptionInInitializerError 通知调用者
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * 创建一个新的 SqlSession 对象
     * @return SqlSession对象
     */
    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }

    /**
     * 释放一个有效的 SqlSession 对象
     * @param session 准备释放的 SqlSession 对象
     */
    public static void closeSession(SqlSession session) {
        if (session != null) {
            session.close();
        }
    }
}

三、MyBatis 数据操作

  • 1、创建实体类(Entity)
  • 2、创建Mapper XML
  • 3、编写 select * from t_goods order by goods_id desc limit 10

    2、单参数查询

        
        
    
        // 测试用例
        @Test
        public void testSelectOne() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                Goods goods = sqlSession.selectOne("goods.selectById", 1602);
                System.out.println(goods.getTitle());
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    3、多参数查询

        
        
    
        // 测试用例
        @Test
        public void testSelectByPriceRange() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                HashMap map = new HashMap<>();
                map.put("min", 100);
                map.put("max", 500);
                map.put("limit", 10);
                List list = sqlSession.selectList("goods.selectByPriceRange", map);
                for (Goods g : list) {
                    System.out.println(g.getTitle() + ":" + g.getCurrentPrice());
                }
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    4、获取多表关联查询结果

        
        
    
        // 测试用例
        @Test
        public void testSelectGoodsMap() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                List list = sqlSession.selectList("goods.selectGoodsMap");
                for (Map map :
                        list) {
                    System.out.println(map);
                }
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    5、 ResultMap结果映射

        
        
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
        
    
        // 测试用例
        @Test
        public void testSelectGoddsDTO() throws Exception {  
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                List list = sqlSession.selectList("goods.selectGoodsDTO");
                for (GoodsDTO g : list) {
                    System.out.println(g.getGoods().getTitle());
                }
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    6、 动态SQL查询

        
    
        // 测试用例
        @Test
        public void testDynamicSQL() {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                Map map = new HashMap<>();
                map.put("category_id", 44);
                map.put("currentPrice", 500);
                List list = sqlSession.selectList("goods.dynamicSQL", map);
                for (Goods g : list) {
                    System.out.println(g.getTitle());
                }
            } catch (Exception e) {
                if (sqlSession != null) {
                    sqlSession.rollback();
                }
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    7、OneToMany对象关联查询

        
        
            
            
            
            
        
        
    
        // 测试用例
        @Test
        public void testOneToMany() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                List list = sqlSession.selectList("goods.selectOneToMany");
                for (Goods g : list) {
                    System.out.println(g.getTitle() + ":" + g.getGoodsDetails().size());
                }
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    8、ManyToOne对象关联查询

        
            
            
        
        
    
        // 测试用例
        @Test
        public void testManyToOne() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                List list = sqlSession.selectList("goodsDetail.selectManyToOne");
                for (GoodsDetail g : list) {
                    System.out.println(g.getGdPicUrl() + ":" + g.getGoods().getTitle());
                }
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    (二)数据插入

        
        
            insert into t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
            values (#{title}, #{subTitle}, #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})
            
                select last_insert_id();
            
        
    
        
        
            insert into t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
            values (#{title}, #{subTitle}, #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})
        
    
        // 测试用例
        @Test
        public void testInsert() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                Goods goods = new Goods();
                goods.setTitle("测试标题");
                goods.setSubTitle("测试副标题");
                goods.setOriginalCost(12.f);
                goods.setCurrentPrice(1231.f);
                goods.setDiscount(0.1f);
                goods.setIsFreeDelivery(1);
                goods.setCategoryId(1);
                int num = sqlSession.insert("goods.insert", goods);
                sqlSession.commit();
                System.out.println(goods.getGoodsId());
            } catch (Exception e) {
                if (sqlSession != null) {
                    sqlSession.rollback();
                }
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
    
        }
    

    (三)数据更新

        
            update t_goods
            set
                title=#{title},
                sub_title=#{subTitle},
                original_cost=#{originalCost},
                current_price=#{currentPrice},
                discount=#{discount},
                is_free_delivery=#{isFreeDelivery},
                category_id=#{categoryId}
            where goods_id=#{goodsId};
        
    
        // 测试用例
        @Test
        public void testUpdate() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                Goods goods = sqlSession.selectOne("goods.selectById", 740);
                goods.setTitle("更新测试商品标题");
                int num = sqlSession.update("goods.update", goods);
                sqlSession.commit();
            } catch (Exception e) {
                if (sqlSession != null) {
                    sqlSession.rollback();
                }
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    (四)数据删除

        
            delete from t_goods where goods_id=#{value}
        
    
        // 测试用例
        @Test
        public void testDelete() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                int num = sqlSession.delete("goods.delete", 740);
                sqlSession.commit();
            } catch (Exception e) {
                if (sqlSession != null) {
                    sqlSession.rollback();
                }
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    四、MyBatis 预防SQL注入攻击

    SQL注入是指攻击者利用SQL漏洞,绕过系统约束,越权获取数据的攻击方式

    sql注入.png

    MyBatis两种传值方式

    • ${} 文本替换,未经任何处理对SQL文本替换
    • #{}预编译传值,使用预编译传值可以预防SQL注入

    五、MyBatis工作流程

    work_process.png

    六、MyBatis日志管理

    • 日志文件是用于记录系统操作事件的记录文件或文件集合
    • 日志保存历史数据,是诊断问题以及理解系统活动的重要依据
    logback官网:https://logback.qos.ch/
    1、在 resources目录下新建logback.xml文件(文件名为固定写法),文件内容如下
    
    
        
            
                %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            
        
        
        
            
        
    
    

    七、MyBatis二级缓存

    1、一级缓存默认开启,缓存范围 SqlSession 会话
    2、二级缓存手动开启,属于范围 Mapper Namespace

    1、二级缓存运行规则
    • 1、二级缓存后默认所有查询操作均使用缓存
    • 2、写操作 commit 提交时对该 namespace 缓存强制清空
    • 3、配置 userCache=false 可以不用缓存
    • 4、配置 flushCache=true 代表强制清空缓存
        @Test
        public void testLv1Cache() throws Exception {
            // 一级缓存默认开启,缓存范围 SqlSession 会话
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                Goods goods = sqlSession.selectOne("goods.selectById", 1603);
                Goods goods1 = sqlSession.selectOne("goods.selectById", 1603);
                System.out.println(goods.hashCode() + ":" + goods1.hashCode());
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
    
            try {
                sqlSession = MyBatisUtils.openSession();
                Goods goods = sqlSession.selectOne("goods.selectById", 1603);
                // 写操作 commit 提交时对该 namespace 缓存强制清空
                sqlSession.commit();
                Goods goods1 = sqlSession.selectOne("goods.selectById", 1603);
                System.out.println(goods.hashCode() + ":" + goods1.hashCode());
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    
        
        
        
        
    
        @Test
        public void testLv2Cache() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                Goods goods = sqlSession.selectOne("goods.selectById", 1603);
                System.out.println(goods.hashCode());
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
    
            try {
                sqlSession = MyBatisUtils.openSession();
                Goods goods = sqlSession.selectOne("goods.selectById", 1603);
                System.out.println(goods.hashCode());
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

    八、PageHelper分页插件

    官网地址:https://pagehelper.github.io/

    1、使用流程
    • 1、maven 引入 PageHelperjssqlparser
            
                com.github.pagehelper
                pagehelper
                5.3.1
            
            
                com.github.jsqlparser
                jsqlparser
                4.4
            
    
    • 2、mybatis-config.xml 增加 Plugin 配置
        
        
            
                
                
                
                
            
        
    
    • 3、代码中使用 PageHelper.startPage() 自动分页
        
    
        @Test
        public void testSelectPage() throws Exception {
            SqlSession sqlSession = null;
            try {
                sqlSession = MyBatisUtils.openSession();
                /*startPage方法会自动将下一次查询进行分页*/
                PageHelper.startPage(2, 10);
                Page page = (Page)sqlSession.selectList("goods.selectPage");
                System.out.println("总页数:" + page.getPages());
                System.out.println("总记录数:" + page.getTotal());
                System.out.println("开始行号:" + page.getStartRow());
                System.out.println("结束行号:" + page.getEndRow());
                System.out.println("当前页码:" + page.getPageNum());
                List list = page.getResult(); // 当前页数据
                for (Goods g : list) {
                    System.out.println(g.getTitle());
                }
                System.out.println("");
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    
    

    九、MyBatis批处理

    1、批量增加
        
        
            insert into t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
            values
            
                (#{item.title}, #{item.subTitle}, #{item.originalCost}, #{item.currentPrice}, #{item.discount}, #{item.isFreeDelivery}, #{item.categoryId})
            
        
    
        @Test
        public void tesBatchInsert() throws Exception {
            SqlSession sqlSession = null;
            try {
                long st = new Date().getTime();
                sqlSession = MyBatisUtils.openSession();
                List list = new ArrayList();
                for (int i = 0; i < 10000; i++) {
                    Goods goods = new Goods();
                    goods.setTitle("测试商品哈哈");
                    goods.setSubTitle("测试子标题");
                    goods.setOriginalCost(200f);
                    goods.setCurrentPrice(100f);
                    goods.setDiscount(0.5f);
                    goods.setIsFreeDelivery(1);
                    goods.setCategoryId(43);
                    list.add(goods);
                }
                sqlSession.insert("goods.batchInsert", list);
                sqlSession.commit();
                long et = new Date().getTime();
                System.out.println("执行时间:" + (et - st) + "毫秒");
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    
    2、批量删除
        
        
            delete from t_goods where goods_id in
            
                #{item}
            
        
    
        @Test
        public void testBatchDelete() throws Exception {
            SqlSession sqlSession = null;
            try {
                long st = new Date().getTime();
                sqlSession = MyBatisUtils.openSession();
                List list = new ArrayList();
                for (int i = 2674; i < 10750; i++) {
                    list.add(i);
                }
                sqlSession.delete("goods.batchDelete", list);
                sqlSession.commit();
                long et = new Date().getTime();
                System.out.println("执行时间:" + (et - st) + "毫秒");
    
            } catch (Exception e) {
                throw e;
            } finally {
                MyBatisUtils.closeSession(sqlSession);
            }
        }
    

你可能感兴趣的:(MyBatis入门)