• myBatis:基础介绍一


    关于myBatis以前一点都没有了解,但是好多招聘上面都是要求mybatis.现在开始基础学习下:

     MyBatis的前身叫iBatis,本是apache的一个开源项目, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录。

    1)MyBATIS 目前提供了三种语言实现的版本,包括:Java、.NET以及Ruby。(我主要学习java,就讲java的使用)

    2)它提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。

    3)mybatis与hibernate的对比?

       mybatis提供一种“半自动化”的ORM实现。
       这里的“半自动化”,是相对Hibernate等提供了全面的数据库封装机制的“全自动化”ORM实现而言,“全自动”ORM实现了POJO和数据库表之间的映射,以及 SQL 的自动生成和执行。

        而mybatis的着力点,则在于POJO与SQL之间的映射关系。

    一:mybatis的project

    我们先建立一个Mybatis的project,项目具体如下:

    首先要导入两个包:一个是mybatis的jar包,一个是mysql的驱动包

    mybatis需要jar包:mybatis-3.3.0.jar

    mysql驱动jar包:mysql-connector-java-5.1.15.-bin.jar

    同样的我们要创建数据库:

     

    这个是我们整体的项目工程:

    二:XML配置

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

    1:添加mybatis配置文件mybatis.cfg.xml

    Mybatis的全局配置文件,主要用于配置Mybatis的运行环境(事务管理器、数据源等)。具体详情可见Mybatis说明文档

    下面通过一个简单的示例,来简要说明这个配置文件。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
     3 <configuration>
     4     <environments default="development">
     5         <environment id="development">
     6             <transactionManager type="JDBC">
     7             </transactionManager>
     8             <!-- 数据库连接配置信息 -->
     9             <dataSource type="POOLED">
    10                 <property name="driver" value="com.mysql.jdbc.Driver"/>
    11                 <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
    12                 <property name="username" value="root"/>
    13                 <property name="password" value="root"/>            
    14             </dataSource>        
    15         </environment>    
    16     </environments>
    17     
    18     <!-- 注册userMapper.xml文件 -->
    19     <mappers>
    20         <mapper resource = "mapper/userMapper.xml"/>    
    21     </mappers>
    22 </configuration>

    头文件(1~2行):第1行是xml声明,声明该xml文件的字符集为UTF-8;第2行是DTD文件类型声明(外部DTD),用于约束该xml文件的结构。引用的DTD约束的格式为<!DOCTYPE 根元素 SYSTEM "DTD文件路径">(本地文件),或<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文件URL">(公共文件),这里是约束configuaration元素的结构为链接中的DTD文件所约束的那样

     environments元素(4~16行):用于配置要创建的SqlSessionFactory实例的环境。每个数据库对应一个SqlSessionFactory实例,每个SqlSessionFactory实例只能选择一种环境(environments元素中可以定义多个environment元素)。

    • 第4行:默认的环境id。
    • 第5行:定义一个environment元素,并设定环境id。
    • 第6行:事务管理器的配置,可选"JDBC"或"MANAGED"。【注:Spring+Mybatis不需要配置事务管理器,因为Spring会用自带管理器覆盖这些配置】
        • "JDBC":直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
        • "MANAGED":不提交或回滚一个连接,而是让容器来管理事务的整个生命周期,默认情况下它会关闭连接
    • 第9~14行:数据源的配置。第12行是配置数据源类型,内置了"UNPOOLED","POOLED"和"JNDI";第13~18行是设定数据源。
      • "UNPOOLED":不使用数据库连接池。只有driver,url,username,password,defaultTransactionIsolationLevel五个属性,其中最后一个属性是指默认的连接事务隔离级别。
      • "POOLED":使用数据库连接池。除了"UNPOOLED"中的5个属性之外,还多了一些连接池属性,比如poolMaximumActiveConnections(最大活动连接数)、poolMaximumIdleConnections(最大空闲连接数)等(详见说明文档)。
      • "JNDI":为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。只需"initial_context"和"data_source"两个属性。
      • 另外,也可以将type设置为一个数据源类,使用任何第三方数据源。

    mappers元素(19~21行):用于设定映射文件路径。可以通过classpath相对路径、文件系统绝对路径设定映射文件,还可以通过类名、包名设定映射接口

    2.userMapper.xml

    sql映射文件,主要用于实现数据库操作的具体细节。此文件需要在MybatisConfig.xml中加载。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     3 
     4 <!-- 为这个mapper指定一个唯一的namespace,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证包名是惟一的 -->
     5 <mapper namespace="mapper.userMapper">
     6 
     7     <!-- 在select标签中编写查询的sql语句,设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果类型。
     8       --> 
     9     <!-- 对于查询单条记录,必须保证查询出来的记录只有一个,如果有多个mybatis是会报错的,而不是就取多条记录中的第一个。 -->   
    10     <select id="getUser" parameterType="String" resultType="beans.User">
    11         select * from users where username=#{id}    
    12     </select>
    13     
    14     <insert id="insertUser" parameterType="beans.User">
    15         insert into users(username, password) value(#{username},#{password})
    16     </insert>
    17     
    18     <update id="update" parameterType="beans.User">
    19         update users set username=#{username}, password=#{password} where id=#{id}            
    20     </update>
    21     
    22     <delete id="delete" parameterType="int">
    23         delete from users where id=#{id}
    24     </delete>
    25     
    26     <!--id为该条SQL的名称,在该Mapper下不能重复
    27     resultType里填写集合泛型,不论返回值是List还是单个类型,都填写泛型或者单个类型即可,
    28     mybatis会自动猜测返回值是一个类型还是集合-->
    29     <select id="selectAllUsers" resultType="beans.User">
    30         select * from users
    31     </select>
    32 
    33 </mapper>
    1. 头文件(1~2行):同上,这里是约束mapper元素的结构为链接中的DTD文件所约束的那样。
    2. 命名空间(5行):最基本的意义,是给这个mapper命名用于区分;更为高级的用法,则是接口绑定(面向接口编程)。namespace的命名方式分为两种:完全限定名和短名称。本例中使用的就是完全限定名。使用短名称时,必须确保这个短名称在系统中是唯一的,否则只能使用完全限定名。
      • 接口绑定:将namespace设为DAO接口,将接口中的方法都通过mapper中的元素实现(元素id与接口方法一一对应),就可以不用写DAO实现类,Mybatis会通过绑定自动找到要执行的sql语句。

    mapper顶级元素(4~61行):mapper中有8个顶级元素,分别是insert,delete,update,select(映射增删改查语句),sql(重用sql语句块),resultMap(描述如何从结果集中加载对象),cache(缓存配置),cache-ref(其他namespace缓存配置)。

    insert、delete、update(5~23行):基本格式就是<元素名 元素属性>sql语句</元素名>。其中,元素名即为insert/delete/update中的一个,可设定的元素属性有9个,这里只列出5个,一般设定1,2即可。在sql语句中,用#{}表示占位符,执行时将#{}替换为?,然后将括号内的参数传递给?。

    1. id:元素标识。
    2. parameterType:接受的参数类型,可为完全限定名或别名。默认为unset。传入多个参数时,这个属性应忽略,在#{}中直接以各参数名表示。(如:18~23行)
    3. .......

    下面看Java的操作:

    数据库操作在代码中的实现步骤大体如下:

    1. 创建IO流,通过Resources类中的getResourceAsStream方法载入全局配置文件(mybatis.cfg.xml)。
    2. 由SqlSessionFactoryBuilder对象的build方法,创建SqlSessionFactory对象。
    3. 由SqlSessionFactory对象的openSession方法,创建SqlSession对象。
    4. 由SqlSession对象,操作数据库。
    5. 关闭SqlSession对象,然后关闭IO流.

    下面主要讲解一下通过SqlSession对象操作数据库的内容。

    1.SqlSession类中的常用方法

    目前主要用到过的方法有:

      1. insert,delete,update:对数据库进行增/删/改操作。注意:进行了这些操作之后,必须调用commit()提交事务,否则数据库记录不会改变。
        返回值:int,操作所影响的行数。
        参数:("sqlID",param):
        1. sqlID:StudentMapper.xml中对应的sql元素的id,若有多个mapper,可以通过mapper.sqlID的形式指定。
        2. param:若对应的接口函数只需要传入一个参数,直接将这个参数传入即可。【最好用变量的形式传入。直接传常量可能会导致类型转换异常】
          若需传入多个参数,则应该用HashMap<String,Object>传入参数。其中,String是mapper.xml中的参数名(#{xx}),Object是参数值。将多个参数放入map后,将map作为参数传入即可。
      2. commit():刷新批处理语句并提交数据库连接。在增删改之后必须调用。
      3. selectOne("sqlID",param):参数意义同上。返回值:mapper.xml中规定的返回值类型。
      4. selectList("sqlID",param):同上。返回值:List<E>,其中E为mapper.xml中规定的返回值类型。
      5. close():关闭会话,释放资源。
    1. POJO类中的构造方法的参数类型,如果是基本数据类型,应该写成其包装类的形式(比如int写为Integer)。因为mapper.xml中的javaType会自动转为完全限定名(比如int转为java.lang.Integer)。如果在resultMap中定义了constructor元素,映射到POJO类时会是完全限定名的类型,如果构造方法中的参数类型不是包装类,就会报错(找不到参数类型为xxx的构造函数)。
    2. 务必在insert/delete/update之后执行commit!否则一切操作都不会在数据库中生效!

    下面看一下Java类文件:

    POJO类:

     1 package beans;
     2 
     3 public class User {
     4     
     5     private int id;
     6     
     7     private String username;
     8     private String password;
     9     
    10     
    11     /**
    12      * @return the id
    13      */
    14     public int getId() {
    15         return id;
    16     }
    17     /**
    18      * @param id the id to set
    19      */
    20     public void setId(int id) {
    21         this.id = id;
    22     }
    23     /**
    24      * @return the username
    25      */
    26     public String getUsername() {
    27         return username;
    28     }
    29     /**
    30      * @param username the username to set
    31      */
    32     public void setUsername(String username) {
    33         this.username = username;
    34     }
    35     /**
    36      * @return the password
    37      */
    38     public String getPassword() {
    39         return password;
    40     }
    41     /**
    42      * @param password the password to set
    43      */
    44     public void setPassword(String password) {
    45         this.password = password;
    46     }
    47     
    48     /* (non-Javadoc)
    49      * @see java.lang.Object#toString()
    50      */
    51     @Override
    52     public String toString() {
    53         return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
    54     }    
    55     
    56 }

    MybatisUtil工具类:

     1 package utils;
     2 
     3 import java.io.IOException;
     4 import java.io.Reader;
     5 
     6 import org.apache.ibatis.io.Resources;
     7 import org.apache.ibatis.session.SqlSession;
     8 import org.apache.ibatis.session.SqlSessionFactory;
     9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    10 
    11 public class MybatisUtil {
    12     
    13     private static SqlSessionFactory sqlSessionFactory = null;
    14     
    15     static{
    16         try {
    17             Reader read = Resources.getResourceAsReader("mybatis.cfg.xml");
    18             sqlSessionFactory = new SqlSessionFactoryBuilder().build(read);
    19         } catch (IOException e) {
    20             e.printStackTrace();
    21         }        
    22     }
    23     
    24     public static SqlSession getSession(){                
    25         return sqlSessionFactory.openSession(true);        
    26     }
    27 }

    测试类:

     1 package test;
     2 
     3 import java.io.IOException;
     4 
     5 import org.apache.ibatis.session.SqlSession;
     6 
     7 import beans.User;
     8 import utils.MybatisUtil;
     9 
    10 public class Test {
    11 
    12     public static void main(String[] args) throws IOException {
    13         
    14         //mybatis的配置文件
    15         //String resource = "mybatis.cfg.xml";
    16         
    17         //使用类加载器加载mybatis配置文件,它也加载关联的映射文件
    18         //InputStream is = Test.class.getClassLoader().getResourceAsStream(resource);
    19         
    20         //构建sqlSession的工厂
    21         //SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
    22         
    23         //使用mybatis提供的Resource类加载mybatis的配置文件(它也加载关联的映射文件)
    24         //Reader read = Resources.getResourceAsReader(resource);
    25         
    26         //构建sqlSession工厂
    27         //SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(read);
    28         //创建能执行映射文件中的sql的sqlSession        
    29         //SqlSession sqlSession = sqlSessionFactory.openSession();    
    30         SqlSession sqlSession = MybatisUtil.getSession();
    31         
    32         //映射sql的标识字符串,mapper.userMapper是userMapper.xml文件中mapper标签的namespace属性值
    33         //getUser是select标签的id属性值,通过select标签的id属性值就可以找到要执行的sql
    34         String statament = "mapper.userMapper.getUser";   //映射sql的标识字符串
    35         //执行查询返回一个唯一的user对象的sql
    36         User user = sqlSession.selectOne(statament, "zxl");
    37         
    38         System.out.println(user);
    39     }
    40 
    41 }

    看上面的例子可以看出,获取SqlSessionFactory一共有两种方式:

    通过myBatis提供的Resources.getResourceAsReader(resource), 然后通过New SqlSessionFactoryBuilder().build()来创建SqlSessionFactory.

    通过使用类加载器加载mybatis配置文件,它也加载关联的映射文件Test.class.getClassLoader().getResourceAsStream(resource);

    上面的查询结果:根据“mapper.userMapper.getUser”找到sql语句:“select * from users where username=#{id}”, 然后将参数传递进去。

    一个复杂些的CRUD:

     1 package test;
     2 
     3 import java.util.HashMap;
     4 import java.util.List;
     5 
     6 import org.apache.ibatis.session.SqlSession;
     7 
     8 import beans.User;
     9 import utils.MybatisUtil;
    10 
    11 public class TestCRUD {
    12 
    13     public static void main(String[] args) {
    14         
    15         //查找一个用户
    16         SqlSession sqlSession = MybatisUtil.getSession();
    17         String statament = "mapper.userMapper.getUserbyMore";
    18         
    19         HashMap<String, Object> paras = new HashMap<String, Object>();
    20         paras.put("username", "zxl");
    21         paras.put("password", "12345");
    22         
    23         User user = new User();
    24         user = sqlSession.selectOne(statament, paras); //通过多个参数去查找,传入参数应该是HashMap,key是数据表中列参数
    25         System.out.println("查询结果:"+ user);
    26         
    27         //更新用户
    28         statament = "mapper.userMapper.update";
    29         User userupdate = new User(); 
    30         userupdate.setId(2);
    31         userupdate.setUsername("zxllll");
    32         userupdate.setPassword("345");        
    33         int result = sqlSession.update(statament, userupdate);
    34         System.out.println("update result: " + result);
    35         
    36         //添加一个用户,前面有删去用户,添加的主键会不连续。
    37         statament = "mapper.userMapper.insertUser";
    38         User useradd = new User();
    39         useradd.setUsername("zxl333");
    40         useradd.setPassword("333");
    41         result = sqlSession.insert(statament, useradd);
    42         System.out.println("insert new user result: " + result);
    43         
    44         //删去一个用户
    45         statament = "mapper.userMapper.delete";
    46         result = sqlSession.delete(statament, 2);
    47         System.out.println("delete user result: " + result);    
    48         
    49         //查找所有用户
    50         statament = "mapper.userMapper.selectAllUsers";
    51         List<User> list = sqlSession.selectList(statament);
    52         System.out.println("select all user result: " + list);    
    53         sqlSession.close();
    54     }
    55 }

    上面查找是通过username和password来查找的,所以在userMapper.xml中添加一部分如下:

    1     <select id="getUserbyMore" resultType="beans.User">
    2         select * from users where username=#{username} and password=#{password}    
    3     </select>

    如输入是多个参数,则parameterType应该是空的。并且Sql语句中where里面条件判断必须是数据表字段。

     格式有点乱,后面再修改。下面是一些参考博客!

    https://www.cnblogs.com/whgk/p/6692746.html----一杯凉茶

    https://www.cnblogs.com/xdp-gacl/p/4261895.html

    https://www.cnblogs.com/hellokitty1/p/5216025.html------学习笔记入门

    https://www.cnblogs.com/mengheng/p/3739610.html

    https://www.cnblogs.com/cage666/p/7359862.html-----对mybatis.cfg.xml做了详细介绍

  • 相关阅读:
    MYSQL中排序
    编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary)
    job1
    python中对于数组的操作
    python中将字符串转为字典类型
    python中的周几
    python 链接redis 获取对应的值
    jenkins 设置定时任务规则
    如何安全close go 的channel
    [转]
  • 原文地址:https://www.cnblogs.com/beilou310/p/10953956.html
Copyright © 2020-2023  润新知