mybatis回顾

mybatis

1. 自定义持久层框架

1.1 JDBC


    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 加载数据库驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 通过驱动管理类获取数据库链接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis? characterEncoding=utf-8", "root", "root");
            String sql = "select * from user where username = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, "tom");
            rs = ps.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                String username = rs.getString("username");
                user.setId(id);
                user.setUsername(username);
            }
            System.out.println(user);
        } catch (Exception e) {
            e.printStackTrace();
        } finally { // 释放资源
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    } 
	//dom4j解析xml
	Document document = new SAXReader().read(inputStream);
	Element rootElement = document.getRootElement();
	//获取所有property标签
	List<Element> list = rootElement.selectNodes("//property");
	Properties properties = new Properties();
	for (Element element : list) {
	    String name = element.attributeValue("name");
	    String value = element.attributeValue("value");
	    properties.setProperty(name,value);
	}

JDBC问题总结:
原始jdbc开发存在的问题如下:
1、 数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能。
2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变 java代码。
3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能 多也可能少,修改sql还要修改代码,系统不易维护。
4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据 库 记录封装成pojo对象解析比较方便

1.2 连接池

	ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
	try {
	     comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
	     comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3307/test");
	     comboPooledDataSource.setUser("root");
	     comboPooledDataSource.setPassword("root");
	     Connection connection = comboPooledDataSource.getConnection();
	     PreparedStatement preparedStatement = connection.prepareStatement("select * from a");
	     ResultSet resultSet = preparedStatement.executeQuery();
	     while (resultSet.next()) {
	         System.out.println(resultSet.getInt("id"));
	     }
	 } catch (Exception e) {
	     e.printStackTrace();
	 }

