一篇文章入门Mybatis(附思维导图)

文章目录

三层架构

三层架构包含的三层:

界面层,业务逻辑层,数据访问层

  • 三层的职责
    1. 界面层:主要功能室接受用户的数据,显示请求的处理结果.使用web界面和用户交互,手机app也是标傲世承认那个的,用户在app中操作,业务逻辑在服务器端处理
    2. 业务逻辑层:接收传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据
    3. 数据访问层:与数据库打交道.主要实现对数据的增删改查.将数据在数据库中的数据提交给业务层,同时将业务层处理事务数据保存到数据库

三层对应的包:

  • 页面层:controller
  • 业务逻辑成:service包
  • 数据访问层:dao包

三层中类的交互

用户使用界面层–>业务逻辑层–>数据访问层(持久层)–>数据库(mysql)

三层对应的处理框架

页面层-------servlet----springmvc

业务逻辑层------service类-------spring

数据访问层-------dao类---------mybatis

框架的概念

框架是一个模板

模板:

  1. 规定了一些条款,内容
  2. 加入自己的东西

框架是一些软件,半成品的软件,定义好了一些基础功能,需要加入你的功能就是完整的软件,它的基础功能室可重复使用的,可升级的

框架特点:

  1. 框架一般不是全能的,不能做所有事情
  2. 框架是针对某一个领域内有效,特长某一方面,比如mabatis做数据库操作强,但是不能做其他的
  3. 框架是一个软件

mybatis框架定义:

一个框架,早期叫做ibaatis,代码在github.

mybatis是mybatis SQL Mapper Framework for java(SQL映射框架)

  1. sql mapper :sql映射

    可以把数据库表中的一行数据,映射为一个java对象

    一行数据可以看做一个java对象.操作这个对象,就相当于操作表中数据

  2. dataaccess object (DAOs):数据访问,对数据库执行增删改查

mybatis提供了哪些功能:

  1. 提供了创建Connection,Statement,Resulset的能力,不用开发人员创建这些对象了
  2. 提供了执行sql语句的能力,不用你执行sql
  3. 提供了循环sql,把sql的结果转为java对象,List集合的能力
  4. 提供了关闭资源的能力,不用你关闭Connection,Statement,ResultSet

开发人员做的是:提供sql语句

最后是:开发人员提供sql语句–mybatis处理sql–开发人员得到list集合或者java对象

总结"mybatis是一个sql映射框架,提供的数据库的操作能力,增强的JDBC,使用mybatis让开发人员集中精神写sql就可以了,不必关心Connection,Statement,ResultSet的创建和销毁.

入门

下载mybatis

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

mapper文件

<?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="com.bjpowernode.dao.StudentDao">
    <select id="selectStudents" resultType="com.bjpowernode.domain.Student">
        select id,name,email,age from student order by id
    </select>
</mapper>
<!--
      select:表示查询操作
      id:你要执行的sql语句的唯一标识,mybatis会使用这个id的值来找到要执行的sql语句
         可以自定义,但是要求你使用接口中的方法名称

      resultTyoe:表示结果类型的,表示sql语句执行后得到的resultSet,遍历这个ResultSet得到的java对象的类型
          值写的名称是全限定名称
-->

<!--
sql映射文件:写sql语句的,mybatis 执行这些sql
       1.指定约束文件
       <!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        mybatis-3-mapper.dtd:约束文件的名称,拓展名是dtd的

        2.约束文件的作用:限制,检查当前文件中的标签,属性必须符合mybatis的要求.
        3.mapper 是当前文件的根标签,必须的
         namespace:叫做命名空间,唯一值得,可以是自定义的字符串
                   要求你使用dao接口的全限定名称.
        4.在当前文件中,可以使用特定的标签,表示数据库的特定操作.
        <select>:表示执行查询
        <update>:表示更新数据库的操作,就是<update>标签中,写的是update sql语句
        <insert>:表示插入
        <delete>:表示删除

-->

mybatis文件

