浅谈Mybatis

 

一、什么是Mybatis

MyBatis是一个优秀的持久层框架,底层基于JDBC实现与数据库的交互。并在JDBC操作的基础上做了封装和优化,它借助灵活的SQL定制,参数及结果集的映射方式,更好的适应了当前互联网技术的发展。总之,Mybatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决JDBC将结果集封装为Java对象的麻烦。

 二、使用JDBC编程和Mybatis编程的区别 

1、使用传统方式JDBC访问数据库:

(1)使用JDBC访问数据库有大量重复代码(比如注册驱动、获取连接、获取传输器、释放资源等);

(2)JDBC自身没有连接池,会频繁的创建连接和关闭连接,效率低,耗内存

(3)SQL是写死在程序中,一旦修改SQL,需要对类重新编译;

(4)对查询SQL执行后返回的ResultSet对象,需要手动处理,有时会特别麻烦

2、使用MyBatis框架访问数据库

(1)Mybatis对JDBC对了封装,可以简化JDBC代码;

(2)Mybatis自身支持连接池(也可以配置其他的连接池),因此可以提高程序的效率;

(3)Mybatis是将SQL配置在mapper文件中,修改SQL只需要修改映射文件,类不需要重新编译。

(4)对查询SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象。

三、Mybatis编程步骤

(1)获取MyBatis核心配置文件/全局配置文件

2)通过核心配置文件获取SqlSessionFactory工厂对象

3)通过工厂对象打开SqlSession回话

(4)通过namespace+id找到要执行的sql语句并执行

(5)返回结果

public void findAll() throws IOException {
	//1.读取mybatis的核心配置文件(mybatis-config.xml)
	InputStream in = Resources
			.getResourceAsStream("mybatis-config.xml");

	//2.通过配置信息获取一个SqlSessionFactory工厂对象
	SqlSessionFactory fac = new SqlSessionFactoryBuilder().build( in );
    
	//3.通过工厂(SqlSessionFactory)打开Session
	SqlSession session = fac.openSession();

	//4.通过[namespace+id]找到要执行的sql语句并执行sql语句
	List<Emp> list = session.selectList("EmpMapper.findAll");

	//5.输出结果
	for(Emp e : list) {
		System.out.println( e );
	}
}

1)在编写之前的准备

(1)创建一个maven工程

(2)在pom.xml文件中导入所需要的依赖

(3)创建核心配置文件(mybatis-config.xml)和映射文件(EmpMapper.xml)

(4)在核心配置文件中配置环境(事务管理方式--JDBC/MANAGED和数据源--POOLED/UNPOOLED),和导入映射文件

(5)编写实体类(Emp.java),用于封装数据,实体类中的属性和数据库表中的列名尽量保持一致,添加私有属性提供对应的get和set方法,并重写toString方法

注意:在写映射文件的时候Mapper标签上的namespace,要求不能重,select/insert/update/delete 标签上的id属性也不能重复,在程序中通过【namespace + id 】定位到要执行哪一条SQL语句

2)如果实体类的属性与数据库表中的字段(列名)不一致的解决方法

(1)在为字段添加别名

假如Emp的属性值为 idd,namee ,jobb,salary  ---  数据库表中的列名为id,name,job,salary

    <select id="findAll" resultType="com.tedu.pojo.Emp">
		select id idd,name namee,job jobb,salary from Emp
    </select>

(2)使用sql标签,也是添加别名,只是把它提取到了sql标签

    <!--  id属性为唯一标识,与refid相对应 -->
    <sql id="emp">
        id idd,
		name namee,
		job jobb,
		salary salary
	</sql>
	<select id="findAll" resultType="com.tedu.pojo.Emp">
		select 
			<include refid="emp"/>
		 from Emp
	</select>

(3)使用resultMap标签

type 属性:用于指定将数据的返回结果封装到哪个实体类中

id属性: 这个封装规则的唯一标识,用于被查询标签中的resultMap所引用

colunm属性:填写数据库表的字段名

property属性:填写实体类的属性值

如果数据库表中的字段名与实体类属性相同的可以不写

    <resultMap type="com.tedu.pojo.Emp" id="empMap"> 
    <!-- 如果是主键需要用id标签,其他的除集合外用result标签存储数据库字段与实体类之间的映射 -->
		<id column="id" property="idd"/>
		<result column="name" property="namee"/>
        <result column="job" property="jobb"/>
	</resultMap>
	
	<select id="findAll" resultMap="empMap">
		select * from Emp
	</select>

四、Mybatis中#{}和${}的区别

