zoukankan      html  css  js  c++  java
  • MyBatis框架简介

    什么是MyBatis?

    MyBatis是一个优秀的持久层框架(就是将某些数据持久化到硬盘或其他存储器中的框架),它把jdbc对数据库的操作进行了封装,使用户只需关注sql本身,不需要去执行jdbc的那一套复杂的操作。
    MyBatis通过配置xml文件或注解的方式,将statement或preparedstatement中的sql语句与java对象中的数据相互映射,最终生成可执行的sql语句,由MyBatis执行sql语句,并将返回结果封装成java对象。
    简而言之,MyBatis封装了JDBC对数据库的复杂操作,并将返回结果封装成所需的java对象。
    MyBatis流程图:
    image
    1.MyBatis-config.xml文件是MyBatis的核心配置文件,这个文件中配置了运行环境,事务管理方式,是否使用连接池等,MyBatis可以通过该配置文件创建SqlSessionFactory
    2.SqlSessionFactory用来创建SqlSession
    3.SqlSession是用来发送sql语句到数据库执行,并返回结果,类似于jdbc中的connection
    4.executor是MyBatis的一个底层对象,用于执行sql语句
    5.MapperStatement也是MyBatis的一个底层对象,用于将配置文件中的sql语句映射为可执行的sql语句。


    JDBC与MyBatis的对比

    JDBC:
    1.使用jdbc有大量重复且复杂的代码
    2.jdbc中的sql语句是写死在代码中,一旦修改sql还需重新编译代码
    3.jdbc本身是不支持使用连接池的,会不断的创建连接,释放资源,影响效率
    4.jdbc返回的ResultSet对象,需要我们手动处理,特别麻烦
    MyBatis:
    1.MyBatis对JDBC进行了封装,可以简化了代码
    2.MyBatis的sql语句都是写在配置文件中的,如需修改sql,修改配置文件即可
    3.MyBatis本身是支持连接池的,且MyBatis还可以兼容其他连接池
    4.MyBatis会将返回的结果,封装为相应的java对象,极大的减少了我们的麻烦。

    MyBatis的用法

    1.首先导入MyBatis框架的所需依赖

        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
    

    2.配置MyBatis的核心配置文件,MyBatis-config.xml
    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">
        
    <!-- MyBatis的全局配置文件 -->
    <configuration >
    	
    </configuration>
    

    第一行是xml文档的声明,及使用的编码
    第2,3,4行用来引入xml文件的约束文档,该文档受mybatis-3-config.dtd的约束
    mybatis的环境配置都是在configuration中进行配置的。
    2)配置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的全局配置文件 -->
    <configuration >
    	<environments default="develop">
    		<environment id="develop">
    			<!--配置事务管理方式,MANAGED/JDBC
    			MANAGED:自己管理
    			JDBC:由JDBC进行管理(推荐)
    			-->
    			<transactionManager type="JDBC"></transactionManager>
    			<!--配置数据库连接方式,POOLED/UNPOOLED/JNDI
    			JNDI:已过时
    			UNPOOLED:不使用连接池
    			POOLED:使用连接池
    			-->
    			<dataSource type="POOLED">
    				<property name="driver" value="com.mysql.jdbc.Driver"/>
    				<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
    				<property name="username" value="root"/>
    				<property name="password" value="root"/>
    			</dataSource> 
    		</environment>
    	</environments>
    	<mappers>
    		<mapper>
    		 <mapper resource="EmpMapper.xml"/>
    		</mapper>
    	</mappers>
    </configuration>
    

    environments,mybatis中可以同时部署多套环境,都是配置在environments,通过environments标签中的default属性来切换环境。
    environment,mybatis中的环境配置,每个environment都有一个id,environments通过这个id来切换环境
    transactionManager,数据库事务管理方式,由MANAGED/JDBC两种,MANAGED,自己手动管理事务,JDBC,由jdbc来管理事务
    datasource,数据源,这里配置数据库连接是否使用连接池,JNDI/POOLED/UNPOOLED
    mappers,可以在该标签下配置多个mapper
    mapper,每个mapper对应一个mapper.xml配置文件


    3.创建对应表的mapper.xml文件,并将该映射文件配置到MyBatis-config.xml文件中

    <?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值应该保证唯一
    	在程序中通过[ namespace + id ]定位到要执行哪一条SQL语句
     -->
    <mapper namespace="EmpMapper">
    	<!-- 通过select、insert、update、delete标签声明要执行的SQL -->
    	<!-- 练习1: 查询emp表中的所有员工信息
    		resultType指定查询的结果将会封装到什么类型中
    		即使最终返回的结果是集合(List<Emp>),resultType也只需要指定集合中的泛型即可!
     	-->
    	<select id="findAll" resultType="com.tedu.pojo.Emp">
    		select * from emp
    	</select>
    
    </mapper>
    

    mapper,根标签,其中namespace(命名空间,要求不能重复),通过namespace+id来定位一条sql语句
    select,映射文件中配置的sql类型标签
    id,一条sql语句的标识
    resultType,sql执行返回的结果类型,如果返回的是一个集合,那么这里包含的应该是集合的泛型,例如上述sql返回结果为list
    则这里resultType就是泛型emp的全限定类名
    resultMap,复杂对象结构,常用与多表查询,resultType与resultMap不能同时使用


    4.通过Java代码查询数据库中数据

    public class TestMyBatis(){
    	public void main(String args[]){
    		//1.读取MyBatis-config.xml核心配置文件
    		InputStream in=Resources.getResourceAsStream("mybatis-config.xml");
    		//2.创建SqlSessionFactory对象
    		SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
    		//3.创建Sqlsession对象
    		SqlSession sqlSession=sqlSessionFactory.openSession();
    		//4.执行sql语句
    		List<emp> empList = sqlSession.selectList("emp.findAll");
    		//5.对返回结果进行操作
    		for (emp item:empList) {
          		 System.out.println(item.toString());
            }
    	}
    }
    

    MyBatis中的占位符#{}和${}

    ${}和#{}的区别:
    ‘#{}’相当与jdbc中的?,并会将传进来的字符进行转义处理,在字符的两边加上单引号。

    ‘${}’是直接将传进来的字符拼接到sql中的,因此有可能出现sql注入,所以每个${}传进来的值,都需进行封装,即使只有一个值。


    动态sql标签

    标签''

    <!-- 
    * 如果没有参数, 则不执行where子句, 默认查询所有员工:
    * 	select * from emp
    * 如果参数中只有minSal(即minSal不为null), 则:
    * 	... where salary > minSal
    * 如果参数中只有maxSal(即maxSal不为null), 则:
    * 	... where salary < maxSal
    * 如果参数有 minSal、maxSal(即minSal、maxSal不为null), 则:
    *		... where salary > minSal and salary < maxSal  -->
    <select id="findAllBySal" resultType="com.tedu.pojo.Emp">
      select * from emp
      where 1=1
      <if test="minSal != null">
      	and salary>#{minSal}
      </if>
      <if test="maxSal != null">
      	and salary <![CDATA[ < ]]> #{maxSal}
      </if>
    </select>
    

    根据if标签中的test属性,来判断是否拼接if标签中的sql
    注意sql中的 'where 1==1',这是为了防止第一个if中的and


    标签''

    <!-- 
    * 如果没有参数, 则不执行where子句, 默认查询所有员工:
    * 	select * from emp
    * 如果参数中只有minSal(即minSal不为null), 则:
    * 	... where salary > minSal
    * 如果参数中只有maxSal(即maxSal不为null), 则:
    * 	... where salary < maxSal
    * 如果参数有 minSal、maxSal(即minSal、maxSal不为null), 则:
    *		... where salary > minSal and salary < maxSal  -->
    <select id="findAllBySal2" resultType="com.tedu.pojo.Emp">
      select * from emp
      <where>
        <if test="minSal != null">
        	and salary>#{minSal}
        </if>
        <if test="maxSal != null">
        	and salary <![CDATA[ < ]]> #{maxSal}
        </if>
      </where>
    </select>
    

    where标签会在需要的时候生成where语句,并且会剔除多余的and或or,例如本例中若第一个if成立就会生成where并剔除and
    标签''
    这个标签主要用于遍历集合

    <!-- 
    	delete from emp where id in (1,3,5,7)
    	collection: 如果传的参数仅仅是一个数组或者List集合, collection可以指定为
    		array或list; 如果传的是多个参数,用map封装,collection则指定为map中的key
    	open: 指定生成的SQL片段以什么符号开始
    	close: 指定生成的SQL片段以什么符号结束
    	item: 指定变量接收数组或集合中的元素
    	separator: 指定一个间隔符, 在将数组或集合中的每个元素拼接到SQL片段之后, 
    		在后面拼接一个间隔符
     -->
    <delete id="deleteByIds">
    	delete from emp where id in
    	<foreach collection="array" open="(" item="id" separator="," close=")">
    		#{id}
    	</foreach>
    </delete>
    

    foreach标签中的属性
    collection 集合(必需)
    item 集合中的元素(必需)
    open 以什么开始
    close 以什么结束
    separator 集合中元素的分割符


    MyBatis的接口开发

    上述,在Java代码中查询数据库时,是通过namepace+id定位sql的,mybatis还有一个更简单的方法来定位sql,通过接口中的方法直接定位到sql
    要求:
    1.创建一个接口,再创建mapper映射文件,映射文件中的namespace与接口的全限定类名一致
    2.mapper映射文件中的每条sql,接口中都需要有一个对应的方法
    3.接口中方法的入参类型要与sql中接收的参数类型一致
    4.接口中方法的返回值类型要与sql中resultType中的一致(注意resutType中只是泛型)

  • 相关阅读:
    JVM 基础知识
    Maven 学习
    Java 中 split() 方法
    JDK、JRE、JVM三者联系与区别
    Effective C++ 笔记 —— Item 5: Know what functions C++ silently writes and calls
    Effective C++ 笔记 —— Item 4: Make sure that objects are initialized before they’re used
    Effective C++ 笔记 —— Item 3: Use const whenever possible
    Effective C++ 笔记 —— Item 2: Prefer consts, enums, and inlines to #defines
    Idea社区版使用插件完成正常开发
    DNS配置
  • 原文地址:https://www.cnblogs.com/planted/p/15207485.html
Copyright © 2011-2022 走看看