<?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>
    <!--环境配置:数据库的连接信息
         default值必须和某个environment的id值一样
         告诉mybatis使用哪个数据库的连接信息,也就是访问哪个数据库
    -->
    <environments default="development">
        <!--environments:一个数据库的配置,环境
           id:一个唯一值,自定义的,表示一个环境的名称.
        -->
        <environment id="development">
            <!--
                  transactionManager:mybatis的事务类型
                  type:JDBC(表示使用jdbc中Connection对象commit,rollback做事务处理)
            -->
            <transactionManager type="JDBC"/>
            <!--
                 dataSource:表示数据源,连接数据库的
                 type:表示数据源的类型,POOLED表示使用连接池
            -->
            <dataSource type="POOLED">
                <!--
                    dirver,url,username,password是固定的,不能自己改
                -->
                <!--数据库的驱动类名-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--连接数据库的url字符串-->
                <property name="url" value="jdbc:mysql://localhost:3306/springdb"/>
                <!--访问数据库的用户名称-->
                <property name="username" value="root"/>
                <!--访问数据库的用户密码-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--sql mapper(sql映射文件)的位置-->
    <mappers>
        <!--一个mapper标签指定一个文件的位置
            从类路径开始的路径信息. (可以有多个)
        -->
        <mapper resource="com/bjpowernode/dao/StudentDao.xml"/>
    </mappers>
</configuration>

<!--
   mybatis的主配置文件:主要定义了数据库的配置信息,sql配置文件的位置

   1.约束文件的说明
   <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
     mybatis-3-config.dtd:约束文件的名称

   2.configuration
-->

问题:xml文件没有编译到target.classes下

首先检查pom.xml文件,查看是否有:

 <build>
<resources>
  <resource>
    <directory>src/main/java</directory><!--所在目录-->
    <includes><!--包括目录下面的.properties,.xml文件都会扫描到-->
      <include>**/*.properties</include>
      <include>**/*.xml</include>
    </includes>
    <filtering>false</filtering>
  </resource>
</resources>
  </build>
  1. 确保文件夹是这种格式的

    一篇文章入门Mybatis(附思维导图)

  2. 操作maven

一篇文章入门Mybatis(附思维导图)

  1. 重新构筑工程

一篇文章入门Mybatis(附思维导图)

  1. 清理缓存

一篇文章入门Mybatis(附思维导图)

一篇文章入门Mybatis(附思维导图)

这几步每次都尝试运行一下,运行成功后面就不需要了.

  1. 最终方式:上面几种都不行的话,直接拷贝到目标文件夹

    一篇文章入门Mybatis(附思维导图)

mybatis调试日志

 <!--控制mybatis全局行为的-->
    <settings>
        <!--设置mybatis输出日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

主要类的介绍

  1. Resources:mybatis中的一个类,负责读取主配置文件

    InputStream in = Resources.getResourceAsStream(“mybatis.xml”)

  2. SqlSessionFactoryBuilder:创建sqlSessionFactory对象,

    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

    //创建SqlSessionFactory对象

  3. SqlSessionFactory:重量级对象,程序创建一个对象耗时比较长,使用资源比较多.在整个的项目目中,有一个就够用了.

    SqlSessionFactory:接口,接口实现类:DefaultSqlSessionFactory

    SqlSessionFactory作用:获取SqlSession对象.

    SqlSession SqlSession = factory.openSession();

    openSession()方法说明:

    1. openSession():无参数的,获取是非自动提交事务的SqlSession对象

    2. openSession(boolean):

      openSession(true) 获取自动提交事务的SqlSession

      openSession(false) 获取非自动提交事务的SqlSession

  4. SqlSession:

    SqlSession接口:定义了操作数据的方法 例如seletctOne(),selectList(),insert(),update(),dalete(),commit(),rollback()

    sqlSession接口的实现类,DefaultSqlSession,

    使用要求:SqlSession对象不是线程安全的的,需要在方法内部使用,在执行sql语句之前,使用openSession()获取SqlSession对象,在执行完sql语句后,需要关闭它,执行SqlSession.close(),这样能保证它的使用是线程安全的.

