MyBatis完整笔记分享

MyBatis

三层架构包含三层:界面层 业务逻辑层 数据访问层

界面层:接收用户的数据 显示请求的处理结果 (Jsp servlet html)

业务逻辑层:处理业务逻辑

数据访问层:完成对数据库的增删改查操作

三层对应的包:

​ 界面层:controller(servlet)

​ 业务逻辑层:Service包(xxxsercice类)

​ 数据访问层:dao包(xxxDao类)

三层中类的交互:

用户使用界面层–>业务逻辑层–>Dao层–>数据库

三层对应的处理框架:

界面层:–servlet–springMvc(框架)

业务逻辑层:–service类–spring(框架)

数据访问层:–dao类–mybatis(框架)

框架是一个舞台 是一个模板

模板:①规定了一些条款 内容

​ ②加入自己的东西

框架是一个模板:

​ ①框架定义好了一些功能 这些功能是可用的

​ ②可以加入自己的功能 这些功能可以利用框架已经写好的功能

框架:frameWork是整个或部分系统的可重用设计 简单说 框架是一个半成品的软件 定义好了一些基础功能 可重复使用可升级

框架特点:一般不是全能的 不能做所有的事情 是针对某一领域有效 比如MyBatis做数据库强 但是不能做其他的
  • myBatis框架:本是apache的一个开源项目iBatis 代码在Github

Github.com 在上面可以搜索关于Java的很多项目

  • MyBatis是sql映射框架

    ①sqlmapper:sql映射

    可以把数据库表中的一行数据 映射为一个Java对象,一行数据可以看作是一个Java对象 操作这个对象相当于操作表中的数据

    ②Data Access ObjectslDaps:数据访问 对数据库的增删改查操作

    MyBatis提供了哪些功能:
    ①提供了创建Comment Statement Result的能力

    ②提供了执行sql语句的能力 不用我们执行sql

    ③提供了循环sql 把sql的结果转化为对象 list集合的能力

    ④提供了关闭资源的能力 不用我们关闭 Connection Statement Result

    开发人员:提供sql语句

    最后:开发人员提供sql语句–=mybatis处理sql—开发人员得到list集合或Java对象(表中的数据)

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

    mapper(映射)

    第一个入门mybatis的例子

    实现步骤:①创建person表

    ​ ②加入maven的mybatis的坐标 mysql驱动的坐标

    ​ ③创建实体类person 保存表中的一行数据的

    ​ ④创建持久层的dao接口定义操作数据库的方法

    ​ ⑤创建一个mybatis使用的配置文件叫做sql映射文件 用来写sql语句的 一般一个表一个

    sql映射文件 这个文件是xml文件

    ​ ⑥创建mybatis的主配置文件 一个项目就一个主配置文件 主配置文件提供了数据库的连接信息和sql映射文件的位置信息

    ​ ⑦创建使用mybais类 通过mybatis访问数据库

    定义实体类 定义dao层接口 并在同级dao下建立与dao接口相同名字的sql映射文件 一般一张表一个 里面写官方的固定格式

    接口名与Mybatis的映射文件名一定要一模一样。

    ​ sql mapper文件 sql映射文件配置

    <?xml version="1.0" encoding="UTF-8" ?>      
        <!--    sql映射文件  (sql mapper)-- > 
        <!DOCTYPE mapper PUBLIC         -------指定约束文件----------
        "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <!--mapper为根元素,namespace指定了命名空间 namespace="接口的全限定名称"--><mapper namespace="com.bdqn.dao.PersonDao">  
        <!--查询操作--><!--id="dao接口里的方法名" resultType="实体类全限定名称(全类名)"-->    <select id="getList" resultType="com.bdqn.entity.Person"> 返回的数据的类型    
        SELECT * FROM person   
        </select
        ><!--    插入操作-->   
        <insert id="insert"> 
        insert  into person(id,useName,sex,pass)values (#{id},#{useName},#{sex},#{pass})
        </insert>
      </mapper>
    

    注释:①sql映射文件是用来写sql语句的 mybatis会执行这些sql

    约束文件:限制检查当前文件中出现的属性及标签必须符合mybatis的要求

    ②nameSpace:叫做命名空间 唯一值 可以是自定义的字符串但是不可重复

    • 要求使用dao接口的全限定名称(全类名)

    ③在当前文件中 可以使用特定的标签 表示数据特定的操作

    表示查询 select语句
    表示更新操作 update语句
    表示插入操作 insert语句
    表示删除操作 delete语句

点击类名右击选择CopyReference 获取 全限定名称的方法

例:

id要执行的sql的唯一标识 mybatis会使用这个id来找打要执行的sql语句 执行后得到Result 遍历后得到Java的对象的类型
在resources(资源)中创建mybaits.xml主配置文件 用来提供数据库的连接信息和sql映射文件位置信息

​ 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">
<!--myBatis的主配置文件,主要定义了数据库的配置信息 sql映射文件的位置-->
<!--配置信息-->
<configuration>
    <!--
       properties配置,用于加载外部的配置文件
     指定properties文件的位置 从类路径根开始找文件-->
     <properties resource=" jdbc.properties"/>

<!--    settings:控制mybatis全局行为-->
    <settings>
<!--        设置mybatis输出日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
<!--    定义自定义的别名  ①type:自定义类型的全限定名称 alias:别名(短小 容易记忆的)-->
    <typeAliases>
<!--        <typeAlias type="com.bdqn.entity.Person" alias="ps"></typeAlias>-->
<!--        ②name是包名 这个包中所有的类 类名就是别名(类名不区分大小写)-->
        <package name="com.bdqn.entity"/>
    </typeAliases>

<!--       主配置文件中配置插件--> 
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>   插件放在环境上面<environments>

    <!--environments主要用与数据源的配置 数据库的连接信息
        可以配置多个数据源,
        通过default=“数据源id”指定-->
    <environments default="development"><!--使用的是id为development的数据源-->
        <!--
        environment:用于配置一个具体的独立的数据源
        id属性是一个唯一值 用于给当前数据源定义一个名称,方便我们在上一级environments中指定
        -->
        <environment id="development">
            <!--
            transactionManager:用于配置事务管理,事务管理默认使用的jdbc管理
            -->
            <transactionManager type="JDBC"/>
            <!--
            dataSource:具体数据源的连接信息
            type:用于指定是否使用连接池
            这里type="POOLED"代表使用连接池
            -->
            <dataSource type="POOLED">
                <!--value是从properties中取到的-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/shun?useUnicode=true&characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
        <!--第二个数据源 也可以通过数据库的属性配置文件-->
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.pass}"/>
            </dataSource>
        </environment>
    </environments>
    <!--
    mappers:只要用于配置我们外部的映射配置文件
    在主配置中需要引入加载映射配置文件
    -->
    <mappers>
        <!-- (sql mapper) sql映射文件的位置
        mapper:主要配置引入某一个具体的映射文件,
        resource:进行路径方式引入
        -->
