• 一、Mybatis入门


    一、单独使用jdbc编程问题总结

      创建JDBC连接数据库

    • 创建resourcesjdbc.properties
    db.username=root
    db.password=root
    db.jdbcUrl=jdbc:mysql:///mybatisdb?useSSL=false&serverTimezone=UTC
    db.driverClass=com.mysql.jdbc.Driver
    • JDBC操作数据库
    public class JDBC_Demo {
        private String userName = null;
        private String password = null;
        private String jdbcUrl = null;
        private String driverClass = null;
    
    
        private ResultSet resultSet =null;
        private PreparedStatement preparedStatement  =null;
        private Connection connection =null;
    
        /**
         * 获取配置文件中的数据库信息
         */
        {
            ClassLoader classLoader2 = this.getClass().getClassLoader();
            InputStream resourceAsStream = classLoader2.getResourceAsStream("jdbc.properties");
            Properties properties = new Properties();
            try {
                properties.load(resourceAsStream);
                userName = properties.getProperty("db.username");
                password = properties.getProperty("db.password");
                jdbcUrl = properties.getProperty("db.jdbcUrl");
                driverClass = properties.getProperty("db.driverClass");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    
        @Test
        public void jdbcDemo () throws ClassNotFoundException {
    
            try {
                //第一步:加载数据库驱动
                Class.forName(driverClass);
                //第二步:通过驱动管理类获取数据库链接
                connection = DriverManager.getConnection(jdbcUrl, userName, password);
                //第三步:定义sql语句 ?表示占位符
                String sql = "select * from items where id = ?";
                //第四步:获取预处理statement
                preparedStatement = connection.prepareStatement(sql);
                //第五步:设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
                preparedStatement.setInt(1, 1);
                //第六步:向数据库发出sql执行查询,查询出结果集
                resultSet = preparedStatement.executeQuery();
                //第七步:遍历查询结果集
                while (resultSet.next()) {
                    System.out.println(resultSet.getInt("id") + "  "
                            + resultSet.getString("name"));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                //第八步:释放资源
                if (resultSet != null) {
                    try {
                        resultSet.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (preparedStatement != null) {
                    try {
                        preparedStatement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    • DriverManager类作用于java程序和JDBC驱动之间,用于检查所加载的驱动程序是否可以建立连接然后通过getConnction()方法根据数据库的URL、用户名和密码,创建一个JDBC Connection 对象

    • Statement对象,Statement类的主要作用用于执行静态的SQL语句并且返回生成结果对象,通过Connection对象的createStatement()方法可以创建一个Statement对象。

    • 调用Statement对象的相关方法执行响应的语句,execuUpdate()更新。

    • 通过Statement的execuQuery()方法进行数据查询,查询结果保存在ResulSet对象中,通过ResulSet对象的next()方法。使指针指向下一行。

    上边使用jdbc的原始方法(未经封装)实现了查询数据库表记录的操作。

    1.1、jdbc编程步骤

    1. 加载数据库驱动

    2. 创建并获取数据库链接

    3. 创建jdbc statement对象

    4. 设置sql语句

    5. 设置sql语句中的参数(使用preparedStatement)

    6. 通过statement执行sql并获取结果

    7. 对sql执行结果进行解析处理

    8. 释放资源(resultSet、preparedstatement、connection)

    1.2、jdbc问题总结如下

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

    二、MyBatis介绍

      MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。

      MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码

      Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

    2.1、Mybatis架构

    1. mybatis配置

      • mybatis-config.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

      • mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。mapper.xml文件需要在mybatis-config.xml中加载。

    2. 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂。

    3. 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

    4. mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

    5. Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

    6. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

    7. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

    2.2、mybatis下载

      mybaits的代码由github.com管理,地址:https://github.com/mybatis/mybatis-3/releases

            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.4</version>
            </dependency>

    2.3、Mybatis数据准备

    CREATE DATABASE `mybatisdb` ;
    USE `mybatisdb`;
    DROP TABLE IF EXISTS `items`;
    
    CREATE TABLE `items` (
      `id` INT(11) NOT NULL AUTO_INCREMENT,
      `name` VARCHAR(32) NOT NULL COMMENT '商品名称',
      `price` FLOAT(10,1) NOT NULL COMMENT '商品定价',
      `detail` TEXT COMMENT '商品描述',
      `createtime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '订单创建时间',
      PRIMARY KEY (`id`)
    ) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    
    INSERT  INTO `items`(`id`,`name`,`price`,`detail`,`createtime`) 
    VALUES (1,'台式机',3000.0,'该电脑质量非常好!!!!','2015-02-03 13:22:53'),
    (2,'笔记本',6000.0,'笔记本性能好,质量好!!!!!','2015-02-09 13:22:57'),
    (3,'背包',200.0,'名牌背包,容量大质量好!!!!','2015-02-06 13:23:02');
    
    DROP TABLE IF EXISTS `orderdetail`;
    
    CREATE TABLE `orderdetail` (
      `id` INT(11) NOT NULL AUTO_INCREMENT,
      `orders_id` INT(11) NOT NULL COMMENT '订单id',
      `items_id` INT(11) NOT NULL COMMENT '商品id',
      `items_num` INT(11) DEFAULT NULL COMMENT '商品购买数量',
      PRIMARY KEY (`id`)
    ) ENGINE=INNODB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
    
    INSERT  INTO `orderdetail`(`id`,`orders_id`,`items_id`,`items_num`) 
    VALUES (1,1,1,1),(2,2,2,2),(3,4,3,4),(4,4,2,3);
    
    DROP TABLE IF EXISTS `orders`;
    
    CREATE TABLE `orders` (
      `id` INT(11) NOT NULL AUTO_INCREMENT,
      `user_id` INT(11) NOT NULL COMMENT '下单用户id',
      `number` VARCHAR(32) NOT NULL COMMENT '订单号',
      `createtime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓璁㈠崟鏃堕棿',
      `note` VARCHAR(100) DEFAULT NULL COMMENT '备注',
      PRIMARY KEY (`id`)
    ) ENGINE=INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
    
    INSERT  INTO `orders`(`id`,`user_id`,`number`,`createtime`,`note`) 
    VALUES (3,1,'1000010','2015-02-04 13:22:35',NULL),
    (4,1,'1000011','2015-02-03 13:22:41',NULL),
    (2,10,'1000012','2015-02-12 16:13:23',NULL);
    
    DROP TABLE IF EXISTS `user`;
    
    CREATE TABLE `user` (
      `id` INT(11) NOT NULL AUTO_INCREMENT,
      `username` VARCHAR(32) NOT NULL COMMENT '用户名称',
      `birthday` DATE DEFAULT NULL COMMENT '生日',
      `sex` CHAR(1) DEFAULT NULL COMMENT '性别',
      `address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
      PRIMARY KEY (`id`)
    ) ENGINE=INNODB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
    
    INSERT  INTO `user`(`id`,`username`,`birthday`,`sex`,`address`)
    VALUES 
    (1,'王五',NULL,'2',NULL),
    (2,'张三','2014-07-10','1','北京市'),
    (3,'张小明',NULL,'1','河南郑州')
     
     

    三、Mybatis入门程序

    实现以下功能:

    • 根据用户id查询一个用户信息

    • 根据用户名称模糊查询用户信息列表

    • 添加用户

    • 更新用户

    • 删除用户

    3.1、创建Maven工程,导入依赖

    <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
          
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.11</version>
            </dependency>
    
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.4</version>
            </dependency>
    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.16</version>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.0</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>

    3.2、创建配置文件

    • 在classpath下创建log4j.properties如下:
    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

      mybatis默认使用log4j作为输出日志信息。

    • 在classpath下创建mybatis-config_01.xml,如下:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 和spring整合后 environments配置将废除-->
        <environments default="development">
            <environment id="development">
                <!-- 使用jdbc事务管理-->
                <transactionManager type="JDBC"/>
                <!-- 数据库连接池-->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql:///mybatisdb?useSSL=false&amp;serverTimezone=UTC"/>
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
    </configuration>

      mybatis-config_01.xml是mybatis核心配置文件,上边文件的配置内容为数据源、事务管理。

      IDEA方法参考:https://www.cnblogs.com/jdy1022/p/13618378.html

    3.3、创建po类

      Po类作为mybatis进行sql映射使用,po类通常与数据库表对应,User.java如下:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class User implements Serializable {
        private String id;
        private String username;// 用户姓名
        private String sex;// 性别
        private Date birthday;// 生日
        private String address;// 地址
        private List<Orders> orders;
    }

    3.4、创建映射配置文件

    • 在classpath下的sqlmap目录下创建sql映射文件Users.xml
    <?xml version="1.0" encoding="utf-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="user">
    
        <!--user表字段-->
        <sql id="sqlColumnsForUserTable">
            id,username,sex,birthday,address
        </sql>
    
    
        <!--结果集-->
        <resultMap type="com.jdy.mybatis2020.bean.User" id="userMap">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
        </resultMap>
    
    
        <!--条件-->
        <sql id="sqlConditions">
            <if test="username != null and '' != username">
                <![CDATA[ AND username = #{username} ]]>
            </if>
            <if test="sex != null and '' != sex">
                <![CDATA[ AND sex  LIKE CONCAT('%','${sex}','%' ) ]]>
            </if>
            <if test="address != null and '' != address">
                <![CDATA[ AND  address = #{address} ]]>
            </if>
            <if test="birthday != null and '' != birthday">
                <![CDATA[ AND birthday > DATE_FORMAT(#{birthday},'%Y-%m-%d') ]]>
            </if>
        </sql>
    
    
        <!-- 根据id获取用户信息 -->
        <select id="findUserById"  resultType="com.jdy.mybatis2020.bean.User">
            select
            <include refid="sqlColumnsForUserTable"/>
            from user where id = #{id};
        </select>
    
    
        <!-- 模糊查询查询用户 -->
        <select id="findUserLikeUsername"  resultType="com.jdy.mybatis2020.bean.User">
            select <include refid="sqlColumnsForUserTable"/>
            from user where username like '%${value}%';
        </select>
    
    
        <!-- 添加用户 -->
        <insert id="insertUser" parameterType="com.jdy.mybatis2020.bean.User">
            <!-- selectKey将主键返回,需要再返回 -->
            <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
                select LAST_INSERT_ID();
            </selectKey>
            insert into user(<include refid="sqlColumnsForUserTable"/>)
            values(#{id},#{username},#{sex},#{birthday},#{address});
        </insert>
    
    
        <!-- 删除用户 -->
        <delete id="deleteUserById" parameterType="int">
            delete from user where id=#{id}
        </delete>
    
    
        <!-- 更新用户 -->
        <update id="updateUser" parameterType="com.jdy.mybatis2020.bean.User">
            update user
            <set>
                <if test="username != null">
                    username = #{username},
                </if>
                <if test="birthday != null">
                    birthday = #{birthday},
                </if>
                <if test="sex != null">
                    sex = #{sex},
                </if>
                <if test="address != null">
                    address = #{address},
                </if>
            </set>
            where id=#{id}
        </update>
    
    </mapper>
    • namespace命名空间,用于隔离sql语句,后面会讲另一层非常重要的作用。

    • parameterType:定义输入到sql中的映射类型,#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql。mybatis通过ognl从输入对象中获取参数值拼接在sql中。

    • resultType:定义结果映射类型。mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。

    3.5、加载映射文件

      mybatis框架需要加载映射文件,把user.xml添加在mybatis-config_01.xml,如下:

        <mappers>
            <mapper resource="sqlmap/user.xml"/>
        </mappers>

    3.6、测试

    • 创建SqlSessionFactory的工具类
    public static SqlSessionFactory  createFactory(String resource){
            try {
                // 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory
                InputStream inputStream = Resources.getResourceAsStream(resource);
                return  new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    • 测试类:Test_00
    public class Test_00 {
    
        public static final String RESOURCE = "mybatis-config/mybatis-config_01.xml";
    
        private SqlSessionFactory sqlSessionFactory;
    
        @Before
        public void createFactory(){
            sqlSessionFactory = SqlSessionFactoryUtil.createFactory(RESOURCE);
        }
        /**
         * 查询数据
         */
        @Test
        public void test_Method00() {
            // 数据库会话实例,一个SqlSession对象代表和数据库的一次会话
            SqlSession sqlSession = null;
            try {
                // 创建数据库会话实例sqlSession
                sqlSession = sqlSessionFactory.openSession();
                // 查询单个记录,根据用户id查询用户信息
                User user = sqlSession.selectOne("user.findUserById", "1");
                // 模糊查询
                List<User> users = sqlSession.selectList("user.findUserLikeUsername", "小");
                // 输出用户信息
                System.out.println(user);
                System.out.println(users);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (sqlSession != null) {
                    sqlSession.close();
                }
            }
        }
    
        /**
         * 添加数据
         */
        @Test
        public void test_Method01() {
            SqlSession sqlSession = null;
            try {
                // 创建数据库会话实例sqlSession
                sqlSession = sqlSessionFactory.openSession();
                // 添加用户信息
                User user = new User();
                user.setUsername("ws");
                user.setAddress("陕西西安");
                user.setSex("1");
                user.setBirthday(new Date());
                sqlSession.insert("user.insertUser", user);
                //提交事务
                sqlSession.commit();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (sqlSession != null) {
                    sqlSession.close();
                }
            }
        }
    
        /**
         * 删除数据
         */
        @Test
        public void test_Method02() {
            // 数据库会话实例
            SqlSession sqlSession = null;
            try {
                // 创建数据库会话实例sqlSession
                sqlSession = sqlSessionFactory.openSession();
                // 删除用户
                sqlSession.delete("user.deleteUserById", "3");
                // 提交事务
                sqlSession.commit();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (sqlSession != null) {
                    sqlSession.close();
                }
            }
        }
    
        /**
         * 修改数据
         */
    
        @Test
        public void test_Method03() {
            // 数据库会话实例
            SqlSession sqlSession = null;
            try {
                // 创建数据库会话实例sqlSession
                sqlSession = sqlSessionFactory.openSession();
                // 添加用户信息
                User user = new User();
                user.setId(29);
                user.setUsername("jdy");
                user.setAddress("sxxn");
                user.setSex("1");
                user.setBirthday(new Date());
                sqlSession.update("user.updateUser", user);
                // 提交事务
                sqlSession.commit();
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (sqlSession != null) {
                    sqlSession.close();
                }
            }
        }
    }

    #{}和${}的区别?

    #{}是预编译处理,$ {}是字符串替换。

    • #{}表示一个占位符号#{}是预编译处理,预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。#{parm}传入的数据都当成一个字符串,会对自动传入的数据加一个双引号

    • ${}表示拼接sql串,是字符串替换,MyBatis在处理时,它会将sql中的{ }替换为变量的值,传入的数据不会加两边加上单引号${param}传递的参数会被当成sql语句中的一部分,比如传递表名,字段名

    3.7、mysql自增主键返回  

      若数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),则可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上

    <insert id="insertUserNew" parameterType="com.jdy.mybatis2020.bean.User" useGeneratedKeys="true" keyProperty="id">
            insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})
    </insert>

      而对于不支持自增型主键的数据库(例如Oracle),Oracle使用序列来模拟自增;每次插入的数据的主键是从序列中拿到的值。可以使用 selectKey 子元素(同时支持mysql):selectKey 元素将会首先运行, id 会被设置, 然后插入语句会被调用

      通过修改sql映射文件,可以将mysql自增主键返回:

    <!-- 添加用户 -->
        <insert id="insertUser" parameterType="com.jdy.mybaties2020.bean.User">
            <!-- selectKey将主键返回,需要再返回 -->
            <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
                select LAST_INSERT_ID()
            </selectKey>
            insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})
        </insert>

      添加selectKey实现将主键返回

      • keyProperty指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性。

      • order:取值BEFORE|AFTER。selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理,执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after。

      • resultType:返回的主键是什么类型。

      • LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。

      Mysql使用 uuid实现主键

    <!--需要增加通过select uuid()得到uuid值-->
    <!--注意这里使用的order是“BEFORE”-->
    <insert  id="insertUser" parameterType="com.jdy.mybaties2020.bean.User">
      <selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id">
            select uuid()
      </selectKey>
    insert into user(id,username,birthday,sex,address) 
             values(#{id},#{username},#{birthday},#{sex},#{address})
    </insert>
    1. 为什么要使用MyBatis?

      • MyBatis是一个半自动化的持久化层框架。

      • 与JDBC相比,JDBC的SQL夹在Java代码块里,耦合度高导致硬编码内伤, 维护不易且实际开发需求中sql是有变化,频繁修改的情况多见。

      • 与Hibernate和JPA相比,Hibernate和JPA 操作长难复杂SQL,对于而言处理也不容易,Hibernate内部自动生产的SQL,不容易做特殊优化,JPA基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难,导致数据库性能下降。

      • 对开发人员而言,核心sql还是需要自己优化,MyBatis 将sql和java 编码分开,功能边界清晰,一个专注业务、一个专注数据 。

    2. Mybatis与hibernate不同?

      • Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。

      • Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

      • Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。

      • 总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。 

  • 相关阅读:
    【洛谷P1005】矩阵取数游戏
    【洛谷P1966】火柴排队
    【题解】洛谷P1731 [NOI1999] 生日蛋糕(搜索+剪枝)
    【题解】洛谷P3627 [APIO2009]抢掠计划(缩点+SPFA)
    【题解】洛谷P1262 间谍网络 (强连通分量缩点)
    【题解】洛谷P3200 [HNOI2009] 有趣的数列(卡特兰数+质因数分解)
    点双连通分量 [HNOI2012]矿场搭建
    分块 公主的朋友
    [置顶] 数学的坑,一点点来填
    大暴搜 [NOIP2009]靶形数独
  • 原文地址:https://www.cnblogs.com/jdy1022/p/13703848.html
Copyright © 2020-2023  润新知