MyBatis

Posted 拇指编程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis相关的知识,希望对你有一定的参考价值。



        今天这篇推文作者换人啦,作者我跑去吃鸡啦。下面有请我的好友——Guitar Fans。来个大家介绍一下什么是Mybatis MyBatis(1)MyBatis(1)MyBatis(1)



Mybatis是什么


        Mybatis是一个持久层的框架,是apache下的顶级项目。该项目目前托管在github下 https://github.com/mybatis/mybatis-3/releases ,下载后解压后目录如下,lib为依赖包,mybatis-3.4.6.jar为核心包。


MyBatis(1)


导入java项目,当然也要导入mysql连接包。


MyBatis(1) MyBatis(1)


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


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


MyBatis(1)




使用教程


        从基本配置文件开始讲起Mybatis注重配置文件和sql的编写,因此我们先了解一下MB的配置文件及其内容。


        首先是目录


MyBatis(1)


        config源码包存储的是mybatis项目中大部分的配置文件;

        db.properties是数据库连接信息;

        log4j.properties为该文件可设定日志的输出目的地和输出格式;

        SqlMapConfig.xml全局配置文件,该文件配置了数据源,映射文件的位置、别名等信息。


src源码包下

      com.fjj.first:junit:测试文件(基本映射测试)

      com.fjj.mapper:mapper:映射文件和对应的数据库操作接口

      com.fjj.po:pojo:自定义类型

      com.fjj.test:junit:测试文件


< 注:以上包和文件的命名可以更改,并非一定要这样命名其他都是项目所需要引用的包 >





接下来详细介绍各个文件的内容

1
log4j.properties

    先贴出文件内容


MyBatis(1)

    

        以上是对于java项目开发者所使用的文件内容,在开发环境 log4j.rootLogger 设置为DEBUG,在生产环境中设置为ERROR或者INFO,输出到控制台。

    如果要将日志输出到文件中,参考: https://blog.csdn.net/u012506661/article/details/52703057


2
db.properties

数据库连接信息配置,此处采用jdbc连接


MyBatis(1)


        这里注意一个细节,也是笔者之前在写一个简单的项目时遇到的问题。因为很多人都熟悉了在Java类中写数据库连接字符串,因此在url中设置字符这一段中经常使用 & 作为“与”来使用,那么在调试过程中,会报出以下错误


MyBatis(1)


        因为在properties文件中只能使用&amp来作为与连接。



3
SqlMapConfig.xml

        SqlMapConfig.xml是用作全局配置文件


<上滑查看内容MyBatis(1)MyBatis(1)>


<?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> 

      <!-- 加载属性文件 -->

      <properties resource="db.properties">

         <propertyname="username" value="123"/>

      </properties>

     

      <typeAliases>

      <!-- 单个别名定义 -->

      <!--<typeAlias type="com.fjj.po.User"alias="User"></typeAlias> -->

      <!-- 批量定义包名(推荐),自动扫描其中的类 ,类名首字母大小写均可-->

      <package name="com.fjj.po"></package>

      </typeAliases>

        <!-- 配置mybatis的环境信息,与spring整合,该信息由spring来管理 --> 

        <environments default="development"> 

            <environment id="development"> 

                <!-- 配置JDBC事务控制,由mybatis进行管理 --> 

                <transactionManagertype="JDBC"></transactionManager> 

                <!-- 配置数据源,采用mybatis连接池 --> 

                <dataSource type="POOLED"> 

                    <property name="driver"value="${jdbc.driver}"/> 

                    <property name="url"value="${jdbc.url}"/> 

                    <property name="username"value="${jdbc.username}"/> 

                    <property name="password"value="${jdbc.password}"/> 

                </dataSource> 

            </environment> 

        </environments> 

      <mappers> 

          <!-- 映射文件的位置 -->

          <!-- 一次加载一个mapper文件-->

          <!--<mapper resource="sqlmap/User.xml" /> 

     

          <mapper resource="mapper/UserMapper.xml"/> -->

         

          <!--通过mapper接口加载文件 -->

          <!--加载规范:需要将mapper接口类名和mapper.xml文件映射文件名保持一致,且在一个目录 -->

          <!--前提:使用mapper代理 -->

          <!--<mapper class="com.fjj.mapper.UserMapper"></mapper>-->

         

          <!--批量加载mapper

          指定包名,扫描包下所有mapper接口进行加载(推荐) -->

          <package name="com.fjj.mapper"></package>

       </mappers>

         