动态代理条件分析

List studentList = dao.selectStudents();调用

  1. dao对象,类型是studentDao,全限定名称是:com.bjpowernode.dao.StudentDao权限定名称和namespace是一样的

  2. 方法名称,selectStudents,这个方法就是mapper文件中的id值selectStudents

  3. 通过dao种方法的返回值也可以确定mybatis要调用的方法SqlSession方法

    如果返回值是list,调用的是SqlSession.selectList()方法

    如果返回值int,或是非list的,看mapper中的标签是,就会调用SqlSession对应的方法

  4. mybatis的动态代理:mybatis根据dao的方法调用,获取执行sql语句的信息.mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的的的对象,完成SqlSession调用方法,访问数据库

动态代理:

StudentDao dao = SqlSession.getMapper(dao接口.class)获取这个dao接口的对象

使用mybatis动态代理机制,使用SqlSession.getMapper(dao接口)

getMapper能获取dao接口对应的实现类对象

深入理解参数

从java代码中传入mapper文件的sql语句中

  1. parameterType:mapper文件中的一个属性.表示dao接口中方法的参数的数据类型.例如StudentDao接口,并非强制的

  2. 简单类型:mybatis中吧java中基本参数类型和String类型叫做简单类型,在mapper文件获取简单类型的一个参数的值,使用#{任意字符}

  3. 传参原理:

    /*
     使用#{}之后,mybatis 执行sql语句是使用的jabc中的PreparedStatement对象
        由mybatis执行以下代码
        1.mybatis创建connection个,PreparedStatement对象
           String SQL = "select id,name,email,age from student where id = ?"
           PrepareStatement pst = new PrepareStatement(sql);
           pst.setInt(1,1001);
        2.执行sql封装为resultType = "com.bjpowernode.domain.Student"这个对象
           ResultSet rs = ps.executeQuery();
           while(rs.next()){
           //从数据库中存储数据,并存储到java对象的属性中
           }
    */
    

多个参数:

  1. 使用@Parm命名参数

接口 public List selectMulitParam(String name,Integer age)

使用 @Param(“参数名”) String name

mapper文件:

<select>
    select * from student where name = #{myname} or age = #{myage}
</select>
  1. 使用对象方式传递

     <!--多个参数,使用java对象的属性值,作为参数实际值
               使用对象的语法:#{属性名,javaType=类型名称,jdbcType=数据类型}   很少用
               javaType:指java中的属性数据类型
               jdbcType:在数据库中的数据类型
               例如:#{paramName,javaType = java.lang.String,jdbcType=VARCHAR}
    
               一般我们使用简化方式:#{属性名},javaType,jdbcType的值mybatis通过反射能够获取.不需要提供
    
        -->
        <select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
            select id,name,email,age from student where id = #{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
                                                     or age = #{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER}
        </select>
    
    简化版
    #{paramName}即可
    
  2. 按位置传参(了解)

  3. map传参(可读性很差,不建议使用)

#和$

  • #:占位符:告诉mybatis使用实际的参数值代替.并使用PrepareStatiment对象执行sql语句,#{…}代替sql语句的?.这样做更加安全,更迅速

    #的结果:select id,name,email,age from studetn where id = ?

  • ** ∗ ∗ : ∗ ∗ 字 符 串 替 换 ∗ ∗ : 告 诉 m y b a t i s 使 用 **:**字符串替换**:告诉mybatis使用 ∗∗:∗∗字符串替换∗∗:告诉mybatis使用包含的"字符串"替换所在位置.使用Statement把sql语句和${}的内容连接起来.主要用在替换表名,列名,不同列排序等操作.

    $的结果:select id,name,email,age from studetn where id = 1001

    使用的是Statement对象执行sql,效率比PreparedStatement低

    当你确定数据是安全的,可以使用$

#和$的区别(重点):

  1. #:使用?在sql语句中做占位的,使用PreparedStatement执行sql,效率高
  2. #:能够避免sql注入,更加安全
  3. $:不适用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
  4. $:有sql注入的风险,缺乏安全性.
  5. $:可以替换表名或者列名

