zoukankan      html  css  js  c++  java
  • Mybatis1

    一.MyBatis介绍

    本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

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

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

    二.环境搭建

    1. 导包
    2. 创建配置文件:SqlMapConfig.xml与日志文件log4j,properties

      在config下创建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

      在config下创建SqlMapConfig.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://localhost:3306/mybatis?characterEncoding=utf-8" />
                      <property name="username" value="root" />
                      <property name="password" value="root" />
                  </dataSource>
              </environment>
          </environments>
      </configuration>
    3. 创建pojo(普通JavaBeans)

      pojo类作为mybatis进行sql映射使用,po类通常与数据库表对应,

      User.java如下:

      Public class User {

         private int id;

         private String username;// 用户姓名

         private String sex;// 性别

         private Date birthday;// 生日

         private String address;// 地址

      get/set……}

    4. sql映射文件
      sqlmap下创建User.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">
      <!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
      <mapper namespace="test">
      </mapper>
    5. 在配置文件sqlmapconfig中加载映射:
    6. 添加sql语句:(以查找为例)

      SELECT * FROM `user` WHERE id = 1
      编辑User.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">
      <!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
      <mapper namespace="test">
      
          <!-- id:statement的id 或者叫做sql的id-->
          <!-- parameterType:声明输入参数的类型 -->
          <!-- 
         resultType:自动映射(属性须与jopo 一 一 对 应)声明输出结果的类型,应该填写pojo的全路径
      若无对应!!则需要resultMap将要映射的属性联系起来
          -->
          <!-- #{}:输入参数的占位符,相当于jdbc的? -->
          <select id="queryUserById" parameterType="int"
              resultType="cn.itcast.mybatis.pojo.User">
              SELECT * FROM `user` WHERE id  = #{id}
          </select>
      
      </mapper>

      在User.xml配置文件中添加如下内容:

      
      

          <!-- 如果传入的参数是简单数据类型,${}里面必须写value -->

          <select id="queryUserByUsername2" parameterType="string"

             resultType="cn.itcast.mybatis.pojo.User">

             SELECT * FROM `user` WHERE username LIKE '%${value}%'

          </select>

    <!-- 如果返回多个结果,mybatis会自动把返回的结果放在list容器中 -->
        <!-- resultType的配置和返回一个结果的配置一样 -->
        <select id="queryUserByUsername1" parameterType="string"
            resultType="cn.itcast.mybatis.pojo.User">
            SELECT * FROM `user` WHERE username LIKE #{username}
        </select>
    <!-- 保存用户 -->
        <insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
            INSERT INTO `user` 
            (username,birthday,sex,address) VALUES
            (#{username},#{birthday},#{sex},#{address})
        </insert>
    <!-- 更新用户 -->
    <update id="updateUserById" parameterType="cn.itcast.mybatis.pojo.User">
        UPDATE `user` SET
        username = #{username} WHERE id = #{id}
    </update>
    <!-- 删除用户 -->
        <delete id="deleteUserById" parameterType="int">
            delete from user where
            id=#{id}
        </delete>

     三.测试
        流程              查找为读,不需要提交,仅仅需要释放资源

     1. 创建SqlSessionFactoryBuilder对象

     2. 加载SqlMapConfig.xml配置文件

     3. 创建SqlSessionFactory对象

     4. 创建SqlSession对象

     5. 执行SqlSession对象执行查询,获取结果User

     6. 打印结果

     7. 释放资源

    public class MybatisTest {
        private SqlSessionFactory sqlSessionFactory = null;
    
        @Before
        public void init() throws Exception {
            // 1. 创建SqlSessionFactoryBuilder对象
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    
            // 2. 加载SqlMapConfig.xml配置文件
            InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    
            // 3. 创建SqlSessionFactory对象
            this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        }
    
        @Test
        public void testQueryUserById() throws Exception {
            // 4. 创建SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            // 5. 执行SqlSession对象执行查询,获取结果User
            // 第一个参数是User.xml的statement的id,第二个参数是执行sql需要的参数;
            Object user = sqlSession.selectOne("queryUserById", 1);
    
            // 6. 打印结果
            System.out.println(user);
    
            // 7. 释放资源
            sqlSession.close();
        }
    }

    四.添加操作与自增主键返回  *

    查询id的sql

    SELECT LAST_INSERT_ID()

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

    如下添加selectKey 标签

    <!-- 保存用户 -->
    <insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
        <!-- selectKey 标签实现主键返回 -->
        <!-- keyColumn:主键对应的表中的哪一列 -->
        <!-- keyProperty:主键对应的pojo中的哪一个属性 -->
        <!-- order:设置在执行insert语句前执行查询id的sql,还是在执行insert语句之后执行查询id的sql -->
        <!-- resultType:设置返回的id的类型 -->
        <selectKey keyColumn="id" keyProperty="id" order="AFTER"
            resultType="int">
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT INTO `user`
        (username,birthday,sex,address) VALUES
        (#{username},#{birthday},#{sex},#{address})
    </insert>

    其中

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

    -------------------------------------------------------------------------------------------------------------------------------------------

    1.1. 小结

    1.1.1. #{}和${}

    #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

    ${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。

     

    1.1.2. parameterType和resultType

    parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

    resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中

    1.1.3. selectOne和selectList

    selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:

    org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3

       at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)

    selectList可以查询一条或多条记录。

      Mybatis解决jdbc编程的问题

    1、  数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。

    解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。

    2、  Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

    解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

    3、  向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

    解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。

    4、  对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

    解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

      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需要具有很强的经验和能力才行。

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

     

     

  • 相关阅读:
    linux软件安装方式
    docker 安装 jenkins touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
    [ERR] Node goodsleep.vip:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    Linux 常用命令 服务器间scp 用户 export 创建文件、软连接
    redis 安装 集群 主从 哨兵 docker
    WPF密码框中禁止复制、粘贴
    Application 统计在线人数
    【转义字符】HTML 字符实体&lt; &gt: &amp;等
    SQL语句统计每天的数据
    正则表达式计算代码数
  • 原文地址:https://www.cnblogs.com/lvoooop/p/10846946.html
Copyright © 2011-2022 走看看