<!--        一个mapper标签指定一个文件的位置
                  从类路径开始的路径信息  代码编译后生成 target/classes(类路径) 不需要写target/classes
-->
<!--        <mapper resource="com/bdqn/dao/PersonDao.xml"></mapper>-->
    
<!--        当天需要因为入的映射文件多的时候  使用<package/>
           要求①mapper文件名称需要和接口名称一样 区分大小写一样
               ②mapper文件和dao接口需要在同一级目录
-->
        <package name="com.bdqn.dao"/>
    </mappers>
</configuration>

environment(环境)配置:数据库的连接信息

default:必须和某个environment的id值一样 告诉mybatis使用哪个数据库的信息 也就是访问哪个数据库

执行刚才示例操作的最后一步 创建使用nybatis类 通过mybatis访问数据库

使用步骤:
  • 访问mybatis读取student 数据

    ①定义mybatis猪配置文件的名称 从类路径的根开始(target/classes)

    String config=“mybatis.xml”;

    ②读取这个config表示的文件

    InoutStream in=Resources.getResourceASStream(config);

    ③创建sqlSessionFactoryBuilder对象

    sqlSessionfactoryBuilder builder=new sqlSessionfactoryBuilder();

    ④创建sqlSessionFactory对象

    sqlSessionFactiory factory=builder.build(in);

    ⑤获取sqlsession对象 从sqlSessionFacetory中获取(重要)

    SqlSession sqlsession=factory.openSession() 里面参数为true时候 默认提交事务 不然则非默认提交事务

    ⑥指定要执行的sql语句的标识 sql映射文件中的namespace+“.”+标签id值即和方法名一样

    Strign sqlId=“com.bdqn.dao.personDao . getList”

    ⑦执行sql语句 通过sql id找到语句

    List list=sqlSession.selectList(sqlId);

    ⑧输出结果

    总结:

    mybatis:

    ​ *作用:增强的JDBC访问数据库 执行增删改查

    ​ 基本步骤:①加入maven依赖

                   <!--    添加myBatis依赖-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.6</version>
            </dependency>
            <!--      添加数据库依赖-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.32</version>
            </dependency>
    

    ②创建dao接口 定义了操作数据库方法

    ③创建mapper文件也叫做sql映射文件 写sql语句的和接口中的方法对应的sql语句

    ④创建mybatis的主配置文件 1.连接数据库 2.指定mapper文件的位置路径

    ⑤使用mybatis对象 sqlsession通过他的不同方法执行sql语句

    ① 第一个入门的mybatis例子

                             第一个入门的mybatis例子   
    //访问mybatis读取person数据  
    //步骤:①定义mybatis主配置文件的名称 从类路径的根开始(target/classes)     
    String config="myBatis.xml";//        
    ②读取这个config表示的文件    
      InputStream  in=Resources.getResourceAsStream(config);
    //           ③创建sqlSessionFactoryBuilder对象     
    SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();//             ④创建sqlSessionFactory对象       
    SqlSessionFactory factory= builder.build(in);//            
    ⑤获取sqlSession对象  从sqlSessionFactory中获取 (重要)      
      SqlSession sqlSession=factory.openSession();
    ⑥指定要执行的sql语句的标识 sql映射文件中的nameSpace+"."+"标签id值" (重要)        String sqlId="com.bdqn.dao.PersonDao.getList";//         
    ⑦执行sql语句通过sqlId找到语句       
        List<Person>  pp=sqlSession.selectList(sqlId);//          
    ⑧输出结果  
        for (Person p:pp){   
      System.out.println("查询的Person"+p);    
    }     
    sqlSession.close();
    
    添加操作:

    ①在dao接口添加执行的接口

    ②在sql映射文件中添加

    inser into person(id,name,sex,pass)values(#{id},#{name},#{sex},#{pass});

    //使用#{}相当于占位符 其实就是JDBC的PreparedStatement中的??? 可以防止sql注入

#{}里的值必须和实体类的一致 例#{age}这个过程是通过反射来做的**

**${}一般会用于在模糊查询的情况**

 

**③一张表 一般一个sql映射文件 弄好之后在主配置文件中添加sql映射文件的路径信息**

④创建使用mybatis类 有固定模板 只需把执行的sql标识更改要执行的方法即可 然后创建一个数据对象  sqlsession调用insert(sql标识,obj)返回整数 一定要开启提交事务 sqlSession.commit();



* mybatis不会默认提交事务 所以在增删改操作后要手动提交事务sqlSession.commit();

或者在获取sqlSession对象的时候factory调用的openSession()参数为true时 自动提交事务

否非自动提交事务

  • 开启日志可得到执行的过程信息 把日志打印到控制台

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

    sqlSession执行的操作方法不同返回的类型也不同

  • 增删改 返回的是整数型

    • 查询的话 返回的可以是单个对象或者集合

查询select(sql标识)

添加insert(sql标识,传的数据对象)

-----------------------------------------------------------------------------------------------------------------------------主要类的介绍:
Resource:mybatis中的一个类 负责读取主配置文件

String config=“myBatis.xml”;
InputStream in= Resources.getResourceAsStream(config);

  
  ②sqlSessionFactoryBuilder:创建
  
  ```java
  SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
    sqlSessionfactory factory= builder.build(in);

​ ③sqlSessionFactory:重量级对象 创建对象耗时较长 使用资源较多 在整个项目中有一个就够用了

​ sqlSessionFactory接口:接口实现类defaultsqlSessionFactory()

​ 作用:获取sqlsession对象

​ sqlSession sqlsession=factort.openSession();

  • openSession方法说明

    openSession() 无参数的 非自动提交事务的sqlsession

    openSession(true) 参数为true的 自动提交事务的sqlsession

    sqlsession是一个接口 定义了操作数据库的方法 例如

    • selectone()

    • selectList()

    • insert()

    • update()

    • delete()

    • commit()

    • rollback

      使用sqlsession对象不是线程安全的 需要在方法内部中使用 在执行sql语句之前 使用opensession()

      获取session() 在执行完成后关闭它sqlsession.close() 可以保证它使用是线程安全的

      把重复的操作封装MybatisUtils工具类

      由于sqlSessionFactory() 是重量级对象 占用资源大 所以一个项目只需创建一个就够用了 所以把创建它放在静态代码块中 只能被执行一次 不用每次调用都新new一个 浪费资源 在虚拟机加载类的时候被执行 且只执行一次

      静态代码块:

      static {

      ​ }

      • 它是随着类的加载机制而执行且只执行一次 并优先于主函数 在代码块设计中可用来创建单例的对象 不用每次调用一个相同的对象的时候都要重新new一次 提高性能

                                mybatis封装的工具类
        //由于sqlSessionFactory是重量级对象 创建对象时候耗时较长 占用资源较大 整个项目只有一个就够用了    //不用每次调用时候都要new一个新的 所以把它放在静态代码块中在虚拟机加载类的时候就会被执行 而且只执行一次  
          private static SqlSessionFactory factory=null;  
          static {       
          //访问mybatis读取person数据      
          //步骤:①定义mybatis主配置文件的名称 从类路径的根开始(target/classes)        String config="myBatis.xml";   
          ②读取这个config表示的文件      
          try {          
          InputStream in= Resources.getResourceAsStream(config);            SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();//             ④创建sqlSessionFactory对象           
          factory= builder.build(in); 
          //重量级对象 创建对象耗时较长 使用资源较多 整个项目有一个就够用了   
          } catch (IOException e) {      
          e.printStackTrace();        
          }     
          ③创建sqlSessionFactoryBuilder对象   
          }    
          /**    *实现功能描述:获取sqlSession的方法   
          *@param   
          *@return org.apache.ibatis.session.SqlSession  
          */  
          public static SqlSession getSqlSession(){ 
          SqlSession sqlSession=null;      
          if(factory!=null){       
          // ⑤获取sqlSession对象,从sqlSessionFactory中获取 (重要)             sqlSession=factory.openSession();//非自动提交事务 参数为true时候 自动提交事务        }       
          return sqlSession; 
          }
        

②传统dao执行操作

public List<Person> getList() {
     SqlSession sqlSession=MybatisUtil.getSqlSession();//     
指定要执行的sql语句的标识 sql映射文件中的nameSpace+"."+"标签id值" (重要)   
String sqlId="com.bdqn.dao.PersonDao.getList";
      List<Person> list=sqlSession.selectList(sqlId);//         sqlSession.close();//关闭    
      return list;
      }

③动态代理:

​ 使用动态代理条件分析:

​ 例:测试类中personDao pp=new personDao();

​ List list=pp,selectPerson()


  • List list=pp,selectPerson();

①dao对象类型是personDao 全限定名称 com.bdqn.dao.personDao 全限定名称和naemSpace一样

②dao调用的方法名称 selectPerson 这个方法名就是mapper文件中的id值

通过dao调用的方法的返回值也可以确定 mybaits要调用的sqlsession方法

  • 若返回值为list 则调用的是selectList()方法

  • 若返回值为int 或者非list 看mapper文件中的标签是insert还是update就会调用sqlsession的insert()

  • 或者update()方法

    mybatis的动态代理:mybatis根据dao方法的调用 获取执行sql语句的信息 mybatis根据dao接口

    创建出一个dao接口的实现类 并创建这个接口的对象 完成sqlSession调用方法 访问数据库

    简单的来说就是不用自己去创建dao的实现类了 且mybatis的动态代理会帮我们创建出来一个dao接口的实现类

    动态代理getMapper

    通过自己封装的工具类获取sqlsession对象 在通过 sqlSession.getMapper(接口类名.class)

    获取personDao对象 对象再.里面的方法即可完成操作

    通过 sqlSession.getMapper(接口类名.class) 获取动态代理对象com.sun.proxy.$proxy2

    paramentherType使用:dao接口中方法参数的数据类型 ------(了解就行)

    paramentherType它的值是java类型的全限定名称(例如:java.lang.Integer)或是mybatis定义的别名(例如:int)

    paramentheType不是强制的 mybatis通过反射机制能够发现接口参数的类型 可以没有 一般不写

    **一个简单类型的参数:**简单类型 mybatis把java的基本数据类型和String都叫做简单类型

    **在mapper文件中获取简单类型的一个参数的值使用#{}**任意字符

      public void show5(){
          //①通过自己封装的工具类获取sqlSession对象         
          SqlSession sqlSession = MybatisUtil.getSqlSession();
          //        ②通过getMapper获取接口类的对象           
          PersonDao dao = sqlSession.getMapper(PersonDao.class);
                                              //参数为接口.class            System.out.println("dao="+dao.getClass().getName());//获取dao类型名字
          //dao=com.sun.proxy.$Proxy3      JDK的动态代理 
         // ③通过接口的对象获取他里面要执行的方法       
          List<Person> pp=dao.getList();         
          for (int i = 0; i < pp.size(); i++) {       
              Person p=pp.get(i);           
              System.out.println(p);      
          }          
          //或者-------------------->
                    
              for (Person person:pp){                                        System.out.println(person);    
              }     
      }
    

    mybatis是封装的JDBC操作:

    使用#{}后 mybatis执行sql是使用JDBC中的prepareStatement对象 由mybatis执行下面代码mybatis创建Connection prepareStatement Result 对象

    String sql=“select * from person where id=?”;

    prepareStatement pst=conn.prepareStatement(sql);

    ​ pst.setInt(15);

    以下操作与之前的JDBC操作相同

    mybatis中当需要传多个参数的时候 不能直接传 需要使用命名参数或者对象参数传递

    命名参数: (推荐使用)

    多个参数时候 使用@param命名参数 在形参定义的前面加入 @Param(“自定义的参数名称”)

    例如: List list(@Param("myId) Integet id,@Param(“myName”) String name);

    List<Person> personList
    (@Param("myId") Integer id,@Param("myPass") String pass);
    

    mapper文件中 多个参数时候 使用@Param命名

    例如:select * from person where id=#{“myId”} or name=#{“myName”);

    <select id="personList" resultType="com.bdqn.entity.Person">   
        select  * from person where id=#{myId} or pass=#{myPass};
    </select>
    

    操作完成之后 sqlsession.close();

    对象参数:

    ​ 把参数封装为一个对象进行传递参数

    按位置传参(不用记)

    通过Map传参(不用记)

    需要传递多个参数的时候使用命名参数或者对象参数

    两个占位符的比较

    **#**占位符 告诉mybatis使用实际的参数值代替并使用 PreparStatement对象执行sql语句#{}代替sql语句的? 避免sql注入 这样做更安全 更迅速 也是首选的做法

    ** ∗ ∗ 字符串替换告诉 m y b a t i s 使用 **字符串替换 告诉mybatis使用 字符串替换告诉mybatis使用中包含的 '字符串’替换所在的位置 使用statement把sql语句和${}的内容连接起来的 执行效率低 $有sql注入的风险 缺乏安全性主要用在替换表名字 列名 不同列排序等的操作

    $可以替换表名或者列名 能确定数据是安全的情况下 可以使用 select*from person order by ${id}

    $和#区别===》

    **#**①#使用了占位符在sql语句中占位的使用prepareStatement执行sql效率高

    ​ ②使用#避免sql注入 更安全

    **$**① $不使用占位符 是字符串连接的方式 使用statement对象 执行sql效率低

    ②$有sql注入的风险 缺乏安全性

    ③$用于替换表名或者列名

    执行的时候: $==>select * from person order by id asc

    ​ #==>select * from person order by ?asc

    ASC升序 DESC降序

    排序的时候使用 #{} 则无效果

    用 $来替换表名或者列名

    复习:

    mybatis:

    ​ Ⅰ.作用:增强的JDBC访问数据库 执行增删改查操作

    ​ Ⅱ.基本步骤:①加入maven依赖 mybatis和mysql驱动坐标

    ​ ②创建dao接口 定义了操作mysql的方法

    ​ ③常见mapper文件也叫sql映射文件 用来写sql语句的 和接口中的方法对应的sql语句

    ​ ④创建mybatis的一个主配置文件 1.连接数据库 2.指定mapper文件的位置

    ​ ⑤使用mybatis的对象 sqlSession通过他的方法执行sql语句

    ​ Ⅲ.使用mybatis的动态代理

    ① 什么是动态代理:mybatis会帮你创建dao接口的实现类 在实现类中调用sqlSession的方法执行sql语句

    ②使用动态代理的方式

    ​ 1.获取sqlSession对象sqlSessionFactory.openSession()

    ​ 2.使用getMapper方法获取某个接口的对象 sqlSession.getMapper(接口.class)

    ​ 3.使用dao接口的方法 调用方法要执行的方法 就执行了mapper文件中的sql语句

    ③使用动态代理方式的要求 1.dao接口和mapper文件在同一级目录

    ​ 2.dao接口和mapper文件名一致

    mapper文件的nameSpace值是接口的全限定名称

    ④mapper文件中的 等id是接口中方法的名称

    ⑤dai接口中不要使用重载方法 不要使用同名不同参的方法

    Ⅳ理解参数

    从java代码把实际的值传入到mapper中

    ①一个简单类型的参数:#{任意字符}

    ②多个简单类型的参数:

    1.使用@param(“自定义的名称”)

    例如: List list(@Param("myId) Integet id,@Param(“myName”) String name);

    2.使用一个java对象 对象的属性为mapper文件找到参数#{Java对象的属性名称}

    3.使用参数的位置 #{arg0}# {arg1}

    4.使用mapper作为参数 #{map的key}

    #和$的区别

    ①#使用占位符 表示列值的 放在等号的右侧

    ②$不使用占位符 表示字符串连接的 把sql语句连接成一个字符串

    ③#使用JDBC的prepareStatement执行sql 安全性高

    使用 J D B C 的 s t a t e m e n t 执行 s q l 有注入危险 ∗ ∗ 所以 使用JDBC的statement执行sql有注入危险 **所以 使用JDBCstatement执行sql有注入危险所以常用于替换表名或者列名**

    排序的时候只能使用${} 否则排序无效果

    替换表名的时候只能使用${} 因为其使用的是statement 若#{}使用的是prepareStatement则?代替

    会出现错误

    细节:#{}里面的参数名称 是通过接口传的参数来判断参数占位符名称是随意的还是指定的 但是最好是与所有属性名称一致

    reultType:的使用resultType的结果类型 可以是全限定名称或者别名

    mybatis的输出结果 mybatis执行了sql语句 得到Java对象

    resultType结果类型 指sql语句执行完毕后 数据转化为Java的对象

    resultType也可以是其他与查询出来的字段相匹配的实体类 (需要自己手动创建实体类)

    定义别名:若查询总条数或处理接收返回结果的类型 即int类型的

    使用全限定名称 java.lang.Interger或者别名int

    <select id="countList" reultType="java.lang.Interget"> 全限定名称
     或者   
    <select id="countList" resultType="int"> 别名
    

    定义自定类的别名的几种方式 (主要用全限定名称 --安全)

     1.<typeAliases>    (不推荐)
    
      type:自定义类型的全限定名称
    
     alias:别名 (短小 容易记忆的)
    
    <typeAlias type="com.bdqn.entity.Person" alias="ps">
    
    </typeAliases>
         
     2.<package>   (常用)但是有弊端
       <package> name是包名 这个包中所有类 类名就是别名(类名不区分大小写)
         <package name="com.bdqn.entity"/>
    缺点: 若不同包下的相同类名 则会报错-->重复      这个<package>也放在<typeAliases>

    查询返回map 1.列名是map的key 2. 列值是map的value

    返回map的时候 数据只能是一行的记录 多于一行 会报错

    resultType:叫做结果映射类型指定列名和java对象属性的对应关系 resultType已帮我们映射好

    resultMap:

    ①当自定义列值赋给哪个属性 ②当列名和属性名不一致的时候 一定使用resultMap

    设置结果映射类型

    while(res.next){

    person.setId(res.getInt(“id”)) mybatis进行自动进行操作的时候 属性和列名必须一致 不然赋值不上

    因为mybatis是通过映射自动完成赋值的

    }

    映射到JavaBean的简单类型属性

                自定义列值赋给哪个属性
    <resultMap id="personMap" type="com.bdqn.entity.Person"> id是自定义名称
       <!--        主键列用  <id column="id" property="id"/>-->    
       <id column="id" property="id"/> ====
       <!--        非主键列用  <result column="useName" property="name"/>-->
       <!--        column 是字段名 property 是对应的属性名-->   
       <result column="useName" property="useName"/>    ===
       <result column="sex" property="sex"/>      ===
       <result column="pass" property="pass"/>    ===
       </resultMap>
       <!--   ② 设置结果映射类型-->    
       <select id="personListSame" resultMap="personMap">这里填的自定义的名称
       SELECT id,useName,sex,pass FROM person 
       </select>
    

    JavaBean内部嵌套一个复杂数据类型(JavaBean)属性 association 一对一

    javaType:完整Java类名或别名。
    property:映射数据库列的实体对象的属性。
    id。设置该项可以有效地提升MyBatis的性能。
    result。property:映射数据库列的实体类对象的属性。 column:数据库列名或别名

      <resultMap id="billProvideResult" type="com.bdqn.entity.Bill" >   
      <id property="id" column="id"/>    
      <result property="billCode" column="billCode"/>      
      <result property="productName" column="productName"/>    
      <result property="totalPrice" column="totalPrice"/>   
      <result property="isPayment" column="isPayment"/>      
      <!--property是在实体类中的属性名称 javaType是属性的数据类型-->
          <!--        通过association进行provider对象赋值 -->       
      <association property="provider" javaType="com.bdqn.entity.Provider">            <id column="id" property="id"/>         
      <result column="proCode" property="proCode"/>          
      <result column="proName" property="proName"/>      
      <result column="proContact" property="proContact"/>     
      <result column="proPhone" property="proPhone"/>    
      </association>  
      </resultMap>
    

    association仅处理一对一的关联关系。

    association复用

    association提供了另一个属性:resultMap。通过这个属性可以扩展一个resultMap来进行联合映射

    <resultMap id="Repeat" type="com.bdqn.entity.Provider">通过id 进行Provider结果映射复用
    <id column="id" property="id"/>  
    <result column="proCode" property="proCode"/>
    <result column="proName" property="proName"/>   
    <result column="proContact" property="proContact"/>  
    <result column="proPhone" property="proPhone"/>
    </resultMap>
    

    JavaBean内部嵌套一个复杂数据类型(集合)属性

    collection一对多

    property:映射数据库列的实体对象的属性

    ofType:完整java类名或者别名(集合中所包括的类型)

    resultMap:引用外部的resulMap

    <resultMap id="billProvideResult" type="com.bdqn.entity.Bill" >   
      <id property="id" column="id"/>    
      <result property="billCode" column="billCode"/>      
      <result property="productName" column="productName"/>    
      <result property="totalPrice" column="totalPrice"/>   
      <result property="isPayment" column="isPayment"/>   
        //嵌套一个复杂数据类型(集合)属性进行赋值
        <collection property="java类中集合的名字" ofType="java类中集合中的实体全类名">
           <id property="" cloumn=""/>
           <result property="" cloumn=""/>
         </collection>
     </resultMap>
    
    

    resultType和resultMap不可以一起用

    当不使用mybatis执行查询操作的时候 实体类可以不与表中列名一致 因为是手动进行赋值的

    使用mybatis执行查询操作的时候实体类属性则必须和列名一致 因为mybatis是通过映射自动完成赋值操作的

    mybatis会根据查询的列名 将列名转化为小写 去进行设置(列名setter方法 )

    解决数据库表的列名和实体类的属性不一致的问题

    当不使用mybatis执行查询的时候 实体类中的属性可以不和数据库表中的列名必须一致

    但是若mybatis执行查询操作的时候 实体类中的属性必须和数据库表中的列名一致 因为是mybatis通过映射自动完成赋值操作的

    原因:Mybatis会根据查询的列名 (会将列名转化为小写) 去进行设值(列名setter方法)

    如果匹配不到则为空值

    ①通过设置别名和Java实体类的属性名一致

    <select id="personListSame" resultType="com.bdqn.entity.Person">实体类的全限定名称    
        SELECT id,useName as name,sex,pass FROM person
        </select>
    

    ②设置结果映射类型

       <resultMap id="personMap" type="com.bdqn.entity.Person">
    <!--        主键列用  <id column="id" property="id"/>-->
            <id column="id" property="id"/>   ===
    <!--        非主键列用  <result column="useName" property="name"/>-->
    <!--        column 是字段名 property 是对应的实体类属性名-->
            <result column="useName" property="name"/>      ===
            <result column="sex" property="sex"/>     ===
            <result column="pass" property="pass"/>  ===
        </resultMap>
        <select id="personListSame" resultMap="personMap"> 和命名的一样
            SELECT id,useName,sex,pass FROM person
        </select>
    

    这里推荐resultMap 因为当需要设置字段多的时候 别名AS就繁琐了.

    resultType和restulMap不可以一起用

    resultMap:结果映射 指定列名和Java对象的属性对应关系

    自定义列值赋给哪个属性

    当列名和属性名不一样时 一定使用resultMap

    like查询的两种方案

    ①Java代码指定like的内容(推荐)

    例: String name =“%李%” (传)

     select * from person where useName like #{useName}
    

    把该变量当参数传递

    ② 在mapper文件中拼接"%" 李 “%” String name=“李”(传)

    select * from person where name like "%" #{name} "%";
    

    模糊查询中 like ‘张_’ 表示张后面一个字符的数据

    ​ like ‘张%’ 表示张后面任意长度的数据

    ​ like '%张%'只要包含张的数据

    ctrl+alt+o 快捷键 相框内识别文字

    动态sql===》

    动态sql–if

    
    

    语法: 属性=XXX值 动态sql==》使用java对象作为参数

    <if test="使用参数Java对象的属性值作为判断条件" ></if>
    
    例:<if test="age>0">  这里age
    
     数据库列名<---age=#{age}
    
    </if>
    

    当条件不满足导致语法规则不正确时 在where后加1=1 或id>0 或者其他可以组成正确语法的均可

    动态sql–where

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

    <where>
    
    <if test="name!=null and name!=''">
    
       name=#{name}
    
    </if>
    
    </where>
    

    动态sql–foreach

    StringBuilder builder=new StringBuilder();

    拼接字符 builder.append()

    builder.deleteCharAt( builder.length()-1 ); 删除 最后一个字符 下标是从0开始的


    mybatis会帮助我们完成操作

    使用

    方式① list集合中为基本类型 不是对象的情况下

    <select id="getList" resultType="com.bdqn.entity.Person">
        select * from where id in
        <foreach collection="list" item="str" open="(" close=")" separator=",">
           #{str}
    </foreach>
    </select>
    

    collection:表示接口中方法参数的类型 如果是数组使用arrays 如果是集合list使用 list (小写的)

    iteam:自定义的表示数组或者集合成员的变量

    open:循环开始时的字符 close:循环结束时的字符

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

    方式 ② list集合中为对象时

    <select id="getList" resultType="com.bdqn.entity.Person">
        select * from where id in
        <foreach collection="list" iteam="str" open="(" close=")" separator=",">
         #{str.id} //通过对象获取其属性
        </foreach>
    </select>
    

    动态sql—代码片段

    代码片段:复用代码的一种快捷键 把反复用的代码 定义为一个代码片段

    语法规则:

     <sql id="studentSql"> 自定义的名称唯一的
      //里面是重复用的sql(可以是完整的 或者表名等)
    </sql>
    
    引用:<include refid="定义的唯一的名称"/>
    

    动态sql总结:

    根据条件得到不同的sql语句 使用mybatis的标签 if:判断条件的 条件为true执行if之间的sql

    添加到主sql之后


    where:里面是多个if 如果有一个if判断为true 在sql后加上一个where关键字 会去掉无用的and or 等字符


    foreach:循环数组 list集合


    sql代码片段:复用sql语句的
    
    ①先定义<sql id="自定义的唯一值">
    
    sql语句 表名字段等
    
    </sql>
    
    ②再使用<include refid="id的值"/>
    

    数据库的属性配置文件:

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

    ①在resouces目录中定义一个属性配置文件 xxx.properties 格式是key-value 一般使用"."做多级目录

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://127.0.0.1:3306/shunuseUnicode=true&amp;characterEncoding=utf8
    jdbc.user=rootjdbc.pass=root
    

    ②在mybatis的主配置文件 使用指定文件的位置 从类路径根 开始找文件即resource下 在需要使用值的地方${key}

    <!--   properties配置,用于加载外部的配置文件 指定properties文件的位置 从类路径根开始找文件--> <properties resource=" jdbc.properties"/>
    

    指定多个mapper文件的方式

    ①在标签中 再添加一个 映射文件路径

    若有100个映射文件则太麻烦

    ②使用包名

    <package name="com.bdqn.dao"/>
    

    name:xml文件mapper映射文件所在的包名 这个包中所有的xml文件 一次性都能加载给mybatis

    使用package的要求:

    ①mapper文件名称需要和接口名称一样 区分大小写

    ②mapper文件和dai接口需要在同一级目录

    例如: 全包名

    拓展:

    pageHelper 用来数据分页的 mybatis通用分页插件 支持多种数据库但不同数据库分页语法不一样

    pageHelper不是mybatis框架的 是国内作者写的一个小功能组件

    步骤:

    ①在pom.xml中添加PageHelper依赖

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

    ②主配置文件中配置插件

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

    ③测试通过PageHelper.starPage() 一定放在查询结果的前面

    总结:mybatis主配置文件 Ⅰ数据库属性配置文件的使用 Ⅱ mapper文件的位置

    • mappers标签中添加一个 一次只能引一个sql映射文件

    • package name=“全包名” 一次能加载给mybatis全部

    • PageHelper分页

      ​ ①功能:实现数据库的分页mysql就是代替limit语句的

      ​ ②使用步骤:1.加入maven依赖 2.主配置文件中配置插件 告诉mybatis要用它

      ​ ③查询方法之前 加入PageHelper.starPage(pageNum,pageSize)

      pageNum:代表从第几页开始查询

      pageSize:代表每页有多少条数据

      PageHelper.startPage会返回一个page对象,这个对象在查询结果出来后会把页数,记录总数给page对象,

      你用page.getPages()和getTotal()获取页数和记录总数。

      PageHelper是MyBatis的分页查询的插件。

你可能感兴趣的:(mybatis,java,数据库)