Mybatis的深入

Mybatis的深入

Mybatis的深入_第1张图片
目录

课程介绍

  • 回顾mybatis的自定义再分析和环境搭建+完善基于注解的mybatis
  • mybatis的CRUD(基于代理dao的方式)
  • mybatis的参数深入及结果集的深入
  • mybatis基于传统dao的编写方式(编写dao的实现类)--了解
  • mybatis中主配置文件的介绍(SqlMapConfig.xml)
    • properties标签
    • typeAliases标签
    • mappers标签

配置基于dao代理的CRUD

配置基于dao代理的CRUD很简单,自己不用写dao的实现类,只需要配置两个地方就可以使用dao进行CRUD操作,前提是mybatis的主配置文件已经写好,这个可以看day01环境配置那里。

  1. dao接口添加方法
  2. dao接口对应的映射配置文件添加方法对应的sql语句,还要指明对应方法的参数类型,返回值类型

1. 保存

  • IUserDao接口添加方法 void saveUser(User user);

  • IUserDao.xml添加insert标签:

    • insertid方法名

    • insert标签中需要添加参数类型parameterType,因为该方法有参数传入

    • parameterType属性:如果是自己定义的类,需要全限定类名

    • sql语句需要参数,使用#{value}从形参中按照变量名获取,====================

    • 
       
          
            
                insert into user(name,address,sex,birthday) values(#{name},#{address},#{sex},#{birthday});
          
      
      

2. 更新

  • void updateUser(User user);
    
  • 
        
            update user set name=#{name},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id};
        
    

3. 删除

  • void deleteUser(int id);
    
  • 需要提供int id,就给了Integer,这里只要是能表示出int类型的都可以,包括intINT等。

  • 
        
            delete from user where id=#{uid};
        
    

4. 根据id查找用户

  • /**
     * 根据id查找user
     * @param id
     * @return
     */
    User findById(int id);
    
  • 这里方法有返回值,所以要用 resultType指明返回类型,自定义对象需要全限定类名,String之类基本数据类型只要写出那几个字母即可,如 stringintdouble即可,没有严格要求,后面会讲为什么。

  • 同时如果只有一个参数,且是基本类型,则 #{value}中的value随便写都可以,不用和形参名对应

  • 
        
    

5. 返回List的查询所有用户

  • /**
     * 查询所有user
     * @return
     */
    List findAll();
    
  • 这里返回值 resultType指明为com.chajiu.domain.User,即泛型的实际类型即可。

  • 
    
    

6. 模糊查找

  • /**
     * 根据名字模糊查询
     * @param name
     * @return
     */
    List findByName(String name);
    
  • 此处把 '%王%'句子放在了形参里,故调用时需要提供参数为:%王%

  • 
    
    

接下来就可以进行测试。

7. 返回一行一列:查询用户总数

  • /**
     * 查询总数
     * @return
     */
    int findTotal();
    
  • 没啥特别,只要指明返回类型即可。

  • 
    
    

mybatis dao测试

使用dao需要六步:

  //1. 读取配置文件,生成字节输入流
      
  //2. 获取SqlSessionFactory对象
       
  //3. 获取SqlSession对象
       
  //4. 获取dao的代理对象
  
  //5. 使用代理对象执行方法
  
  //6. 释放资源

如果在每个方法中都写上这些步骤,显得繁琐。因此把重复的代码抽出包装成方法。

@Before注解的方法在 @Test方法执行前执行, @After注解的方法在其之后执行。故正好用于创建 SqlSession和释放资源。(这些注解在junit包中)

package com.chajiu.test;

import com.chajiu.dao.IUserDao;
import com.chajiu.domain.User;
import org.apache.ibatis.io.Resources; //注意Resources导包
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class MybatisTest {
    //将测试方法中需要用到的对象声明为成员变量。
    private InputStream in; //未来要关闭
    private SqlSession session;//未来要关闭
    private IUserDao userDao; //未来要调用接口方法

    @Before//用于在测试方法前执行
    public void init() throws IOException {
        //1. 读取配置文件,生成字节输入流
        in= Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 获取SqlSessionFactory对象
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(in);
        //3. 获取SqlSession对象
        session=factory.openSession();
        //4. 获取dao的代理对象
        userDao=session.getMapper(IUserDao.class);
    }

    @After//用于在测试方法执行后执行
    public void destroy() throws IOException {
        //5.设置手动提交事务
        session.commit();

        //6. 关闭
        session.close();
        in.close();
    }


    
    //查询所有
    @Test
    public void testFindAll(){

        //5. 执行查询所有
        List users=userDao.findAll();
        for (User user:users) {
            System.out.println(user);
        }

    }

    //保存
    @Test
    public void testSaveUser(){
        User user=new User();
        user.setName("mybatis");
        user.setAddress("北京市顺义区");
        user.setSex("男");
        user.setBirthday(new Date());

        System.out.println(user);
        //5. 执行保存
        userDao.saveUser(user);
        System.out.println(user);
    }

    //更新
    @Test
    public void testupdateUser(){
        User user=new User();
        user.setName("mybatis_update");
        user.setAddress("北京市顺义区");
        user.setSex("男");
        user.setBirthday(new Date());
        user.setId(4);

        userDao.updateUser(user);
    }

    //删除
    @Test
    public void testDeleteUser(){
        userDao.deleteUser(5);
    }

    //根据id找user
    @Test
    public void testFindById(){
        User user=userDao.findById(2);
        System.out.println(user);
    }

    //根据名字模糊查询
    @Test
    public void testFindByName(){
        List users=userDao.findByName("%y%");
        for(User user:users){
            System.out.println(user);
        }
    }

    //查询总数
    @Test
    public void testFindTotal(){
        System.out.println(userDao.findTotal());
    }

}


mybatis替我们做了什么

  • 读取xml配置文件
  • 注册驱动
  • 数据库的连接
  • 事务的开启(SqlSession还是要先自己构造出来)
  • 创建dao接口的代理对象(用SqlSession)
  • 封装查询结果到对象中

mybatis参数详解

1. parameterType 输入参数类型

可以传递:

  • 简单参数

  • 自定义pojo类型

    • 使用#{}或者${}指定属性名称=======是的,${}也可以
  • 包装类型

    • 若包装了多个自定义pojo对象,如何访问其中的属性?

      #{value}视为parameterType的类中的属性,有类QueryVo包含User

      public class QueryVo {
          private User user;
          //getter 
          //setter
      }
      
    • 则通过#{user.name}访问user的name属性。即视为拼在输入类型后面。

     
     
    

注意:sql语句中的#{value}value字段必须和实体类中的属性名称对应!!!

OGNL表达式:

  • Object Graphic Navigation Language 对象 图 导航 语言
  • 它是通过对象的取值方法来获取数据,在写法上把get省略了
  • 比如:获取用户名称
    • 类中:user.getUserName()
    • OGNL:user.userName
  • mybatis中为什么不用user.userName,而是直接userName呢?
    • 因为在parameterType中已经指明了属性所属的类,因此不用写对象名

2. resultType 结果类型

  • 输出简单类型

  • 输出pojo对象

    • mybatis如何封装查询结果到pojo呢?

    • 第一种方法:表字段名和pojo属性名对应,自动匹配。不对应的匹配不上为null

    • 第二种方法:表字段名和pojo属性名不对应时,

      • 改sql语句,别的都不用改:

        • 优点:执行效率高
        select id as userId, name as userName, sex as userSex, address as userAddress, birthday as userBirthday from user
        
      • 或者手动配置查询结果字段和实体类属性的映射关系,返回结果改成resultMap

        • 优点:方便开发
          
                
                
                
                
                
                
                
            
            
            
        
  • 输出pojo列表

3. properties

原本properties用于配置连接数据库的四个信息:


                
                
                
                

现在可以用properties标签把property抽出来,原处property标签的value${name}指向上面的property:=======必须用 ${},不可用 #{}


    
    
        
        
        
        
    
    
    
        
            
            
                
                
                
                
                
                
                
            
        
    

    
        
    

所以说,

可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置信息:

  • resource属性:常用

    • 用于指定配置文件的位置,按照类路径的写法写,并必须存在于类路径下
  • url属性:

    • 要求 按照url的写法写位置

    • URL:统一资源定位符,他可以唯一标识一个资源的位置

      写法:http://localhost:8080/mybatis_demo/demoServlet

      ​ 协议 主机 端口 URI

      • URI:统一资源标识符,在应用中唯一定位一个资源
    • 所以使用URL属性可以把配置文件放在任意目录,但是路径写为:

      • file:///C:/Users/Alice/IdeaProjects/jdbcConfig.properties
        
      • 使用协议:file://

      • 端口主机省略,故是file:///

4. typeAliases标签

用于给实体类取别名,方便在parameterTyperesultType中使用,不用再写全限定类名了,这就是为什么String以及基本数据类型不用写全限定类名的原因,他已经默认配好了别名。



        
        
        
        


使用:凡是要指定全限定类名的地方都可以用,比如parameterTyperesultTyperesultMap中的type

5. package 标签

刚才typeAliases中用了package,这样这个包下的类自动有了别名。
在主配置文件的Mappers中,也可以用这个package标签,用于指定dao接口的包,写了这个就不用再写mapperresource以及class了,他会自己去找xml文件,方便开发。

    

            
            
    

你可能感兴趣的:(Mybatis的深入)