封装mybatis输出结果

mybatis执行了sql语句,得到java对象

  1. resultType结果类型,指sql语句执行完毕后,数据转为java对象

    处理方式:

    • mybatis执行sql语句,然后mybatis调用类的无参数构造方法,创建对象
    • mybatis把ResultSet指定列值付给同名的属性
    <select id="selectMutiPosotion" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student
    </select>
    

    对等的JDBC:

    ResultSet rs = executeQuery("select id,name,email,age from student");
    while(rs.next()){
        Student student = new Student();
        student.setId(rs.getInt("id"));
        ...
    }
    

ResultType

  1. resultType结果类型,指sql语句执行完毕后,数据转为java对象,java类型是任意的

    resultType结果类型的它值,1.类型的全限定名称2.类型的别名,例如java.lang.Integer别名是int

  2. 定义自定义类型的别名

    1. 在mybatis主配置文件中定义,使定义别名
    2. 可以再resultType中使用自定义别名
     <typeAliases>
            <!--
            可以制定一个类型一个自定义别名
            type:自定义类型的全限定名称
            alias:别名(短小,容易定义)
            -->
    <!--        <typeAlias type="com.bjpowernode.domain.Student" />-->
    <!--        <typeAlias type="com.bjpowernode.vo.ViewStudent" alias="vstu"/>-->
            <!--
            <package> name是包名,这个包中的所有类,类名就是别名(类名不区分大小写)
            -->
            <package name="com.bjpowernode.domain.Student"/>
            <package name="com.bjpowernode.vo.ViewStudent"/>
    
    
        </typeAliases>
    
  3. resultMap:结果映射,指定列名和java对象的属性对应关系.

    1. 你自定义列值赋值给哪个属性
    2. 当你的列名和属性名不一样时,一定要使用resultMap
    <resultMap id="studentMap" type="com.bjpowernode.domain.Student">
            <!--列名和java属性之间的关系-->
            <!--主键列,使用id标签
                cloumn:列名
                property:java类型的属性名
            -->
            <id column="id" property="id"/>
            <!--非主键列,使用result-->
            <result column="name" property="name"/>
            <result column="email" property="email"/>
            <result column="age" property="age"/>
        </resultMap>
        <select id="selectAllStudents" resultMap="studentMap">
            select id,name,email,age from student
        </select>
    

    resultMap是可以复用的.

    resultMap和resultType不要一起用,二选一

  4. 使用resultType的不同属性的另一种方法,使用as起别名

like查询

  1. 提前准备好"%张%";
  2. 或者在mapper文件中准备好 “%” #{name} “%”

动态 SQL

  • 动态sql:sql的内容是变化的,可以根据条件获取到不同的sql语句.

    主要是where部分发生变化.

  • 动态sql的实现,使用的是mybatis提供的标签,,

    是判断条件的

    语法:

    ​ 部分SQL语句

    1. 用来包含多个的.当多个id有一个成立时,会自动增加一个where关键字,并去掉if中多余的 and or等.

    2. 循环Java中的数组,list集合的,主要用在sql的in语句

      比如学生id是 1001,1002,1003的三个学生

      select * from student where id in (1001,1002,1003)

      collection:表示接口中的方法参数的类型,如果是数组使用array,如果是list集合使用list

      item:自定义的,表示数组和集合成员的变量

      open:循环开始时的字符

      close:循环结束时的字符

      separator:集合成员之间的分割符

       <!--foreach使用1-->
          <select id="selectForeachOne" resultType="com.bjpowernode.domain.Student">
              select * from student where id  in
               <foreach collection="list" item="myid" open="(" close=")" separator=",">
                    #{myid}
               </foreach>
          </select>
      
       <select id="selectForeachTwo" resultType="com.bjpowernode.domain.Student">
              select * from student where id in
              <foreach collection="list" item ="stu" open="(" close=")" separator=",">
                  #{stu.id}
              </foreach>
          </select>
      

      对应的两个方法

       @Test
          public void testselectStudentForeachOne() {
              SqlSession sqlSession = MybatisUtil.getSqlSession();
              StudentDao dao = sqlSession.getMapper(StudentDao.class);
              Student stu = new Student(1001, "张三", "zhangsan@126.com", 25);
              List<Integer> list = new ArrayList<>();
      
      
              List<Student> student = dao.selectForeachOne(list);
              for (Student student1 : student) {
                  System.out.println("foreach---one===" + student1);
              }
          }
      
          @Test
          public void testselectStudentForeachTwo() {
              SqlSession sqlSession = MybatisUtil.getSqlSession();
              StudentDao dao = sqlSession.getMapper(StudentDao.class);
              Student stu = new Student(1001);
              Student stu2 = new Student(1002);
              List<Student> list = new ArrayList<>();
              list.add(stu);
              list.add(stu2);
      
      
              List<Student> student = dao.selectForeachTwo(list);
              for (Student student1 : student) {
                  System.out.println("foreach---one===" + student1);
              }
          }
      
  • sql代码片段,就是复用一些语法

    步骤:

    1. 先sql语句,表名,字段等
    2. 在使用即可