</configuration> 


MyBatis(1)



讲解sqlmapconfig.xml各标签作用

        A. properties:加载属性文件,其内含resource属性指明了属性文件名,在之后可以使用${文件名.属性}调用文件中的属性值,在标签内部可以定义单个属性property,如<property name="username" value="123"/>,即文件中的username值为123


        B. typeAliases:定义别名,在映射文件需要用到po层下的自定义类,若不定义别名,则每次都要使用路径查询类,如com.fjj.User,定义别名 后可以只用User,简化代码。批量定义别名,只需加入package标签,name 设置为包名称,会自动扫描该包下的所有类名,并作为别名来使用(推荐使用)


        C. 有关 transactionManager,

environment的作用可以看下注释在这里不做过多的解释


        D. mapper:指明映射文件的加载位置,有三个方法:第一种,一次加载一个mapper文件,在dao层写接口和实现类完成数据库操作,这种方法使得java代码中存在大量模板方法和硬编码;第二种,使用mapper接口加载文件,这里需要mapper接口和映射文件在同一目录下且文件名一致;第三种,注册指定包下的所有映射文件,同样要求mapper接口和映射文件在同一目录且文件名一致(推荐使用)


    E. 有关 association,settings,plugins,typeHandlers,objectFactory作用以后介绍



4
mapper映射文件


<还是一样的骚操作MyBatis(1)>


<?xml version="1.0"encoding="UTF-8"?>

<!DOCTYPE mapper

    PUBLIC"-//mybatis.org//DTD Config 3.0//EN" 

    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

   

<mapper namespace="com.fjj.mapper.UserMapper">

    <!-- 使用resultMap进行输出映射

    type:resultMap最终映射的Java类型

    id:resultMap标识符

     -->

    <resultMap type="User"id="userResultMap">

       <!-- id表示查询结果集中的唯一标识

       column:查询出来的列名

       property:type指定的pojo类型中的属性名

       最终resultMap对column和property做一个映射关系 -->

       <id column="id_"property="id"></id>

       <result column="username_"property="username"></result>

    </resultMap>

   

    <select id="findUserByIdResultMap"parameterType="int"resultMap="userResultMap">

       select idid_,usernameusername_ from user where id=#{value}

    </select>

    <!-- 用户信息综合查询

    #{userCustom.sex}取出pojo中用户性别

    -->

   

    <select id="findUserCount"parameterType="UserQueryVo"resultType="int">

       selectcount(*) from user where sex=#{userCustom.sex} and username like '%${userCustom.username}%'

    </select>

   

    <select id="findUserByUsername"parameterType="String"resultType="User">

       SELECT * FROMUSER WHERE username like '%${value}%'

    </select>

 

    <delete id="deleteUser"parameterType="int">

       DELETE FROMUSER WHERE id=#{id}

    </delete>

</mapper>


MyBatis(1)



        贴出以上代码,在下面的mybatis基础项目开发过程中会详细讲映射文件的作用的。




Mybatis单表查询及mapper代理


Mybatis开发大概流程如下:

        a.创建java项目,导入依赖jar包

        b.创建核心配置文件sqlmapconfig.xml

        c.创建映射文件UserMapper.xml

        d.创建实体类User,根据数据库表字段创建


MyBatis(1)

MyBatis(1)


        e.创建mapper接口文件,接口与映射文件名同名,接口方法名与映射文件中配置的sql的id对应



实体类mapper映射文件和mapper接口:

        Mapper映射文件namespace指定要映射mapper接口,在文件中select,insert,update,delete标签对应sql语句中的查,增,改,删;


MyBatis(1)


        如上所示,id是唯一标识,在与接口中的方法对应,parameterType表示输入值类型,即sql语句执行所需的条件值,resultType表示返回值类型,标签内部定义sql语句。


        这里select语句返回的记录可能不止一条,即返回值在java代码中表现为list,但是这里resultType表示单条记录表示的类型,因此这里还是返回user类型。若sql语句的条件没有输入值,则不需要定义parameterType,resultTye也是一样。



