mapper配置

代码参考mybatis-demo

1.基于xml配置的映射器的概率

  • cache - 给定命名空间的缓存配置
  • cache-ref - 其他命名空间缓存配置的引用
  • resultMap - 是最复杂也是最强大的元素,用来描述如何从数据库结果集中加载对象
  • sql - 可被其他语句引用的可重用语句块
  • insert - 映射插入语句
  • update
  • delete
  • select

mapper配置最核心的两个要素是:SQL语句和映射规则。
1)sql insert update delete select是写SQL语句
2)resultMap是写映射规则的

2.select元素

mapper配置_第1张图片

2.1 自动映射和手动映射

  • resultType和resultMap只用其中一个
    参考TUserMapper.xml
    

其中BaseResultMap为手动进行映射:

    

        
        
        
        
        
        
        
        
    
  • 自动映射
    前提:SQL列名和JavaBean的属性是一致的
    自动映射等级autoMappingBehavior设置为PARTIAL,谨慎使用FULL
    使用resultType
    如果列名和JavaBean不一致,mapUnderscoreToCamelCase设置为true。(规范命名时使用)

  • 相关的阿里规范说明——使用手动映射


2.2 传递多个查询入参

  • 使用map传递参数:可读性差,导致可维护性和可扩展性差,杜绝使用
  • 使用注解传递参数:直观明了,当参数小于5个时,建议使用
  • 使用Java Bean的方式传递参数:当参数大于5个时,建议使用

参考TUserMapper.java

    List selectByEmailAndSex1(Map param);

    List selectByEmailAndSex2(@Param("email")String email, @Param("sex")Byte sex);

    List selectByEmailAndSex3(EmailSexBean esb);

参考TUserMapper.xml

    

    


    

测试代码参考MybatisDemo.java

    // 多参数查询
    @Test
    public void testManyParamQuery() {
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.获取对应mapper
        TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);

        String email = "qq.com";
        Byte sex = 1;

        // 第一种方式使用map
        Map params = new HashMap();
        params.put("email", email);
        params.put("sex", sex);
        List list1 = mapper.selectByEmailAndSex1(params);
        System.out.println(list1.size());

        // 第二种方式直接使用参数
        List list2 = mapper.selectByEmailAndSex2(email, sex);
        System.out.println(list2.size());

        // 第三种方式用对象
        EmailSexBean esb = new EmailSexBean();
        esb.setEmail(email);
        esb.setSex(sex);
        List list3 = mapper.selectByEmailAndSex3(esb);
        System.out.println(list3.size());
    }

3.resultMap元素

  • 互联网应用中,大多数是用单表查询。因为数据量巨大,实现时是分库分表分布式的。

resultMap是Mybatis中最重要最强大的元素,让你从90%的JDBC ResultSets数据提取代码中解放出来。
设计思想是:简单的语句不需要明确的结果映射,复杂的语句只需要描述它们的关系即可。

    
        
        
        
        
        
        
        
        
        
        
    

3.1 属性

mapper配置_第2张图片

3.2 子元素

3.2.1 id & result

  • id和result都将一个列的值映射到一个简单数据类型的属性或字段;
    区别是,id表示的结果将是对象的标识属性(key主键一样),在比较对象实例时用到。可以提高整体的性能,尤其是缓存和嵌套结果映射(也就是联合映射)的时候。


    mapper配置_第3张图片

3.2.2 constructor

  • 一个pojo不存在没有参数的构造方法,就需要使用construtor
    为了通过名称来引用构造方法参数,可以添加@Param注解,指定参数名称的前提下,以任意顺序编写arg元素。

  
  
  

4.insert、update和delete元素