#{}:相当于JDBC中的问号(?)占位符,会先预编译,能防止SQL注入攻击,并且当#{}占位符是为字符串或者日期类型的值进行占位时,会进行转义处理(在字符串或日期类型的值的两边加上单引号);

${}:是为SQL片段进行占位,直接将传过来的SQL片段拼接在 ${} 占位符所在的位置,不会进行任何的转义处理。由于是直接将参数拼接在SQL语句中,因此可能会引发SQL注入攻击问题

需要注意的是:使用 ${} 占位符为SQL语句中的片段占位时,即使只有一个占位符,需要传的也只有一个参数,也需要将参数先封装再传递!

<!-- $占位符进行模糊查询 -->
select * from emp where name like '%${name}%'

<!-- #占位符使用concat函数进行字符串拼接 能防止sql注入 -->
select * from emp where name like concat('%',#{name},'%')

五、MyBatis的动态SQL标签

(1)where标签

用于对包含在其中的SQL片段进行检索,在需要时可以生成where关键字,并且在需要时会剔除多余的连接词(比如and或者or)

(2)if标签

是根据test属性中的布尔表达式的值,从而决定是否执行包含在其中的SQL片段。如果判断结果为true,则执行其中的SQL片段;如果结果为false,则不执行其中的SQL片段

<select id="select01" resultType="com.tedu.pojo.Emp">
 	 select * from emp
 		 <where>
  			  <if test="name != null">
    			and name = #{name}
   			  </if>
   			  <if test="salary!= null">
    			and salary = #{salary}
   			  </if>
          </where>
</select>

(3)choose标签

按顺序判断when中的条件出否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满则时,则执行 otherwise中的sql。类似于Java 的switch  case语句,choose为switch,when为case,otherwise则为default。

<select	id="select01"	resultType="com.tedu.pojo.Emp">     
    select * from emp    
    <where>     
        <choose>     
            <when test="name!=null ">     
                    and name = #{name}
            </when>     
            <when test="job!= null ">     
                    and job =#{job}      
            </when>                   
            <otherwise>     
                    and id = 10
            </otherwise>     
        </choose>     
    </where>     
</select>   

(4)set标签

使用set标签可以将动态的配置set关键字,和剔除追加到条件末尾的任何不相关的逗号。

<update id="update01" resultType="com.tedu.pojo.Emp">     
    update emp 
    <set>     
        <if test="name!=null ">     
           name =#{name},     
        </if>     
        <if test="job!=null ">     
           Job =#{job}, 
        </if> 
        <if test="salary!=null ">     
            salary = #{salary}  
        </if>     
    </set>     
    where id =#{id}    
</update>  

(5)foreach标签

可以对传过来的参数数组或集合进行遍历。以下是它的一些基本属性:

item必需,若collection为数组或List集合时,item表示其中的元素,若collection为map中的key,item表示map中value(集合或数组)中的元素

collection必需,值为遍历的集合类型,例如:如果参数只是一个数组或List集合,则collection的值为array或list;如果传的是多个参数,用map封装,collection则指定为map中的key。

open可选,表示遍历生成的SQL片段以什么开始,最常用的是左括号'('

close可选,表示遍历生成的SQL片段以什么结束,最常用的是右括号')'

separator可选,每次遍历后给生成的SQL片段后面指定间隔符

<delete id="deleteByIds">
	delete from emp where id in
	<foreach collection="array" open="(" item="id" separator="," close=")">
		#{id}
	</foreach>
</delete>

六、MyBatis的接口开发

1创建一个接口,接口的全限定类名和mapper文件的namespace值要相同

2mapper文件中每条要执行的SQL语句,在接口中要添加一个对应的方法,并且接口中的方法名和SQL标签上的id值相同

3Mapper接口中方法接收的参数类型,和mapper.xml中定义的sql的接收的参数类型要相同

4接口中方法的返回值类型和SQL标签上的resultType即返回值类型相同(如果方法返回值是集合,resultType只需要指定集合中的泛型)

测试类的实现代码

public void testFindById() throws Exception{
  //1、获取核心配置文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml")
  //2、获取工厂对象,并根据工厂对象获取SqlSession对象
     SqlSessionFactory fac =new SqlSessionFactoryBuilder().build(in);
  //true表示自动提交事务,mabatis默认手动提交
   	 SqlSession session = fac.openSession(true);
  //3.获取Mapper接口对象
  EmpMapper map = session.getMapper(EmpMapper.class);
  //4.调用接口对象的方法进行查询
  Emp e = map.findById(2);
  //5.输出结果
  System.out.println(e);
}

 


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值