Mybatis基于接口代理实现DAO层的数据操作(关于多参数问题和模糊查询)

往期博客----> Mybatis的使用-操作数据库的学习和总结

之前使用Mybatis写了一个初级案例,这里介绍使用接口代理模式来降低代码耦合行,实现面向接口编程.

1.整体思想

  • 之前我们使用接口定义操作数据库的方法,然后使用实现类来实现接口,但我们依旧需要创建实现类对象来调用方法,并且当我们对任何的实现类代码修改时,写的类都需要重新编译,所以Mybatis使用xml配置文件来代替实现类,我们修改xml文件来配制sql查询语句.

2.实现过程

  • 配制环境:导入jar包,书写核心配制文件,创建实体类
  • 创建接口 PersonMapper:
public interface PersonMapper {
     
//定义一个查询所有消息的方法
    List<Person> queryAll()
}
  • 开始配制映射文件:


        //1.这里使用接口的全限定名来当做命名空间
<mapper namespace="com.offcn.mapper.PersonMapper">
    <select id="queryAll" resultMap="com.offcn.pojo.Person">
        select * from person
    select>
mapper>
  • 创建Junit测试类:
 @Test
    public void m1() throws IOException {
     
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = build.openSession();
        //前三部没有任何改变,获取SqlSession对象
        //使用代理模式获取接口对象,传入接口的类对象
        PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
        List<Person> people = mapper.queryAll();
        people.forEach(a-> System.out.println(a));
        sqlSession.commit();
        sqlSession.close();
    }

3.总结

  • 创建接口
  • 映射文件的命名空间使用接口的全限定名
  • 使用SqlSession的getMapper()方法获取接口对象
  • 调用方法

Mybatis中映射文件中sql语句传入多参数问题

  • 我们在使用修改语句时,需要传入id和需要修改的数据,此时我们面临多参数问题,这里在xml映射文件中该任何书写呢,这里有几种方法,我们慢慢来看.

1.使用方法索引

  • 我们的接口中有一个抽象方法:
void updatePerson(int id,String name);
  • 这里是通过传入id来修改名字,Mybatis给我们提供了两套参数规范,参数从第一个开始进行索引命名,分别是:
arg0,arg1,arg2… param1,param2.param3…
  • 当我们选择arg0开始和param1开始,或者混合使用
	 
    <update id="updatePerson">
        update person set pname=#{arg1} where pid=#{agr0}
    update>
     
    <update id="updatePerson">
        update person set pname=#{param2} where pid=#{param1}
    update>
	
    <update id="updatePerson">
        update person set pname=#{arg1} where pid=#{param1}
    update>
  • 缺点:做不到见名知其意

2.使用注解@Param

  • 我们使用为参数添加注解来实现见名知其意,现在修改接口中参数列表:
void updatePerson(@Param("pid") int pid,@Param("pname") String pname);
  • 这样我们在映射文件中可以直接使用id和name:
 <update id="updatePerson">
        update person set pname=#{name} where pid=#{id}
    update>
  • 缺点:方法参数少时可以使用,如果超过5个,则方法列表太长.

3.使用引用类型对象

  • 我们的接口中直接传入Person实体类对象,然后写实体类属性值,这里我就不多说了,这个是之前一直用的方式

4.使用Map(强烈推荐)

  • 我们直接传入Map对象,因为Map对象可以存储键值对,而且是可以动态添加的:
void updatePerson(Map map);
	<update id="updatePerson">
	//这里直接使用Map集合中的键值名就可以了
        update person set pname=#{pname} where pid=#{pid}
    update>
  • 测试 类代码:
@Test
    public void testupdatePerson() throws IOException {
     
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = build.openSession();
        PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
        Map map=new HashMap();
        map.put("pid",9);
        map.put("pname","程序逸");
        mapper.updatePerson(map);
        sqlSession.commit();
        sqlSession.close();
    }

Mybatis中模糊查询的实现

  • 我们如何实现sql语句的动态添加呢?根据姓名来查询结果,最基本的sql语句:
select * from person where name like%%
  • 第一步,实现接口方法:

    //模糊查询
    List<Person> fuzzy(String name);
  • 第二步,配置映射文件,这里有三种方式:
	//第一种,直接使用双引号拼接,缺点:Oracle数据库除了取别名使用双引号,其余不允许使用
 	<select id="fuzzy">
        select * from person where name like "%"#{name}"%";
    select>
	//第二种,使用${}来拼接,类似java中String的+操作,缺点:产生sql注入问题
	<select id="fuzzy">
        select * from person where name like '%${name}%';
    select>

	//第三种使用字符串拼接函数
	select * from person where name like concat('%',#{name},'%')
     // 缺点:0racle数据库concat函数不支持多次拼接
    // 解决方案:
    select * from person where name like concat(concat('%',#{name}),'%')
	

这里查询涉及到sql优化问题,我们一般使用*来查询所有字段,但这个效率低,这里使用sql代码片段.

  • 我们把所有字段属性名通过一个sql标签全部定义好,然后直接导入sql语句中就可以了:
	<sql>
		id,name,adress
	sql>

	 <select id="queryByName">
        select <include refid="baseColumn"/> from person where pname like concat(concat('%',#{name}),'%')
  	select>

当我们实体类字段名和数据库字段名不一样时,我们就需要手动设置映射关系了,这里在映射配置文件里面使用resultMap标签来实现.

  • 我们定义的实体类里面字段name如果变成了names,那么我们如果不指定映射关系,则出现查询结果为null,所以这里使用resultMap来指定names对应于表中的字段name:
		//1.标签的id属性类似唯一标识,type是指定的实体类
    <resultMap id="queryAll" type="com.offcn.pojo.Person">
    	//2.id标签是设置主键映射关系,property为实体类中属性名,column是表中字段名
        <id property="pid" column="pid">id>
        //3.result是普通字段指定映射关系
        <result property="pname" column="pname">result>
        <result property="adress" column="adress">result>
    resultMap>
   

到这里,一些基本的Mybatis的使用就结束了.

你可能感兴趣的:(Mybatis,mybatis)