zoukankan      html  css  js  c++  java
  • JavaEE MyBatis (一) 基础概念

    1. 什么是框架?

    MyBatis 就是一个操作数据库的框架,框架就是软件功能的半成品,框架提供了一个软件项目中通用的功能,将大多数常见的功能进行封装,无需自己重复开发。

    2. 什么是对象关系映射?

    MyBatis 是一个基于 “ORM” 的框架,ORM 的全称是对象关系映射(Object Relational Mapping).

    对象(Object)就是Java中的对象,关系(Relational)就是数据库中的数据表,基于 “ORM” 的框架是把数据在对象和关系之间进行双向转换。

    ORM 的细节可以从 3 个方面来介绍:

    (1)1 个类 对应 1 个表。

    (2)1 个类的对象 对应 表中的一行。

    (3)1 个类的对象中的属性 对应 1 个表中的列。

    ORM 映射关系如图 1-1 所示。

    MyBatis 框架可以将 Java 类中的数据转化为数据表中的记录,或者将数据表中的记录封装到 Java 类中,过程如图 1-2 所示:

    从图 1-2 的过程来看,程序员不再直接使用 JDBC 对象访问数据库,而是以面向对象的方式来使用实体类,对实体类进行的增加、删除、更新和查询操作都会由 ORM 框架转化成对数据库的增加、删除、更新和查询操作。

    ORM 框架内部的核心技术的原理其实就是 JDBC 和 反射,这个技术是由 ORM 框架、也就是 MyBatis 来进行封装的。

    3. MyBatis 的优势

    MyBatis 是现阶段操作数据库的主流框架,此框架的主要作用就是更加便捷地操作数据库。它具有很多优势,具体体现在以下 7 个方面:

    (1)ROW 行 与 Entity 实体类双向转换:可以将数据表中的 ROW 行与 Entity 实体类进行互相转换,比如将 ResultSet 对象返回的数据自动封装到 Entity 实体类 或 List 中,或将 Entity 实体类中的数据转换成数据表中新的一行 ROW。

    (2)SQL语句 与 Java文件 分离: 可以把 SQL 语句写到 XML 文件中,目的是将 SQL语句 与 Java文件 分离,使代码分层更明确。

    (3)允许对 SQL语句 进行自定义优化:因为 MyBatis框架 是使用 SQL语句 对数据库进行操作的,所以可以单独地对 SQL语句 进行优化,以提高操作效率。

    (4)减化 DAO层 代码:在使用传统的 JDBC 开发方式时,需要写上必要的 DAO层 代码以对数据库进行操作,但冗余代码太多,所以 MyBatis 解决了这个问题。使用 MyBatis 做查询时可以自动将数据表中的数据记录封装到 实体类 或 Map 中,再将它们放入 List 进行放回。

    (5)半自动化所带来的灵活性: MyBatis 是 “半自动化” 的 “ORM” 框架,但它应该算作 SQL映射框架(SQL Mapper Framework)。将 MyBatis 称为 “半自动化的 ORM 框架” 是因为 MyBatis 操作数据库时还是使用原始的 SQL 语句,这些 SQL语句 还需要程序员自己来进行设计,这就是半自动化。

    (6)支持 XML 或 Annotation 注解的方式进行 ORM :MyBatis 可以使用 XML 或 Annotations注解的方式 将数据表中的记录 映射成 1 个 Map 或 Java POJO 实体类对象,但推荐使用 XML 方式。

    (7)功能丰富:MyBatis 还可以实现自定义 SQL 段落、调用存储过程和进行高级映射等功能。

    4. ORM 的原理实现

    本章将用代码来模拟实现一个微型的 ORM 功能。

    4.1 使用 JDBC 和反射技术实现泛型 DAO

    MyBatis 实现 ROW 行与 Entity实体类双向转换的原理是基于 JDBC 和 反射技术,MyBatis 框架只是对 JDBC 技术进行了轻量级的封装,使程序员更方便地区操作数据库。

    创建获得 Connection 连接对象,代码如下:

    public class GetConnection {
        public static Connection getConnection() throws ClassNotFoundException, SQLException {
            // 使用 oracle驱动器
            String driverName = "oracle.jdbc.OracleDriver";
            String url = "jdbc:oracle:thin:@localhost:1521:orcl";
            String username = "y2";
            String password = "123";
            Class.forName(driverName);//Class.forName(String) 返回与给定字符串名称的类或接口相关联的 Class对象。
            Connection conn = DriverManager.getConnection(url, username, password);
            return conn;
        }
    }
    

    创建实体类 Userinfo,核心代码如下:

    public class Userinfo {
        private long id;
        private String username;
        private String password;
        
        public Userinfo(long id, String username, String password) {
            this.id = id;
            this.username = username;
            this.password = password;
        }
        
        //省去 get 和 set 方法
    }
    

    创建泛型 DAO 类 BaseDAO,代码如下:

    import java.lang.reflect.Field;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class BaseDao<T> {
        // 此方法模拟了 MyBatis 的 save() 方法
        // MyBatis 框架内部的核心和本示例基本一样
        // 使用的技术就是 JDBC 和 反射
        public void save(T t)
                    throws IllegalArgumentException, IllegalAccessException,
                ClassNotFoundException, SQLException {
            String sql = "insert into";
            String colName = "";
            String colParam = "";
            String begin = "(";
            String end = ")";
            Class classRef = t.getClass(); //反射获取 t 的类对象
            String tableName=classRef.getSimpleName().toLowerCase(); //getSimpleName获取具体类名称,如main
            sql = sql + tableName;
            List values = new ArrayList();
            Field[] fieldArray = classRef.getDeclaredFields();// 返回一个 Field对象,该对象反映由该 Class对象表示的类或接口的指定声明字段。 
            for (int i = 0; i < fieldArray.length; i++) {
                Field eachField = fieldArray[i];
                eachField.setAccessible(true); //跳过连通性检验
                String eachFieldName = eachField.getName();
                Object eachValue = eachField.get(t);
                colName = colName + "," + eachFieldName;
                colParam = colParam + ",?";
                values.add(eachValue);
            }
            colName = colName.substring(1);
            colParam = colParam.substring(1);
            sql = sql + begin + colName + end;
            sql = sql + " values" + begin + colParam + end;
            System.out.println(sql);
            for (int i = 0; i < values.size(); i++) {
                System.out.println(values.get(i));
            }
    
            Connection conn = GetConnection.getConnection();
            PreparedStatement ps = conn.prepareStatement(sql); //JDBC 的预编译函数
            for (int i = 0; i < values.size(); i++) {
                ps.setObject(i + 1, values.get(i)); //批处理
            }
            ps.executeUpdate();
            ps.close();
            conn.close();
        }
        //Mybatis 的 get() 方法
          ...  
        //Mybatis 的 update() 方法
          ...  
        //Mybatis 的 delete() 方法
          ...  
        //由于方法实现大致类似,故在此省略
    }
    

    增加记录的代码如下:

    public class Insert {
        public static void main(String[] args) 
                throws IllegalArgumentException, IllegalAccessException, 
                ClassNotFoundException, SQLException {
            Userinfo userinfo = new Userinfo();
            userinfo.setId(1000L);
            userinfo.setPassword("中国人");
            userinfo.setUsername("中国");
            BaseDao<Userinfo> dao = new BaseDao<Userinfo>();
            dao.save(userinfo);
        }
    }
    

    以上代码的作用就是使用 JDBC 结合反射技术来将数据表中的 1 行记录和实体类进行双向转换,这也是 ORM 框架的原理。以上代码用到了 JDBC(结合)反射技术,MyBatis 实现 ORM 的原理就是 JDBC 和 反射技术。

    4.2 操作 XML 文件

    XML,全称是 eXtensible Markup Language(可扩展标记语言),它可以自定义标记名称与内容,在灵活度上相比相比 HTML 有大幅提高,经常用在配置以及数据交互领域。

    XML具体语法及操作

    Java 读取 XML 文件中的内容

  • 相关阅读:
    Windows Phone 8 开发环境搭建
    常用正则表达式大全分享
    ios 使用NSRegularExpression解析正则表达式
    大整数类BIGN的设计与实现 C++高精度模板
    CODEVS_1227 方格取数2 网络流 最小费用流 拆点
    CODEVS_1034 家园 网络流 最大流
    CODEVS_1033 蚯蚓的游戏问题 网络流 最小费用流 拆点
    HDU_4770 Lights Against Dudely 状压+剪枝
    CODEVS_2144 砝码称重 2 折半搜索+二分查找+哈希
    CODEVS_1074 食物链
  • 原文地址:https://www.cnblogs.com/john1015/p/13928579.html
Copyright © 2011-2022 走看看