zoukankan      html  css  js  c++  java
  • mybatis3.2.7 原理和入门程序

    使用jdbc操作数据库有以下缺点    

      |--数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁开启和关闭,造成数据源资源浪费,影响数据库性能。        

        设想:使用数据库连接池管理数据库连接。    

      |--将sql语句硬编码到Java代码中,如果sql语句修改,需要重新编译Java源码,不利于系统维护。        

        设想:将sql语句配置在xml文件中,即使sql变化,不需要对Java代码进行重新编译    

      |--向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码,不利于系统维护。        

        设想:将sql语句和占位符号和参数 全部配置在xml文件中    

      |--从resultSet中遍历结果集resultSet时,存在硬编码,将获取表的字段进行硬编码,不利于系统维护。        

        设想:将查询的结果集,自动映射成Java对象。

    1.mybaits是什么?    

      1.1 mybatis是一个持久层框架,是Apache下的顶级框架。后来托管到googlecode下面,再后来托管到github下。    

      1.2 mybatis让程序员主要把精力放在sql上,通过mybaits提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql) 满足需求的sql语句。    

      1.3 mybatis可以将向preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象(输出映射)。

    2.mybaits原理    

      2.1 SqlMapConfig.xml(是mybatis的全局配置文件,名称是不固定的)         

        配置了数据源、事务等mybaits环境         

        配置映射文件(配置sql语句)  mapper.xml  mapper.xml ....    

      2.2 SqlSessionFactory(会话工厂),根据配置文件创建工厂         

        作用:创建SqlSession    

      2.3 SqlSession(会话):是一个接口,面向用户(程序员)的接口         

        作用:操作数据库(发出sql 增、删、改、查)    

      2.4 Executor(执行器):是一个接口(基本执行器、缓存执行器)         

        作用:SqlSession通过执行器操作数据库    

      2.5 mapper statement(底层封装对象)         

        作用:对操作数据库进行存储封装,包括sql语句、输入参数、输出结果类型。           

          --输入参数类型: Java简单类型、hashmap、pojo自定义           

          --输出结果类型:  java简单类型、hashmap、pojo自定义    

      2.6 数据库

    3. mybaits的jar包 3.2.7版本  

       https://github.com/mybatis/mybatis-3/releases

         lib下: 依赖包  log4j日志包   cglib.jar(动态代理的jar包)   

       mybaits-3.2.7.jar : 核心包   

             数据库驱动包

    示例代码

    1. sql-map-config.xml

    <configuration>    

      <!--和Spring整合以后,environments配置将废除-->

      <environments default="development">   

        <environment id="development">    

          <!--使用jdbc事物管理,事务由mybatis控制-->    

          <transactionManager type="JDBC">

            <!--数据库连接池,由mybatis控制-->    

          <dataSource type="POOLED">     

            <property name="driver" value="com.mysql.jdbc.Driver"/>     

            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8"/>

            <property name="username" value="root"/>

            <property name="password" value="root"/>

              </dataSource>

        </environment>

      <environments>

       <!--加载配置文件mapper.xml-->  

      <mappers>     

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

        <mapper resource="sqlmap/user-mapping.xml"/>

      </mappers>

    </configuration>

     

    2. user-mapping.xml

      namespace命名空间,作用就是对sql进行分类管理,理解sql隔离

      注意:使用mapper代理方法开发,namespace有着特殊重要的作用   

    <mapper namespace="test">    

      <!--  在映射文件中配置很多的sql语句  

        需求:通过id查询用户表的记录  通过select语句执行数据库查询

            id:标识映射文件中的sql  将sql语句封装到mapperStatement中去,所以将id称为statement的id  

            parameterType;指定输入参数的类型,这里指定int类型  

          #{}表示一个占位符号  

          #{id}:其中的id表示接收输入的参数,参数名称就是id,如果输入参数是简单数据类型,参数名称可以任意命名,比如value或者其他名称。    

          resultType:指定sql输出结果的所映射的Java对象类型,select指定resultMap表示将单条记录映射成java对象。  -->

      <select id="findUserById" parameterType="int" resultType="cn.itcast.po.User">   

          select * from user where id = #{id}  

      </select>

       <!--  需求:根据用户名称迷糊查询用户信息,可能返回多条  

          resultType:指定就是单条记录所映射的java对象类型  

          ${}: 表示拼接sql串,将接收到参数的内容不添加任何修饰,拼接在sql中   ==>${}拼接sql,就会引起一个问题,sql注入  

          ${value}:接收输入参数的类型,如果传入类型是简单类型,${}中只能使用value.  -->  

      <select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.po.User">   

          select * from user where name like '%${value}%'  

      </select>

       <!--  添加用户,返回插入数据的主键值(MySQL/Oracle)

          parameterType:指定输入参数pojo数据类型(包括用户信息)  

          #{}: 指定pojo的属性名,接收到pojo的对象的属性值。mybatis通过OGNL获取对象的属性值  -->  

          <insert id="insertUser" parameterType="cn.itcast.po.User"> 

            <!--1. MySQL 自增主键返回 --> 

            <!--将插入数据的主键返回,返回到User对象中      

              Select LAST_INSERT_ID():得到刚刚insert进去记录的值,只适用于mysql自增主键

              keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性      

              order: Select LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序      

              resultType:指定Select LAST_INSERT_ID()的结果类型   -->   

            <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">    

                Select LAST_INSERT_ID();   

            </selectKey>   

            insert into user(name, age, sex, birthday)

                  values(#{name}, #{age}, #{sex}, #{birthday})

               <!--2. MySQL 非自增主键返回:使用mysql的uuid()生成主键

            执行过程:首先通过uuid()得到主键,将主键设置到user对象的id属性中         

                 其次在insert执行之前,从user对象中取出id的属性值   -->   

            <!--   <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">    

                  Select UUID();   

               </selectKey>   

                 insert into user(id, name, age, sex, birthday)

                     values(#{id}, #{name}, #{age}, #{sex}, #{birthday})   -->

             <!--3. ORACLE 主键返回:通过oracle的序列生成主键      

             执行过程:首先通过 序列名.nextVal 得到主键,将主键设置到user对象的id属性中         

                  其次在insert执行之前,从user对象中取出id的属性值   -->   

           <!--   <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">    

                  Select 序列名.nextval;   

              </selectKey>   

              insert into user(id, name, age, sex, birthday)

                      values(#{id}, #{name}, #{age}, #{sex}, #{birthday})   -->  

               </insert>

       <!--  根据id删除用户  -->  

      <delete id="deleteUserById" parameterType="java.lang.Integer">   

        delete from user where id = #{id}

      </delete>

       <!--  根据id更新用户  分析:需要传入用户的id       

          需要传入用户的更新信息  

          parameterType: 指定user对象,包括id和更新信息,注意:id 必须存在  

          #{id} : 从输入user对象中获取id属性值  -->  

      <update id="updateUserById" parameterType="cn.itcast.po.User">   

          update user   

          set name = #{name}, age = #{age}, sex = #{sex}, birthday = #{birthday}   

          where id = #{id}  

      </update>

    </mapper>

    3. 测试代码

      1 public void findUserByIdTest(){
      2     //mybatis配置文件
      3     String resource = "sqlMapConfig.xml";
      4 
      5     //得到配置文件流
      6     InputStream inputStream = Resources.getResourceAsStream(resource);
      7 
      8     //创建会话工厂,传入mybatis的配置文件信息
      9     SqlSessionFactory  sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
     10     
     11     //通过工厂得到sqlSession
     12     SqlSession sqlSession = sqlSessionFactory.openSession();
     13 
     14     //通过sqlSession操作数据库
     15     //第一个参数:映射文件中statement的id,命名规则: namespace + "." + statement的id
     16     //第二个参数:指定和映射文件中所匹配的parameterType类型的参数
     17     //sqlSession.selectOne结果是与映射文件中匹配的resultType类型的对象
     18     User user = sqlSession.selectOne("test.findUserById", 1);
     19    
     20     System.out.println(user);
     21 
     22     //释放资源
     23     sqlSession.close();
     24    }
     25 
     26 
     27    public void findUserByNameTest(){
     28     //mybatis配置文件
     29     String resource = "sqlMapConfig.xml";
     30 
     31     //得到配置文件流
     32     InputStream inputStream = Resources.getResourceAsStream(resource);
     33 
     34     //创建会话工厂,传入mybatis的配置文件信息
     35     SqlSessionFactory  sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
     36     
     37     //通过工厂得到sqlSession
     38     SqlSession sqlSession = sqlSessionFactory.openSession();
     39 
     40     //通过sqlSession操作数据库
     41     //list中的User和映射文件中resulType所指定的类型一致
     42     List<User> users = sqlSession.selectList("test.findUserByName", "小明");
     43    
     44     System.out.println(users);
     45 
     46     //释放资源
     47     sqlSession.close();
     48    }
     49 
     50 
     51    public void insertUserTest(){
     52     //mybatis配置文件
     53     String resource = "sqlMapConfig.xml";
     54 
     55     //得到配置文件流
     56     InputStream inputStream = Resources.getResourceAsStream(resource);
     57 
     58     //创建会话工厂,传入mybatis的配置文件信息
     59     SqlSessionFactory  sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
     60     
     61     //通过工厂得到sqlSession
     62     SqlSession sqlSession = sqlSessionFactory.openSession();
     63 
     64     //插入用户对象
     65     User user = new User();
     66     user.setName("小明");
     67     user.setAge(24);
     68     user.setSex("女");
     69     user.setBirthday(new Date());
     70     
     71     sqlSession.insert("test.insertUser", user);
     72    
     73     //提交事务
     74     sqlSession.commit();
     75 
     76     //获取用户信息主键
     77     System.out.println(user.getID());
     78 
     79     //释放资源
     80     sqlSession.close();
     81    }
     82 
     83    public void deleteUserTest(){
     84     //mybatis配置文件
     85     String resource = "sqlMapConfig.xml";
     86 
     87     //得到配置文件流
     88     InputStream inputStream = Resources.getResourceAsStream(resource);
     89 
     90     //创建会话工厂,传入mybatis的配置文件信息
     91     SqlSessionFactory  sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
     92     
     93     //通过工厂得到sqlSession
     94     SqlSession sqlSession = sqlSessionFactory.openSession();
     95 
     96     //根据用户id删除用户    
     97     sqlSession.delete("test.deleteUserById", 4);
     98    
     99     //提交事务
    100     sqlSession.commit();
    101 
    102     //释放资源
    103     sqlSession.close();
    104    }
    105 
    106 
    107    public void updateUserTest(){
    108     //mybatis配置文件
    109     String resource = "sqlMapConfig.xml";
    110 
    111     //得到配置文件流
    112     InputStream inputStream = Resources.getResourceAsStream(resource);
    113 
    114     //创建会话工厂,传入mybatis的配置文件信息
    115     SqlSessionFactory  sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
    116     
    117     //通过工厂得到sqlSession
    118     SqlSession sqlSession = sqlSessionFactory.openSession();
    119     
    120     User user = new User();
    121     user.setId(21);
    122     user.setName("小明");
    123     user.setAge(24);
    124     user.setSex("女");
    125     user.setBirthday(new Date());
    126 
    127 
    128     //根据用户id更新用户信息    
    129     sqlSession.update("test.updateUserById", user);
    130    
    131     //提交事务
    132     sqlSession.commit();
    133 
    134     //释放资源
    135     sqlSession.close();
    136    }
    View Code

    4.  总结

       4.1 parameterType: 在映射文件中通过parameterType指定输入参数的类型。

       4.2 resultType: 在映射文件中通过parameterType指定输入结果的类型。  

       4.3 #{}: 表示一个占位符号    #{}接收输入参数,类型可以是简单类型、pojo、hashmap  

           如果是简单类型,#{}可以写成value或者其他名称   

          #{}如果接收pojo对象值,通过OGNL读取对象的属性值,通过属性.属性.属性...方式获取对象属性值。

       4.4 ${}: 表示一个拼接符号,会引起sql注入问题,不建议使用   

          ${}接收输入参数,类型可以是简单类型、pojo、hashmap   

            如果是简单类型,${}只可以写成value   

            ${}如果接收pojo对象值,通过OGNL读取对象的属性值,通过属性.属性.属性...方式获取对象属性值。

       4.5 selectOne:表示查询出一条记录进行映射。如果使用selectList也可以实现(list中只有一条记录)  

       4.6 selectList:表示查询出一个列表(多条记录)进行映射。  

       4.7 添加用户主键返回MySQL 、Oracle

     1 --MySQL 主键自增,执行insert提交之后自动生成一个自增主键。
     2 --通过mysql的函数获取到刚刚插入记录的自增主键。
     3 LAST_INSERT_ID();是insert之后调用此函数。
     4 <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
     5     Select LAST_INSERT_ID();
     6 </selectKey>
     7 insert into user(name, age, sex, birthday) 
     8 values(#{name}, #{age}, #{sex}, #{birthday})
     9 
    10 --MySQL 非自增主键返回(使用uuid())
    11 --通过mysql的UUID()查询到主键,修改表中的id字段类型为String,长度设置为35位。
    12 --执行思路:先通过uuid()查询到主键,将主键输入到sql语句中。
    13 --执行uuid()语句顺序,是相对于insert语句之前执行。
    14 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
    15         Select UUID();
    16 </selectKey>
    17 insert into user(id, name, age, sex, birthday) 
    18 values(#{id}, #{name}, #{age}, #{sex}, #{birthday})
    19         
    20 --oracle主键返回: 通过oracle的序列生成主键
    21 --执行思路: 先通过 序列名.nextval 得到主键,将主键输入到sql语句中。
    22 --执行 序列名.nextval 语句顺序,是相对于insert语句之前执行。
    23 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
    24           Select 序列名.nextval;
    25 </selectKey>
    26 insert into user(id, name, age, sex, birthday) 
    27 values(#{id}, #{name}, #{age}, #{sex}, #{birthday})    
    View Code

    5. mybatis和Hibernate的本质区别和应用场景      

        Hibernate:是一个标准的ORM框架(对象关系映射),入门门槛较高,不需要程序员写sql,sql语句自动生成了。                  

              对sql语句进行优化和修改比较困难。      

          应用场景:适用于需求变化不多的中小型项目,比如:后台管理系统、erp、oa、orm。

            Mybatis:专注于sql本身,需要程序员自己写sql语句,sql修改和优化比较方便。                 

            Mybatis是一个不完全的ORM框架,虽然程序员自己写sql,但是可以实现映射(输入映射、输出映射)     

         应用场景:适用于需求变化较多的项目,比如:互联网项目。

      

     

  • 相关阅读:
    .Net数据集导出到Excel样式细节---------------摘自别人的
    导出word excel 方法
    constructor
    计算程序运行时间(.net1.1 于.net2.0的区别)在.net2.0中提供了Stopwatch类,简单例子
    委托 事件 observer
    easyui及读取xml
    MVC4.0 上传文件
    Asp.net MVC验证那些事(1)-- 介绍和验证规则使用----[转]--[并修改了部分内容]
    Educational Codeforces Round 54 (Rated for Div. 2) C. Meme Problem
    素数表的获取,埃氏筛法 介绍(复杂度 : O(n*loglogn) )
  • 原文地址:https://www.cnblogs.com/qianbing/p/6972859.html
Copyright © 2011-2022 走看看