标签内部定义sql语句:

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

中like后面的字符有两种写法:


        1. '%${value}%',${}起到拼接字符串作用,使用这种方法拼接sql会有sql注入的风险


MyBatis(1)

        这是value为'范'查询的结果


MyBatis(1)

        这是value为'OR 1=1 OR'的结果,导致所有用户信息泄露。


        2. #{id},#{}起到占位符的作用,这种方法是不存在sql注入的,所以为了安全起见,在实际开发过程中,尽量使用#{}



哪些情况下使用${}拼接不会发生sql注入?

        有时候可能需要直接插入一个不做任何修改的字符串到SQL语句中。这时候应该使用${}语法。比如动态sql中的字段名:ORDER BY ${columnName}Mapper 映射文件配置好了以后就要写mapper接口,根据命名空间的定义,命名为UserMapper,接口内方法


MyBatis(1)


<注:接口写好以后不需要写实现类,可以在测试中直接调用>


测试类代码如下:


(划船不靠浆MyBatis(1)MyBatis(1)MyBatis(1)



package com.fjj.test;


import static org.junit.Assert.*;

import java.io.InputStream;

import java.util.List;

importorg.apache.ibatis.io.Resources;

importorg.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

importorg.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.Before;

import org.junit.Test;

import com.fjj.mapper.UserMapper;

import com.fjj.po.User;

 

public class UserMapperTest {

    privateSqlSessionFactory sqlSessionFactory;

   

    @Before

    publicvoid setUp() throws Exception {

        //配置代码

        Stringresource="SqlMapConfig.xml";

        InputStreaminputStream= Resources.getResourceAsStream(resource);

       

        //创建会话工厂

        sqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);

    }

 

@Test

publicvoid testFindUserByUsername()throwsException{

    SqlSessionsqlSession=sqlSessionFactory.openSession();

    UserMapperuserMapper=sqlSession.getMapper(UserMapper.class);

       List<User>list=userMapper.findUserByUsername("范");     

       System.out.println(list);

}   

}

MyBatis(1)


测试结果如下


MyBatis(1)


        可以看出以上输出的列名为username,sex,

birthday,id,与User类的属性名一直,但在实际开发中需要输出的列名不一定与pojo类属性名相同,这个时候就需要使用resultMap进行输出映射,以下面代码为例:



(他咋写怎么多呢MyBatis(1)MyBatis(1)MyBatis(1)



<!-- 使用resultMap进行输出映射

    type:resultMap最终映射的Java类型

    id:resultMap标识符

     -->

    <resultMap type="User"id="userResultMap">

       <!-- id表示查询结果集中的唯一标识

       column:查询出来的列名

       property:type指定的pojo类型中的属性名

       最终resultMap对column和property做一个映射关系 -->

       <id column="id_"property="id"/>

       <result column="username_"property="username"/>

       <result column="birthday_"property="birthday"/>

       <result column="sex_"property="sex"/>

       <result column="address_"property="address"/>

    </resultMap>

   

    <select id="findUserByIdResultMap"parameterType="int"resultMap="userResultMap">

       select idid_,sex sex_,usernameusername_,birthday birthday_,addressaddress_ from user whereid=#{value}

    </select>


MyBatis(1)


 

       resultMap中<id/>是查询结果集的唯一标识,比如User中的id,column为查询出来的列名,property为映射到pojo类型中的属性名,如id_映射到user类中的id<result/>是对普通列的映射定义,比如username,sex,birthday等。


        column为查询出来的列名,property是映射到pojo类型中的属性名。清楚这一点后,其他代码基本相同,输出结果如下:


MyBatis(1)





        最后,Guitar Fans 写了这么多也不知道让大家有没有理解Mybatis框架。不过这是第一篇,之后会继续推出Mybatis其他文章以及其他Web框架。期待吧MyBatis(1)MyBatis(1)




以上是关于MyBatis的主要内容,如果未能解决你的问题,请参考以下文章

MybatisMyBatis 注解方式的基本 用法

MybatisMyBatis之缓存

MyBatisMyBatis的增删改查

Mybatismybatis登录实例

MybatisMybatis基础(中)

MybatisMybatis缓存