mapper配置_第4张图片
int insert1(TUser record);
    
        insert into t_user (id, user_name, real_name,
        sex, mobile,
        email,
        note, position_id)
        values (#{id,jdbcType=INTEGER},
        #{userName,jdbcType=VARCHAR},
        #{realName,jdbcType=VARCHAR},
        #{sex,jdbcType=TINYINT}, #{mobile,jdbcType=VARCHAR},
        #{email,jdbcType=VARCHAR},
        #{note,jdbcType=VARCHAR},
        #{positionId,jdbcType=INTEGER})
    `

测试代码:

    @Test
    // 测试插入数据自动生成id
    public void testInsertGenerateId1() throws IOException {
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.获取对应mapper
        TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);
        // 4.执行查询语句并返回结果
        TUser user1 = new TUser();
        user1.setUserName("test1");
        user1.setRealName("realname1");
        user1.setEmail("myemail1");
        mapper.insert1(user1);
        sqlSession.commit();
        System.out.println(user1.getId());
    }

4.1 selectKey元素——无自动增长时使用

mapper配置_第5张图片

对于id,Mysql是在插入之后拿到主键id,Oracle是在插入之前拿到主键id。

int insert2(TUser record);
    
    
        
            select LAST_INSERT_ID()
        
        insert into t_user (id, user_name, real_name,
        sex, mobile,
        email,
        note, position_id)
        values (#{id,jdbcType=INTEGER},
        #{userName,jdbcType=VARCHAR},
        #{realName,jdbcType=VARCHAR},
        #{sex,jdbcType=TINYINT}, #{mobile,jdbcType=VARCHAR},
        #{email,jdbcType=VARCHAR},
        #{note,jdbcType=VARCHAR},
        #{positionId,jdbcType=INTEGER})
    

测试代码:

    @Test
    // 测试插入数据自动生成id
    public void testInsertGenerateId2() throws IOException {
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.获取对应mapper
        TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);
        // 4.执行查询语句并返回结果
        TUser user2 = new TUser();
        user2.setUserName("test2");
        user2.setRealName("realname2");
        user2.setEmail("myemai2l");
        mapper.insert2(user2);
        sqlSession.commit();
        System.out.println(user2.getId());
    }

5.sql元素

    
        id, user_name, real_name, sex, mobile, email, note,
        position_id
    


    

6.参数:向sql语句中传递的可变参数

  • 传值${}:传入的数据直接显式生成在sql中,无法防止sql注入
    直接插入到sql语句中。

  • 预编译#{}:将传入的数据当成一个字符串,会对自动传入的数据加一个单引号,能够很大程序防止sql注入
    使用占位符?表示。

  • 表名、选取的列是动态的,order by和in操作,可以考虑使用$

    

测试程序:

    @Test
    // 参数#和参数$区别测试(动态sql 入门)
    public void testSymbol() {
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.获取对应mapper
        TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);

        String inCol = "id, user_name, real_name, sex, mobile, email, note";
        String tableName = "t_user";
        Byte sex = 1;
        String orderStr = "sex,user_name";

        List list = mapper.selectBySymbol(tableName, inCol, orderStr, sex);
        System.out.println(list.size());

    }

测试结果:

2018-09-24 15:03:30.859 [main] DEBUG c.e.mybatis.mapper.TUserMapper.selectBySymbol - ==>  Preparing: select id, user_name, real_name, sex, mobile, email, note from t_user a where a.sex = ? order by sex,user_name 
2018-09-24 15:03:30.920 [main] DEBUG c.e.mybatis.mapper.TUserMapper.selectBySymbol - ==> Parameters: 1(Byte)
2018-09-24 15:03:30.940 [main] DEBUG c.e.mybatis.mapper.TUserMapper.selectBySymbol - <==      Total: 3

7.注解方式配置

注解方式就是将SQL语句直接写在接口上,对于需求比较简单的系统,效率较高。缺点在于,每次修改sql语句都要编译代码,对于复杂的sql语句可编辑性和可读性都差,一般不建议使用这种配置方式。

  • @Select
    @Results
    @ResultMap
    @Insert
    @Update
    @Delete
public interface TJobHistoryAnnoMapper {

    int deleteByPrimaryKey(Integer id);


    int insertSelective(TJobHistory record);

    TJobHistory selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(TJobHistory record);

    int updateByPrimaryKey(TJobHistory record);


    @Results(id="jobInfo",value={
            @Result(property="id",column="id",id = true),
            @Result(property="userId",column="user_id"),
            @Result(property="compName",column="comp_name"),
            @Result(property="years",column="years"),
            @Result(property="title",column="title")
    })
    @Select("select id, user_id, comp_name, years, title from t_job_history"
            + " where user_id = #{userId}")
    List selectByUserId(int userId);

    @ResultMap("jobInfo")
    @Select("select id, user_id, comp_name, years, title from t_job_history")
    List selectAll();

    @Insert("insert into t_job_history (id, user_id, comp_name, years, title)"
            + " values (#{id,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER},"
            + "#{compName,jdbcType=VARCHAR},"
            + "#{years,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR})")
    @Options(useGeneratedKeys=true,keyProperty="id")
    int insert(TJobHistory record);
}

测试代码

    @Test
    // 注解测试
    public void testAnno() {
        // 2.获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 3.获取对应mapper
        TJobHistoryAnnoMapper mapper = sqlSession.getMapper(TJobHistoryAnnoMapper.class);

        List list = mapper.selectByUserId(1);
        System.out.println(list.size());

        List listAll = mapper.selectAll();
        System.out.println(listAll.size());

        TJobHistory job = new TJobHistory();
        job.setTitle("产品经理");
        job.setUserId(1);
        job.setCompName("美团");
        job.setYears(3);

        mapper.insert(job);
        System.out.println(job.getId());
    }

mapper配置:

    
    
        
         
    

结果:

018-09-24 15:22:50.596 [main] DEBUG c.e.m.mapper.TJobHistoryAnnoMapper.selectByUserId - ==>  Preparing: select id, user_id, comp_name, years, title from t_job_history where user_id = ? 
2018-09-24 15:22:50.636 [main] DEBUG c.e.m.mapper.TJobHistoryAnnoMapper.selectByUserId - ==> Parameters: 1(Integer)
2018-09-24 15:22:50.686 [main] DEBUG c.e.m.mapper.TJobHistoryAnnoMapper.selectByUserId - <==      Total: 1
1
2018-09-24 15:22:50.690 [main] DEBUG c.e.mybatis.mapper.TJobHistoryAnnoMapper.selectAll - ==>  Preparing: select id, user_id, comp_name, years, title from t_job_history 
2018-09-24 15:22:50.693 [main] DEBUG c.e.mybatis.mapper.TJobHistoryAnnoMapper.selectAll - ==> Parameters: 
2018-09-24 15:22:50.696 [main] DEBUG c.e.mybatis.mapper.TJobHistoryAnnoMapper.selectAll - <==      Total: 6
6
2018-09-24 15:22:50.697 [main] DEBUG c.e.mybatis.mapper.TJobHistoryAnnoMapper.insert - ==>  Preparing: insert into t_job_history (id, user_id, comp_name, years, title) values (?, ?,?,?, ?) 
2018-09-24 15:22:50.698 [main] DEBUG c.e.mybatis.mapper.TJobHistoryAnnoMapper.insert - ==> Parameters: null, 1(Integer), 美团(String), 3(Integer), 产品经理(String)
2018-09-24 15:22:50.699 [main] DEBUG c.e.mybatis.mapper.TJobHistoryAnnoMapper.insert - <==    Updates: 1
7

参考

  • 1)享学课堂Lison老师笔记
  • 2)阿里巴巴java开发手册 1.4.0

你可能感兴趣的:(mapper配置)