主配置文件

transactionManager:mybatis提交事务,回滚事务的方式

type:事务的处理的类型

  1. JDBC:表示mybatis底层是调用JDBC中Connection对象的,commit,rollback
  2. MANAGED:把mybatis的事务委托给其他的容器(一个服务器软件,一个框架(spring))

DataSource:表示数据源,java体系中,规定实现了javax.sql.DataSource接口的都是数据源.数据源表示Connection对象的

type:指定数据源的类型

  1. POOLED:使用连接池,mybatis回传件PooledDataSource类

  2. UNPOOLED:在每一次执行sql语句的时候,先创建连接,执行sql,再关闭连接

    mybatis会创建一个UnPooledDataSource,管理Connection对象的使用

  3. JNDI:java命名和目录服务(类似于windows注册表)

数据库的属性配置文件

把数据库的连接信息放到一个单独的文件中.和mybatis主配置文件分开,目的是便于修改,保存,处理多个数据库的信息

  1. 在resources目录中定义一个属性配置文件,xxxx.properties,例如jdbc.properties

    在属性配置文件中,定义数据,格式是key=value

    key:一般使用,做多级目录

    例如:jdbc.mysql.driver , jdbc.driver ,mydriver

    jdbc.driver=com.mysql.jdbc.Driver

    jdbc.url=jdbc:mysql//…

  2. 在mybatis的主配置文件中,使用指定文件的位置,在需要使用值的地方,${key}

指定多个mapper文件的方式

  1. 标签写多个,有多少个就写多少个

  2. 使用包名

    这个包中的所有xml文件都能一次加载进mybatis

    使用package的要求:

    1. mapper文件名称需要和接口名称一致,并且区分大小写
    2. mapper文件和dao接口需要在同一目录

pageHelper

pageHelper是用来做数据分页的

需要导入PageHelper依赖

<!--    PageHelper依赖-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.1.10</version>
    </dependency>

需要导入mybatis框架中

<!--配置插件-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

使用方法:

//加入pageHelper的方法,,分页
        //pageNum:第几页,从1开始
        //pageSize:一页中有多少行数据
        PageHelper.startPage(2,2);

xml文件都能一次加载进mybatis

使用package的要求:

  1. mapper文件名称需要和接口名称一致,并且区分大小写
  2. mapper文件和dao接口需要在同一目录

pageHelper

pageHelper是用来做数据分页的

需要导入PageHelper依赖

<!--    PageHelper依赖-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.1.10</version>
    </dependency>

需要导入mybatis框架中

<!--配置插件-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

使用方法:

//加入pageHelper的方法,,分页
        //pageNum:第几页,从1开始
        //pageSize:一页中有多少行数据
        PageHelper.startPage(2,2);

思维导图

一篇文章入门Mybatis(附思维导图)

上一篇:Processing 基础 | 粒子系统


下一篇:Processing 基础 | 极坐标系