1.2.1 连接池封装版
ComboPooledDataSource  comboPooledDataSource = new ComboPooledDataSource();

    //@Value后续
    private String className = "com.mysql.jdbc.Driver";
    private String url = "jdbc:mysql://localhost:3307/test";
    private String userName = "root";
    private String password = "root";

    private void initPool() throws PropertyVetoException {
        if(comboPooledDataSource.getUser() == null) {
            comboPooledDataSource.setDriverClass(className);
            comboPooledDataSource.setJdbcUrl(url);
            comboPooledDataSource.setUser(userName);
            comboPooledDataSource.setPassword(password);
        }
    }
    PreparedStatement getPrepareStatement(String sql) throws SQLException, PropertyVetoException {
        initPool();
        return comboPooledDataSource.getConnection().prepareStatement(sql);
    }

    public void excute(String sql ,Object ... params) {
        try {
            PreparedStatement preparedStatement = getPrepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i+1,params[i]);
            }
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                System.out.println(resultSet.getInt("id"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
1.2.2 返回值使用 反射或者内省 封装类
ResultSet resultSet = preparedStatement.executeQuery();
        String resultType = mappedStatement.getResultType();
        Class<?> resultTypeClass = getClassType(resultType);

        ArrayList<Object> objects = new ArrayList<>();

        // 6. 封装返回结果集
        while (resultSet.next()){
            Object o =resultTypeClass.newInstance();
            //元数据
            ResultSetMetaData metaData = resultSet.getMetaData();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {

                // 字段名
                String columnName = metaData.getColumnName(i);
                // 字段的值
                Object value = resultSet.getObject(columnName);

                //使用反射或者内省,根据数据库表和实体的对应关系,完成封装
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
                Method writeMethod = propertyDescriptor.getWriteMethod();
                writeMethod.invoke(o,value);


            }
            objects.add(o);

        }
            return (List<E>) objects;

1.3 反射获取类变量值

try {
            Class<?> aClass = Class.forName("类的全路径");
            //反射
            Field declaredField = aClass.getDeclaredField("变量名称");
            //暴力访问
            declaredField.setAccessible(true);
            Object o = declaredField.get("对应类的对象");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

1.4 自定义框架设计

使用端:
提供核心配置文件:
sqlMapConfig.xml : 存放数据源信息,引入mapper.xml Mapper.xml : sql语句的配置文件信息
框架端:
1.读取配置文件
读取完成以后以流的形式存在,我们不能将读取到的配置信息以流的形式存放在内存中,不好操作,可 以创建javaBean来存储
(1)Configuration : 存放数据库基本信息、Map<唯一标识,Mapper> 唯一标识:namespace + “.” +
id
(2)MappedStatement:sql语句、statement类型、输入参数java类型、输出参数java类型
2.解析配置文件
创建sqlSessionFactoryBuilder类:
方法:sqlSessionFactory build():
第一:使用dom4j解析配置文件,将解析出来的内容封装到Configuration和MappedStatement中 第二:创建SqlSessionFactory的实现类DefaultSqlSession
3.创建SqlSessionFactory:
方法:openSession() : 获取sqlSession接口的实现类实例对象
4.创建sqlSession接口及实现类:主要封装crud方法
方法:selectList(String statementId,Object param):查询所有 selectOne(String statementId,Object param):查询单个
具体实现:封装JDBC完成对数据库表的查询操作 涉及到的设计模式:
Builder构建者设计模式、工厂模式、代理模式

2. Mybatis基础回顾和高级应用

2.1 Mybatis相关概念

2.1.1 ORM : Object/Relation Mapping

对象-关系映射,其实就是实体类和数据库表产生映射关系,从而达到操作实体类等用于操作数据库

2.1.2 Mybatis 简介

Mybatis是一款基于ORM的半自动轻量级持久层框架

2.2 Mybatis常用配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 Mybatis复杂映射

2.2.1 一对一

在这里插入图片描述

在这里插入图片描述

2.2.1.1 一对一(注解)

概述:用户和订单,一个订单只对应一个用户,查询订单并查询关联的用户,就是一对一
cs

2.2.2 一对多

在这里插入图片描述

在这里插入图片描述

2.2.2.1 一对多(注解)

概述:用户和订单,一个用户对应多个订单,查询用户并查询关联的订单,就是一对多
在这里插入图片描述

2.2.3 多对多

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.3.1 多对多(注解)

在这里插入图片描述

2.3 Mybatis缓存

缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存,我们可以避免频繁的与数据库 进行交互,进而提高响应速度

2.3.1 一级缓存

一级缓存到底是什么?
一级缓存底层实现是hashmap

一级缓存什么时候被创建、一级缓存的工作流程是怎样的?
一级缓存在执行查询语句前被创建,在语句执行前进行get,有缓存就使用缓存,没有缓存就查询数据库,然后将数据放进缓存中,缓存会在增删改的操作中进行重置,避免脏读

2.3.2 二级缓存

原理和一级缓存一样,区别于一级缓存作用于sqlsession,而二级缓存作用于mapper文件的namespace,也就是说多个sqlsession可以共享一个mapper中的二级缓存区域

在这里插入图片描述
注解版:
在这里插入图片描述

2.3.2.1 二级缓存整合redis

上面介绍了 mybatis自带的二级缓存,但是这个缓存是单服务器工作,无法实现分布式缓存。 那么 什么是分布式缓存呢?假设现在有两个服务器1和2,用户访问的时候访问了 1服务器,查询后的缓 存就会 放在1服务器上,假设现在有个用户访问的是2服务器,那么他在2服务器上就无法获取刚刚那个 缓存

在这里插入图片描述

2.4 Mybatis插件

2.4.1 pageHelper分页插件Mybatis插件

在这里插入图片描述
在这里插入图片描述

2.4.2 通用mapper

通用Mapper就是为了解决单表增删改查,基于Mybatis的插件机制。开发人员不需要编写SQL,不需要 在DAO中增加方法,只要写好实体类,就能支持相应的增删改查方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 设计模式

3.1 Builder构建者模式

Builder模式定义
"将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表 示。”

它属于创建类模式,一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范 围,就可以使用工厂模式和Builder模式,相对于工厂模式会产出一个完整的产品,Builder应用于更加 复杂的对象的构建,甚至只会构建产品的一个部分

直白来说,就是使用多个简单的对象一步一步构建 成一个复杂的对象

3.2 工厂模式

在Mybatis中比如SqlSessionFactory使用的是工厂模式,该工厂没有那么复杂的逻辑,是一个简单工厂 模式。
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于创 建型模式。
在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建 其他类的实例,被创建的实例通常都具有共同的父类
例子:生产电脑
假设有一个电脑的代工生产商,它目前已经可以代工生产联想电脑了,随着业务的拓展,这个代工生产 商还要生产惠普的电脑,我们就需要用一个单独的类来专门生产电脑,这就用到了简单工厂模式。

3.3 代理模式

代理模式(Proxy Pattern):给某一个对象提供一个代理,并由代理对象控制对原对象的引用。 它是一种对象结构型模式,代理模式分为静态代理和动态代理
简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。

静态代理:由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口、被代理类、代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的影城管理系统,源码+数据库+论文答辩+毕业论文+视频演示 随着现在网络的快速发展,网上管理系统也逐渐快速发展起来,网上管理模式很快融入到了许多生活之中,随之就产生了“小徐影城管理系统”,这样就让小徐影城管理系统更加方便简单。 对于本小徐影城管理系统的设计来说,系统开发主要是采用java语言技术,在整个系统的设计中应用MySQL数据库来完成数据存储,具体根据小徐影城管理系统的现状来进行开发的,具体根据现实的需求来实现小徐影城管理系统网络化的管理,各类信息有序地进行存储,进入小徐影城管理系统页面之后,方可开始操作主控界面,主要功能包括管理员:首页、个人中心、用户管理、电影类型管理、放映厅管理、电影信息管理、购票统计管理、系统管理、订单管理,用户前台;首页、电影信息、电影资讯、个人中心、后台管理、在线客服等功能。 本论文主要讲述了小徐影城管理系统开发背景,该系统它主要是对需求分析和功能需求做了介绍,并且对系统做了详细的测试和总结。具体从业务流程、数据库设计和系统结构等多方面的问题。望能利用先进的计算机技术和网络技术来改变目前的小徐影城管理系统状况,提高管理效率。 关键词:小徐影城管理系统;Spring Boot框架,MySQL数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值