MyBatis入门

打印 上一主题 下一主题

主题 756|帖子 756|积分 2268

Mybatis

环境

  • JDBC
  • java基础
  • JDK 1.8
  • Mysql5.7
  • maven 3.6.1
  • 开发工具 idea
  • Junit
SSM框架:配置文件的最好方式:看官网文档
1 简介

1.1 什么是Mybatis?


  • MyBatis是一款优秀的持久层框架
  • 支持定制SQL、存储过程以及高级映射
  • Mybatis避免了几乎所有的JDBC代码和手动设置参树,以及获取结果集
  • Mybatis可以使用简单的XML注解来配置和映射原生类型、接口和Java的POJO(Plain Old Java Objects,普通老式Java对象)为数据库中的记录
  • MyBatis本是apache的一个开源项目iBatis
  • 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis
  • 2013年11月迁移到Github
如何获得Mybatis?
1.2 持久化

数据持久化

  • 持久化就是将程序的数据保存在硬盘中
  • 内存特性:断电会失去信息
  • 数据库(jdbc),io文件持久化
  • 生活中的持久化:冷藏,写……
为什么需要持久化?

  • 我们需要将一些数据保存下来,方便以后使用
  • 内存价格过高(制造成本高)
1.3 持久层

复习学习过的层:Dao,Service,Controller
持久层的工作

  • 完成持久化工作的代码块
  • 层之间的接线非常明显
1.4 为什么需要Mybatis?


  • 帮助程序员将数据存入到数据库中
  • 传统的JDBC代码太复杂了
  • 简化、框架、自动化
  • 不用Mybatis也能实现,Mybatis可以使程序员在不知道底层原理的情况下,完成网站后台搭建
  • 优点:

    • 简单易学
    • 灵活
    • 解除sql与程序代码的耦合
    • 提供映射标签,支持对象与数据库的orm字段关系映射
    • 提供对象关系映射标签,支持对象关系组建维护
    • 提供xml标签,支持编写动态sql。

2 第一个MyBatis程序

思路:搭建环境-->导入MyBatis-->编写代码-->测试
2.1 搭建环境


  • 搭建数据库
    1. -- 创建数据库
    2. create database `mybatis`;
    3. use mybatis;
    4. -- 创建表
    5. create table `user`(
    6.         `id` int(20) not null,
    7.         `name` varchar(30) default null,
    8.         `pwd` varchar(30) default null,
    9.         primary key(`id`)
    10. )engine=InnoDB default charset=utf8mb4;
    11. -- 插入数据
    12. insert into `user`(`id`,`name`,`pwd`) values
    13. (1,'千树','123'),
    14. (2,'张三','123'),
    15. (3,'李飞','123');
    复制代码
  • mybatis官方文档:文档地址
  • 新建普通maven项目作为父项目,导入sql驱动,mybatis,junit组件
    1. <dependencies>
    2.    
    3.     <dependency>
    4.         <groupId>mysql</groupId>
    5.         <artifactId>mysql-connector-java</artifactId>
    6.         <version>5.1.46</version>
    7.     </dependency>
    8.    
    9.     <dependency>
    10.         <groupId>org.mybatis</groupId>
    11.         <artifactId>mybatis</artifactId>
    12.         <version>3.5.2</version>
    13.     </dependency>
    14.    
    15.     <dependency>
    16.         <groupId>junit</groupId>
    17.         <artifactId>junit</artifactId>
    18.         <version>4.12</version>
    19.     </dependency>
    20. </dependencies>
    复制代码
  • 新建新组件作为子级项目,普通maven的module
  • 添加配置文件:
    在src->main->resources目录下新建mybatis-config.xml文件,把官方的配置代码复制粘贴(不能在配置文件中写中文注释)
    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE configuration
    3.   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    4.   "http://mybatis.org/dtd/mybatis-3-config.dtd">
    5. <configuration>
    6.   <environments default="development">
    7.     <environment id="development">
    8.       <transactionManager type="JDBC"/>
    9.       <dataSource type="POOLED">
    10.         <property name="driver" value="${driver}"/>//数据库驱动,不同驱动可连接不同数据库服务器
    11.         <property name="url" value="${url}"/>//连接数据库的目录
    12.         <property name="username" value="${username}"/>//数据库名字,默认root
    13.         <property name="password" value="${password}"/>//数据库密码,自己的数据库密码,一般为root
    14.       </dataSource>
    15.     </environment>
    16.   </environments>
    17. </configuration>
    复制代码
    配置文件的作用就是连接数据库
2.2 创建模块


  • 编写mybatis工具类
    1. //SqlSessionFactory --生产--> SqlSession
    2. public class MybatisUtils {
    3.         private static SqlSessionFactory sqlSessionFactory; //提升作用域
    4.         //获取工厂,固定代码
    5.         static {
    6.                 try {
    7.                         String resource="mybatis-config.xml";
    8.                         InputStream inputStream = Resources.getResourceAsStream(resource);
    9.                         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    10.                 } catch (IOException e) {
    11.                         e.printStackTrace();
    12.                 }
    13.         }
    14.         //获取sqlSession
    15.         //SqlSession完全包含了面向对象数据库执行SQL命令所需的方法
    16.         public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession();}
    17. }
    复制代码
2.3 编写代码


  • 实体类
    1. public class User {
    2.         private int id;
    3.         private String name;
    4.         private String pwd;
    5.         public User() { }
    6.         public User(int id, String name, String pwd) {
    7.                 this.id = id;
    8.                 this.name = name;
    9.                 this.pwd = pwd;
    10.         }
    11.         public int getId() {
    12.                 return id;
    13.         }
    14.         public void setId(int id) {
    15.                 this.id = id;
    16.         }
    17.         public String getName() {
    18.                 return name;
    19.         }
    20.         public void setName(String name) {
    21.                 this.name = name;
    22.         }
    23.         public String getPwd() {
    24.                 return pwd;
    25.         }
    26.         public void setPwd(String pwd) {
    27.                 this.pwd = pwd;
    28.         }
    29.         @Override
    30.         public String toString() {
    31.                 return "User{" +
    32.                                 "id=" + id +
    33.                                 ", name='" + name + '\'' +
    34.                                 ", pwd='" + pwd + '\'' +
    35.                                 '}';
    36.         }
    37. }
    复制代码
  • Dao接口
    1. public interface UserDao {
    2.         List<User> getUserList();
    3. }
    复制代码
  • 接口实现类改为以xxxMapper.xml的配置文件
    注意事项:配置文件中不要写中文注释,如果非要写,解决方法见后面的异常解决方案
    1. <?xml version="1.0" encoding="utf-8" ?>
    2. <!DOCTYPE mapper
    3.                 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4.                 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.qian.dao.UserDao">
    6.         <select id="getUserList" resultType="com.qian.pojo.User">
    7.                 select * from mybatis.user where id = #{id}
    8.         </select>
    9. </mapper>
    复制代码
2.4 测试


  • 测试类
    1. public class UserDaoTest {
    2.         @Test
    3.         public void test(){
    4.                 //获取SqlSession对象
    5.                 SqlSession sqlSession = MybatisUtils.getSqlSession();
    6.                 //获取mapper
    7.                 UserDao mapper = sqlSession.getMapper(UserDao.class);
    8.                 List<User> list = mapper.getUserList();
    9.                 for (User u:list){
    10.                         System.out.println(u);
    11.                 }
    12.                 //不推荐使用
    13. /*
    14.         这种方式能够正常工作,对使用旧版本 MyBatis 的用户来说也比较熟悉。但现在有了一种更简洁的方式——使用和指定语句的参数和返回值相匹配的接口(比如 BlogMapper.class),现在你的代码不仅更清晰,更加类型安全,还不用担心可能出错的字符串字面值以及强制类型转换。
    15. */
    16. //        List<User> list = sqlSession.selectList("com.qian.dao.UserDao.getUserList");
    17. //        for (User user : list) {
    18. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    19. @Select("select * from mybatis.user where id=#{id}")
    20. User selectUserById(@Param("id") int id);
    21. @Select("select * from mybatis.user")
    22. List<User> selectAll();
    23. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    24. boolean insertUser(User u);
    25. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    26. boolean updateUser(User u);
    27. @Delete("delete from mybatis.user where id=#{id}")
    28. boolean deleteUser(@Param("id") int id);   System.out.println(user);
    29. //        }
    30.                 //关闭SqlSession
    31.                 sqlSession.close();
    32.         }
    33. }
    复制代码
    异常1:org.apache.ibatis.binding.BindingException: Type interface com.qian.dao.UserDao is not known to the MapperRegistry.
    解决方法:每一个Mapper.xml文件都需要在src->main->resources目录下新建mybatis-config.xml的核心配置文件中  注册
    xml//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    @Select("select * from mybatis.user where id=#{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from mybatis.user")
    List<User> selectAll();

    @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    boolean insertUser(User u);

    @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    boolean updateUser(User u);

    @Delete("delete from mybatis.user where id=#{id}")
    boolean deleteUser(@Param("id") int id);             //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    @Select("select * from mybatis.user where id=#{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from mybatis.user")
    List<User> selectAll();

    @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    boolean insertUser(User u);

    @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    boolean updateUser(User u);

    @Delete("delete from mybatis.user where id=#{id}")
    boolean deleteUser(@Param("id") int id);     
    异常2:               
    Error building SqlSession.       
    The error may exist in com/qian/dao/UserMapper.xml       
    Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration.        
    Cause: java.io.IOException: Could not find resource com/qian/dao/UserMapper.xml
    解决方法:
    xml//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    @Select("select * from mybatis.user where id=#{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from mybatis.user")
    List<User> selectAll();

    @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    boolean insertUser(User u);

    @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    boolean updateUser(User u);

    @Delete("delete from mybatis.user where id=#{id}")
    boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    @Select("select * from mybatis.user where id=#{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from mybatis.user")
    List<User> selectAll();

    @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    boolean insertUser(User u);

    @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    boolean updateUser(User u);

    @Delete("delete from mybatis.user where id=#{id}")
    boolean deleteUser(@Param("id") int id);                                     <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>src/main/resources   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>        **/*.properties   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>        **/*.xml   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>true                                                 <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>src/main/java   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>        **/*.properties   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>        **/*.xml   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>   <typeAliases>
        <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
           
           
            <package name="com.yu.pojo"/>
    </typeAliases>true                                      //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    @Select("select * from mybatis.user where id=#{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from mybatis.user")
    List<User> selectAll();

    @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    boolean insertUser(User u);

    @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    boolean updateUser(User u);

    @Delete("delete from mybatis.user where id=#{id}")
    boolean deleteUser(@Param("id") int id);     
    异常3:       
    Error building SqlSession.       
    The error may exist in com/qian/dao/UserMapper.xml       
    Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration.        
    Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 6;
    解决方法:       
    xml               //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    @Select("select * from mybatis.user where id=#{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from mybatis.user")
    List<User> selectAll();

    @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    boolean insertUser(User u);

    @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    boolean updateUser(User u);

    @Delete("delete from mybatis.user where id=#{id}")
    boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    @Select("select * from mybatis.user where id=#{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from mybatis.user")
    List<User> selectAll();

    @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    boolean insertUser(User u);

    @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    boolean updateUser(User u);

    @Delete("delete from mybatis.user where id=#{id}")
    boolean deleteUser(@Param("id") int id);   
    另一种解决方法:删除掉xxxMapper.xml文件中所有的中文注释
    异常4:
    Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
    解决方法:       
    useSSL=true改为false(true也可以,需要在mysql中启用SSL)
    xml//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    @Select("select * from mybatis.user where id=#{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from mybatis.user")
    List<User> selectAll();

    @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    boolean insertUser(User u);

    @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    boolean updateUser(User u);

    @Delete("delete from mybatis.user where id=#{id}")
    boolean deleteUser(@Param("id") int id);     
2.5 总结

  1. public class UserDaoTest {
  2.     @Test
  3.     public void test(){
  4.         //获取SqlSession对象
  5.         SqlSession sqlSession = MybatisUtils.getSqlSession();
  6.         try{
  7. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  8. @Select("select * from mybatis.user where id=#{id}")
  9. User selectUserById(@Param("id") int id);
  10. @Select("select * from mybatis.user")
  11. List<User> selectAll();
  12. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  13. boolean insertUser(User u);
  14. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  15. boolean updateUser(User u);
  16. @Delete("delete from mybatis.user where id=#{id}")
  17. boolean deleteUser(@Param("id") int id);   //获取mapper
  18. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  19. @Select("select * from mybatis.user where id=#{id}")
  20. User selectUserById(@Param("id") int id);
  21. @Select("select * from mybatis.user")
  22. List<User> selectAll();
  23. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  24. boolean insertUser(User u);
  25. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  26. boolean updateUser(User u);
  27. @Delete("delete from mybatis.user where id=#{id}")
  28. boolean deleteUser(@Param("id") int id);   UserDao mapper = sqlSession.getMapper(UserDao.class);
  29. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  30. @Select("select * from mybatis.user where id=#{id}")
  31. User selectUserById(@Param("id") int id);
  32. @Select("select * from mybatis.user")
  33. List<User> selectAll();
  34. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  35. boolean insertUser(User u);
  36. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  37. boolean updateUser(User u);
  38. @Delete("delete from mybatis.user where id=#{id}")
  39. boolean deleteUser(@Param("id") int id);   List<User> list = mapper.getUserList();
  40. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  41. @Select("select * from mybatis.user where id=#{id}")
  42. User selectUserById(@Param("id") int id);
  43. @Select("select * from mybatis.user")
  44. List<User> selectAll();
  45. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  46. boolean insertUser(User u);
  47. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  48. boolean updateUser(User u);
  49. @Delete("delete from mybatis.user where id=#{id}")
  50. boolean deleteUser(@Param("id") int id);   for (User u:list){
  51. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  52. @Select("select * from mybatis.user where id=#{id}")
  53. User selectUserById(@Param("id") int id);
  54. @Select("select * from mybatis.user")
  55. List<User> selectAll();
  56. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  57. boolean insertUser(User u);
  58. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  59. boolean updateUser(User u);
  60. @Delete("delete from mybatis.user where id=#{id}")
  61. boolean deleteUser(@Param("id") int id);       System.out.println(u);
  62. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  63. @Select("select * from mybatis.user where id=#{id}")
  64. User selectUserById(@Param("id") int id);
  65. @Select("select * from mybatis.user")
  66. List<User> selectAll();
  67. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  68. boolean insertUser(User u);
  69. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  70. boolean updateUser(User u);
  71. @Delete("delete from mybatis.user where id=#{id}")
  72. boolean deleteUser(@Param("id") int id);   }
  73. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  74. @Select("select * from mybatis.user where id=#{id}")
  75. User selectUserById(@Param("id") int id);
  76. @Select("select * from mybatis.user")
  77. List<User> selectAll();
  78. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  79. boolean insertUser(User u);
  80. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  81. boolean updateUser(User u);
  82. @Delete("delete from mybatis.user where id=#{id}")
  83. boolean deleteUser(@Param("id") int id);   //不推荐使用
  84. //        List<User> list = sqlSession.selectList("com.qian.dao.UserDao.getUserList");
  85. //        for (User user : list) {
  86. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  87. @Select("select * from mybatis.user where id=#{id}")
  88. User selectUserById(@Param("id") int id);
  89. @Select("select * from mybatis.user")
  90. List<User> selectAll();
  91. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  92. boolean insertUser(User u);
  93. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  94. boolean updateUser(User u);
  95. @Delete("delete from mybatis.user where id=#{id}")
  96. boolean deleteUser(@Param("id") int id);   System.out.println(user);
  97. //        }
  98.         }finally {
  99. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  100. @Select("select * from mybatis.user where id=#{id}")
  101. User selectUserById(@Param("id") int id);
  102. @Select("select * from mybatis.user")
  103. List<User> selectAll();
  104. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  105. boolean insertUser(User u);
  106. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  107. boolean updateUser(User u);
  108. @Delete("delete from mybatis.user where id=#{id}")
  109. boolean deleteUser(@Param("id") int id);   //关闭SqlSession
  110. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  111. @Select("select * from mybatis.user where id=#{id}")
  112. User selectUserById(@Param("id") int id);
  113. @Select("select * from mybatis.user")
  114. List<User> selectAll();
  115. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  116. boolean insertUser(User u);
  117. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  118. boolean updateUser(User u);
  119. @Delete("delete from mybatis.user where id=#{id}")
  120. boolean deleteUser(@Param("id") int id);   sqlSession.close();
  121.         }
  122.     }
  123. }
复制代码
3 增删改查实现

3.1 Mapper接口
  1. public interface UserMapper {
  2.     //查询全部用户
  3.     List<User> getUserList();
  4.     //根据id查询用户
  5.     <select id="queryBlogIf" parameterType="map" resultType="Blog">
  6.     select * from mybatis.blog where 1=1
  7.     <if test="title!=null">
  8.         and title = #{title}
  9.     </if>
  10.     <if test="author!=null">
  11.         and author = #{author}
  12.     </if>
  13. </select>
  14.     //增加新的用户
  15.     boolean insertNewUser(User u);
  16.     //删除用户
  17.     boolean deleteUserById(int id);
  18.     boolean deleteUserByName(String name);
  19.     //修改用户
  20.     boolean updateUserById(User u);
  21. }
复制代码
3.2 xxxMapper.xml文件
  1. <?xml version="1.0" encoding="utf8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.qian.dao.UserMapper">
  6.     <select id="getUserList" resultType="com.qian.pojo.User">
  7.         select * from mybatis.user
  8.     </select>
  9.     <select id="getUserById" parameterType="int" resultType="com.qian.pojo.User">
  10.     @Test
  11. public void queryBlogIf(){
  12.     SqlSession sqlSession = MybatisUtils.getSqlSession();
  13.     BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
  14.     Map<String,Object> map=new HashMap<String,Object>();
  15.     mapper.queryBlogIf(map);
  16.     System.out.println("==================");
  17.     map.put("title",(String)"MyBatis如此简单");
  18.     mapper.queryBlogIf(map);
  19.     System.out.println("==================");
  20.     map.put("author",(String)"狂神说");
  21.     mapper.queryBlogIf(map);
  22.     System.out.println("==================");
  23.     sqlSession.close();
  24. }
  25.     </select>
  26.    
  27.     <insert id="insertNewUser" parameterType="com.qian.pojo.User">
  28.         insert into mybatis.user (id, name, pwd) VALUES (#{id},#{name},#{pwd})
  29.     </insert>
  30.     <delete id="deleteUserById" parameterType="int">
  31.         delete from mybatis.user where id=#{id}
  32.     </delete>
  33.     <delete id="deleteUserByName" parameterType="String">
  34.         delete from mybatis.user where name=#{name}
  35.     </delete>
  36.     <update id="updateUserById" parameterType="com.qian.pojo.User">
  37.         update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
  38.     </update>
  39. </mapper>
复制代码
3.3 Test类

注意:增删改要提交事务!!!
  1. public class UserDaoTest {
  2.     @Test
  3.     public void test(){
  4.         //获取SqlSession对象
  5.         SqlSession sqlSession = MybatisUtils.getSqlSession();
  6.         try{
  7. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  8. @Select("select * from mybatis.user where id=#{id}")
  9. User selectUserById(@Param("id") int id);
  10. @Select("select * from mybatis.user")
  11. List<User> selectAll();
  12. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  13. boolean insertUser(User u);
  14. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  15. boolean updateUser(User u);
  16. @Delete("delete from mybatis.user where id=#{id}")
  17. boolean deleteUser(@Param("id") int id);   //获取mapper
  18. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  19. @Select("select * from mybatis.user where id=#{id}")
  20. User selectUserById(@Param("id") int id);
  21. @Select("select * from mybatis.user")
  22. List<User> selectAll();
  23. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  24. boolean insertUser(User u);
  25. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  26. boolean updateUser(User u);
  27. @Delete("delete from mybatis.user where id=#{id}")
  28. boolean deleteUser(@Param("id") int id);   UserMapper mapper = sqlSession.getMapper(UserMapper.class);
  29. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  30. @Select("select * from mybatis.user where id=#{id}")
  31. User selectUserById(@Param("id") int id);
  32. @Select("select * from mybatis.user")
  33. List<User> selectAll();
  34. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  35. boolean insertUser(User u);
  36. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  37. boolean updateUser(User u);
  38. @Delete("delete from mybatis.user where id=#{id}")
  39. boolean deleteUser(@Param("id") int id);   查询全表
  40. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  41. @Select("select * from mybatis.user where id=#{id}")
  42. User selectUserById(@Param("id") int id);
  43. @Select("select * from mybatis.user")
  44. List<User> selectAll();
  45. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  46. boolean insertUser(User u);
  47. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  48. boolean updateUser(User u);
  49. @Delete("delete from mybatis.user where id=#{id}")
  50. boolean deleteUser(@Param("id") int id);   List<User> list = mapper.getUserList();
  51. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  52. @Select("select * from mybatis.user where id=#{id}")
  53. User selectUserById(@Param("id") int id);
  54. @Select("select * from mybatis.user")
  55. List<User> selectAll();
  56. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  57. boolean insertUser(User u);
  58. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  59. boolean updateUser(User u);
  60. @Delete("delete from mybatis.user where id=#{id}")
  61. boolean deleteUser(@Param("id") int id);   for (User u:list){
  62. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  63. @Select("select * from mybatis.user where id=#{id}")
  64. User selectUserById(@Param("id") int id);
  65. @Select("select * from mybatis.user")
  66. List<User> selectAll();
  67. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  68. boolean insertUser(User u);
  69. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  70. boolean updateUser(User u);
  71. @Delete("delete from mybatis.user where id=#{id}")
  72. boolean deleteUser(@Param("id") int id);       System.out.println(u);
  73. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  74. @Select("select * from mybatis.user where id=#{id}")
  75. User selectUserById(@Param("id") int id);
  76. @Select("select * from mybatis.user")
  77. List<User> selectAll();
  78. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  79. boolean insertUser(User u);
  80. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  81. boolean updateUser(User u);
  82. @Delete("delete from mybatis.user where id=#{id}")
  83. boolean deleteUser(@Param("id") int id);   }
  84. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  85. @Select("select * from mybatis.user where id=#{id}")
  86. User selectUserById(@Param("id") int id);
  87. @Select("select * from mybatis.user")
  88. List<User> selectAll();
  89. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  90. boolean insertUser(User u);
  91. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  92. boolean updateUser(User u);
  93. @Delete("delete from mybatis.user where id=#{id}")
  94. boolean deleteUser(@Param("id") int id);   //根据id查询
  95. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  96. @Select("select * from mybatis.user where id=#{id}")
  97. User selectUserById(@Param("id") int id);
  98. @Select("select * from mybatis.user")
  99. List<User> selectAll();
  100. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  101. boolean insertUser(User u);
  102. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  103. boolean updateUser(User u);
  104. @Delete("delete from mybatis.user where id=#{id}")
  105. boolean deleteUser(@Param("id") int id);   User user = mapper.getUserById(1);
  106. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  107. @Select("select * from mybatis.user where id=#{id}")
  108. User selectUserById(@Param("id") int id);
  109. @Select("select * from mybatis.user")
  110. List<User> selectAll();
  111. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  112. boolean insertUser(User u);
  113. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  114. boolean updateUser(User u);
  115. @Delete("delete from mybatis.user where id=#{id}")
  116. boolean deleteUser(@Param("id") int id);   System.out.println(user);
  117. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  118. @Select("select * from mybatis.user where id=#{id}")
  119. User selectUserById(@Param("id") int id);
  120. @Select("select * from mybatis.user")
  121. List<User> selectAll();
  122. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  123. boolean insertUser(User u);
  124. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  125. boolean updateUser(User u);
  126. @Delete("delete from mybatis.user where id=#{id}")
  127. boolean deleteUser(@Param("id") int id);   //插入新用户,注意:更新,插入,删除都需要提交事务
  128. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  129. @Select("select * from mybatis.user where id=#{id}")
  130. User selectUserById(@Param("id") int id);
  131. @Select("select * from mybatis.user")
  132. List<User> selectAll();
  133. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  134. boolean insertUser(User u);
  135. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  136. boolean updateUser(User u);
  137. @Delete("delete from mybatis.user where id=#{id}")
  138. boolean deleteUser(@Param("id") int id);   User user1 = new User(4,"李四","25615");
  139. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  140. @Select("select * from mybatis.user where id=#{id}")
  141. User selectUserById(@Param("id") int id);
  142. @Select("select * from mybatis.user")
  143. List<User> selectAll();
  144. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  145. boolean insertUser(User u);
  146. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  147. boolean updateUser(User u);
  148. @Delete("delete from mybatis.user where id=#{id}")
  149. boolean deleteUser(@Param("id") int id);   boolean isInserted = mapper.insertNewUser(user1);
  150. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  151. @Select("select * from mybatis.user where id=#{id}")
  152. User selectUserById(@Param("id") int id);
  153. @Select("select * from mybatis.user")
  154. List<User> selectAll();
  155. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  156. boolean insertUser(User u);
  157. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  158. boolean updateUser(User u);
  159. @Delete("delete from mybatis.user where id=#{id}")
  160. boolean deleteUser(@Param("id") int id);   sqlSession.commit();
  161. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  162. @Select("select * from mybatis.user where id=#{id}")
  163. User selectUserById(@Param("id") int id);
  164. @Select("select * from mybatis.user")
  165. List<User> selectAll();
  166. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  167. boolean insertUser(User u);
  168. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  169. boolean updateUser(User u);
  170. @Delete("delete from mybatis.user where id=#{id}")
  171. boolean deleteUser(@Param("id") int id);   //代码优化
  172. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  173. @Select("select * from mybatis.user where id=#{id}")
  174. User selectUserById(@Param("id") int id);
  175. @Select("select * from mybatis.user")
  176. List<User> selectAll();
  177. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  178. boolean insertUser(User u);
  179. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  180. boolean updateUser(User u);
  181. @Delete("delete from mybatis.user where id=#{id}")
  182. boolean deleteUser(@Param("id") int id);   if (mapper.insertNewUser(new User(4,"李四","25615"))) sqlSession.commit();
  183. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  184. @Select("select * from mybatis.user where id=#{id}")
  185. User selectUserById(@Param("id") int id);
  186. @Select("select * from mybatis.user")
  187. List<User> selectAll();
  188. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  189. boolean insertUser(User u);
  190. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  191. boolean updateUser(User u);
  192. @Delete("delete from mybatis.user where id=#{id}")
  193. boolean deleteUser(@Param("id") int id);   //删除用户
  194. ////多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  195. @Select("select * from mybatis.user where id=#{id}")
  196. User selectUserById(@Param("id") int id);
  197. @Select("select * from mybatis.user")
  198. List<User> selectAll();
  199. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  200. boolean insertUser(User u);
  201. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  202. boolean updateUser(User u);
  203. @Delete("delete from mybatis.user where id=#{id}")
  204. boolean deleteUser(@Param("id") int id);   if (mapper.deleteUserById(4))sqlSession.commit();
  205. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  206. @Select("select * from mybatis.user where id=#{id}")
  207. User selectUserById(@Param("id") int id);
  208. @Select("select * from mybatis.user")
  209. List<User> selectAll();
  210. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  211. boolean insertUser(User u);
  212. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  213. boolean updateUser(User u);
  214. @Delete("delete from mybatis.user where id=#{id}")
  215. boolean deleteUser(@Param("id") int id);    if (mapper.deleteUserByName("李四"))sqlSession.commit();
  216. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  217. @Select("select * from mybatis.user where id=#{id}")
  218. User selectUserById(@Param("id") int id);
  219. @Select("select * from mybatis.user")
  220. List<User> selectAll();
  221. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  222. boolean insertUser(User u);
  223. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  224. boolean updateUser(User u);
  225. @Delete("delete from mybatis.user where id=#{id}")
  226. boolean deleteUser(@Param("id") int id);    //修改用户
  227. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  228. @Select("select * from mybatis.user where id=#{id}")
  229. User selectUserById(@Param("id") int id);
  230. @Select("select * from mybatis.user")
  231. List<User> selectAll();
  232. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  233. boolean insertUser(User u);
  234. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  235. boolean updateUser(User u);
  236. @Delete("delete from mybatis.user where id=#{id}")
  237. boolean deleteUser(@Param("id") int id);   if (mapper.updateUserById(new User(4,"王五","6849816")))sqlSession.commit();
  238.         }finally {
  239. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  240. @Select("select * from mybatis.user where id=#{id}")
  241. User selectUserById(@Param("id") int id);
  242. @Select("select * from mybatis.user")
  243. List<User> selectAll();
  244. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  245. boolean insertUser(User u);
  246. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  247. boolean updateUser(User u);
  248. @Delete("delete from mybatis.user where id=#{id}")
  249. boolean deleteUser(@Param("id") int id);   //关闭SqlSession
  250. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
  251. @Select("select * from mybatis.user where id=#{id}")
  252. User selectUserById(@Param("id") int id);
  253. @Select("select * from mybatis.user")
  254. List<User> selectAll();
  255. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
  256. boolean insertUser(User u);
  257. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
  258. boolean updateUser(User u);
  259. @Delete("delete from mybatis.user where id=#{id}")
  260. boolean deleteUser(@Param("id") int id);   sqlSession.close();
  261.         }
  262.     }
  263. }
复制代码
3.4 常见错误


  • 标签要匹配
  • resource绑定Mapper,需要使用路径
  • 配置文件中不要写注释
  • useSSL=true有时候无法使用,改为false
3.5 万能Map


  • UserMapper.java
    1. User getUser(Map<String,Object> map);
    2. boolean addUser(Map<String,Object> map);
    复制代码
  • UserMapper.xml
    1. <select id="getUser" parameterType="map" resultType="com.qian.pojo.User">
    2.     select * from mybatis.user where id=#{userId}
    3. </select>
    4. <insert id="addUser" parameterType="map">
    5.     insert into mybatis.user (id, name, pwd) VALUES (#{userId},#{userName},#{password})
    6. </insert>
    复制代码
  • Test.java
    1. @Test
    2. public void test(){
    3.     //获取SqlSession对象
    4.     SqlSession sqlSession = MybatisUtils.getSqlSession();
    5.     UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    6.        
    7.         Map<String, Object> map = new HashMap<String, Object>();
    8.         map.put("userId",5);
    9.         User user = mapper.getUser(map);
    10.         System.out.println(user);
    11.         map.put("userId",5);
    12.         map.put("userName","孙悟空");
    13.         map.put("password","565464");
    14.         if (mapper.addUser(map)) sqlSession.commit();
    15.        
    16.         sqlSession.close();
    17. }
    复制代码
3.6 模糊查询


  • java执行的时候,传递通配符% %
  • UserMapper.java
    1. //模糊查询
    2. List<User> getUsersLike(String value);
    复制代码
  • UserMapper.xml
    1. <select id="getUsersLike" resultType="com.qian.pojo.User">
    2.     select * from mybatis.user where name like #{value};
    3. </select>
    复制代码
  • Test.java
    1. @Test
    2. public void getUsersLike(){
    3.     UserMapper mapper = getUserMapper();
    4.     List<User> userList = mapper.getUsersLike("%千%");
    5.     System.out.println(userList);
    6. }
    7. public UserMapper getUserMapper(){
    8.     return MybatisUtils.getSqlSession().getMapper(UserMapper.class);
    9. }
    复制代码
  • 在sql中使用拼接符
    1. <select id="getUsersLike" resultType="com.qian.pojo.User">
    2.     select * from mybatis.user where name like "%"#{value}"%"
    3. </select>
    复制代码
4 配置解析

4.1 核心配合文件


  • mybatis-config.xml
  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
    1. configuration(配置)
    2. properties(属性)
    3. settings(设置)
    4. typeAliases(类型别名)
    5. environments(环境配置)
    6.         environment(环境变量)
    7.                 transactionManager(事务管理器)
    8.                 dataSource(数据源)你
    9. mappers(映射器)
    复制代码
4.2 环境配置(environments)

MyBatis 可以配置成适应多种环境,尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
MyBatis默认事务连接器就是JDBC,连接池POOLED

  • 数据源(dataSource)       
    作用:连接数据库       
    c3p0 druid dbcp       
    大多数 MyBatis 应用程序会按示例中的例子来配置数据源。虽然数据源配置是可选的,但如果要启用延迟加载特性,就必须配置数据源。       
    有三种内建的数据源类型(也就是 type="[UNPOOLED|POOLED|JNDI]"):
4.3 属性(properties)

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。

  • 配置db.properties
    1. driver=com.mysql.jdbc.Driver
    2. url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&;useUnicode=true&;
    3. characterEncoding=UTF8&;serverTimezone=GMT%2B8&;autoConnect=true
    4. username=root
    5. password=root
    复制代码
  • 在核心配置文件中引入
    注意:在xml中,所有的标签都可以规定顺序
    1. (properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".
    复制代码
  • 核心文件配置
    1. <configuration>
    2.         <properties resource="db.properties"/>
    3.         <environments default="development">
    4.                 <environment id="development">
    5.                         <transactionManager type="JDBC"></transactionManager>
    6.                         <dataSource type="POOLED">
    7.                                 <property name="driver" value="${driver}"/>
    8.                                 <property name="url" value="${url}"/>
    9.                                 <property name="username" value="${username}"/>
    10.                                 <property name="password" value="${password}"/>
    11.                         </dataSource>
    12.                 </environment>
    13. </configuration>
    复制代码
  • 总结

    • 可以直接引入外部文件
    • 也可以在里面配置
    • 外部引入的文件(db.properties)的优先级要比在要高

  • 错误提示

4.4 类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

  • 在mybatis-config.xml -> 配置
    1. <typeAliases>
    2.     <typeAlias type="com.yu.pojo.User" alias="user"></typeAlias>
    3.        
    4.        
    5.         <package name="com.yu.pojo"/>
    6. </typeAliases>
    复制代码
  • 然后xxxMapper.xml的返回值(resultType)就可以替换为resultType user
  • 实体类较少的时候使用第一种,较多就直接扫描包目录
  • 第二种也可以用注解@Alias("xxx")给类起别名
4.5 设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

  • 需要掌握的设置


4.6 映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件

  • 几种绑定方式

  • class与扫描包(packaaage)绑定的注意点

    • 接口和Mapper配置文件必须同名
    • 接口和他的Mapper配置文件必须在同一包下


4.7 其他配置


  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)

4.8 生命周期和作用域(Scope)

理解我们之前讨论过的不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。
SqlSessionFactoryBuilder

  • 局部变量:一旦创建了 SqlSessionFactory,就不再需要它了。
SqlSessionFactory

  • 全局变量:一旦被创建就应该在应用的运行期间一直存在,可以想象为数据库连接池,没有任何理由丢弃它或重新创建另一个实例。
  • 因此 SqlSessionFactory 的最佳作用域是应用作用域,最简单的就是使用单例模式或者静态单例模式。
SqlSession

  • 连接到连接池的一个请求
  • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
  • 用完之后需要关闭
  • 每一个Mapper代表一个具体的业务
5 解决属性名和字段名不一致

5.1 新建项目mybatis-03


  • 复制原文件到对应目录下,修改属性(ctrl+r)pwd->password

  • 使用测试类测试

  • UserMapper.xml
    1. <mapper namespace="com.yu.dao.UserMapper">
    2.         <select id="getUserById" parameterType="int" resultType="user">
    3.                 select * from mybatis.user where id=#{id}
    4.                
    5.         </select>
    6. </mapper>
    复制代码
5.2 解决方法


  • 起别名
    1. select id,name,pwd as password from mybatis.user where id=#{id}
    复制代码
  • 使用resultMap
    resultMap:结果集映射
    1. <resultMap id="UserMap" type="user">
    2. /*<result column="id" property="id"/>
    3.     <result column="name" property="name"/> */
    4.     <result column="pwd" property="password"/>
    5. </resultMap>
    6. <select id="getUserById" parameterType="int" resultMap="UserMap">
    7. @Test
    8. public void queryBlogIf(){
    9.     SqlSession sqlSession = MybatisUtils.getSqlSession();
    10.     BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    11.     Map<String,Object> map=new HashMap<String,Object>();
    12.     mapper.queryBlogIf(map);
    13.     System.out.println("==================");
    14.     map.put("title",(String)"MyBatis如此简单");
    15.     mapper.queryBlogIf(map);
    16.     System.out.println("==================");
    17.     map.put("author",(String)"狂神说");
    18.     mapper.queryBlogIf(map);
    19.     System.out.println("==================");
    20.     sqlSession.close();
    21. }
    22. </select>
    复制代码
    ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
    ResultMap 的优秀之处——你完全可以不用显式地配置它们。 虽然上面的例子不用显式配置 ResultMap。 但为了讲解,我们来看看如果在刚刚的示例中,显式使用外部的 resultMap 会怎样,这也是解决列名不匹配的另外一种方式。
6 日志

6.1 日志工厂

如果数据库操作出现异常,需要通过日志获取sql语句,方便纠错。

  • logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。

    • SLF4J +
    • LOG4J 【掌握】
    • | LOG4J2
    • | JDK_LOGGING
    • | COMMONS_LOGGING
    • | STDOUT_LOGGING 【掌握】
    • | NO_LOGGING

  • 在mybatis-config.xml中配置设置
    STDOUT_LOGGING 标准日志输出
    1. <configuration>
    2.         <properties resource="db.properties"/>
    3.         <settings>
    4.                 <setting name="logImpl" value="STDOUT_LOGGING"/>
    5.         </settings>
    6.         ... ...
    7. <configuration>
    复制代码
6.2 测试输出

<ul>STDOUT_LOGGING
  1. Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
  2. /*
  3.         ...
  4. */
  5. Created connection 471579726.
  6. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1c1bbc4e]
  7. ==>  Preparing: select * from mybatis.user where id=?
  8. ==> Parameters: 1(Integer)
  9. <==    Columns: id, name, pwd
  10. <==        Row: 1, 千树, 123
  11. <==      Total: 1
  12. User{id=1, name='千树', password='123'}
  13. Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1c1bbc4e]
  14. Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1c1bbc4e]
  15. Returned connection 471579726 to pool.
复制代码
  1. ......
  2. Caused by: org.apache.ibatis.exceptions.PersistenceException:
  3. ### Error building SqlSession.
  4. ### The error may exist in SQL Mapper Configuration
  5. ### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.logging.LogException: Error setting Log implementation.
  6. ......
  7. Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.logging.LogException: Error setting Log implementation.  Cause: java.lang.NoClassDefFoundError: org/apache/log4j/Priority
  8. ...
复制代码
  1. <dependency>
  2.     <groupId>log4j</groupId>
  3.     <artifactId>log4j</artifactId>
  4.     <version>1.2.17</version>
  5. </dependency>
复制代码
  1. log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).
  2. log4j:WARN Please initialize the log4j system properly.
  3. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
  4. User{id=1, name='千树', password='123'}
复制代码
  1. #newhappy  log4j.properties start
  2. log4j.rootLogger=DEBUG,console,file
  3. #控制台输出 console appender
  4. log4j.appender.console=org.apache.log4j.ConsoleAppender
  5. log4j.appender.console.Target=System.out
  6. log4j.appender.console.threshold=DEBUG
  7. log4j.appender.console.layout=org.apache.log4j.PatternLayout
  8. log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
  9. #文件输出 rolling file appender
  10. log4j.appender.file=org.apache.log4j.RollingFileAppender
  11. log4j.appender.file.File=./log/yu.log
  12. log4j.appender.file.MaxFileSize=10mB
  13. log4j.appender.file.MaxBackupIndex=2
  14. log4j.appender.file.layout=org.apache.log4j.PatternLayout
  15. log4j.appender.file.layout.ConversionPattern=%d{mmm d,yyyy hh:mm:ss a} : %p [%t] %m%n
  16. log4j.appender.file.threshold=DEBUG
  17. #日志输出级别 logger
  18. log4j.logger.org.mybatis=DEBUG
  19. log4j.logger.java.sql=DEBUG
  20. log4j.logger.java.sql.Statement=DEBUG
  21. log4j.logger.java.sql.ResultSet=DEBUG
  22. log4j.logger.java.sql.PreparedStatement=DEBUG
  23. #newhappy log4j.properties end
复制代码
11.3按照结果嵌套处理


  • 代码演示
    1. public class UserDaoTest {
    2.         static Logger logger = Logger.getLogger(UserDaoTest.class);
    3.         @Test
    4.         public void loggerTest(){
    5.                 logger.info("info:进入了TestLog4j");
    6.                 logger.debug("debug:调试");
    7.                 logger.error("error:错误");
    8.                 logger.fatal("fatal:致命错误");
    9.         }
    10. }
    复制代码
    1. -- 语法:select * from xxx limit startIndex,pageSize
    2. select * from user limit 3;
    复制代码
    1. List<User> selectLimit(Map<String,Integer> map);
    复制代码
11.4 回顾Mysql多对一查询方式


  • 子查询
  • 联表查询
11.5 一对多的处理


  • 代码演示
    1. <select id="selectLimit" parameterType="map" resultMap="UserMap">
    2.     select * from mybatis.user limit #{startIndex},#{pageSize}
    3. </select>
    复制代码
    1. public class UserDaoTest {
    2.         @Test
    3.         public void limitTest(){
    4.                 SqlSession sqlSession = MybatisUtils.getSqlSession();
    5.                 UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    6.                 Map<String, Integer> map = new HashMap<String, Integer>();
    7.                 map.put("startIndex",0);
    8.                 map.put("pageSize",2);
    9.                 List<User> list=mapper.selectLimit(map);
    10.                 for (User u:
    11.                          list) {
    12.                         System.out.println(u);
    13.                 }
    14.                 sqlSession.close();
    15.         }
    16. }
    复制代码
    1. public interface TeacherMapper {        <dependency>
    2.     <groupId>log4j</groupId>
    3.     <artifactId>log4j</artifactId>
    4.     <version>1.2.17</version>
    5. </dependency>        //获取指定老师下的所有学生        Teacher getTeacher(@Param("tid")int id);        Teacher getTeacher2(@Param("tid")int id);        List getStudents(@Param("tid")int id);}
    复制代码
    1. <select id="selectRowBounds" resultMap="UserMap">
    2.     select * from mybatis.user
    3. </select>
    复制代码
    1. @Test
    2. public void selectRowBounds(){
    3.     SqlSession sqlSession = MybatisUtils.getSqlSession();
    4.     RowBounds rowBounds = new RowBounds(0,2);
    5.     List<User> list = sqlSession.selectList("com.yu.dao.UserMapper.selectRowBounds"
    6.     ,null,rowBounds);
    7.     for (User user : list) {
    8.         System.out.println(user);
    9.     }
    10.     sqlSession.close();
    11. }
    复制代码
11.6 小结


  • 关联 association 多对一
  • 集合 collection  一对多
  • javaType 指定实体类中属性的类型
  • ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型
注意点:

  • 保证sql语句的可读性
  • 注意一对多和多对一属性和字段的问题
  • 面试要点

    • Mysql引擎
    • InnoDB底层原理
    • 索引
    • 索引优化

12 动态SQL

什么是动态SQL?
动态SQL是指根据不同的条件生成不同的SQL语句
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach
12.1 搭建环境


  • 搭建数据库
    1. @Select("select * from mybatis.user")
    2. List<User> selectAll();
    复制代码
创建基础工程

  • 导包
  • 编写配置文件
  • 编写实体类日
    1. <mappers>
    2.     <mapper />
    3. </mappers>
    复制代码
  • 编写实体类对应Mapper接口和Mapper.xml文件
    1. @Test
    2. public void selectAll(){
    3.     SqlSession sqlSession = MybatisUtils.getSqlSession();
    4.     //底层主要应用反射
    5.     UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    6.     List<User> list=mapper.selectAll();
    7.     for (User user : list) {
    8.         System.out.println(user);
    9.     }
    10.     sqlSession.close();
    11. }       
    复制代码
    1. [/code]
    2. [*]解决数据库字段名和实体类属性名不一致的问题[code]//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    3. @Select("select * from mybatis.user where id=#{id}")
    4. User selectUserById(@Param("id") int id);
    5. @Select("select * from mybatis.user")
    6. List<User> selectAll();
    7. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    8. boolean insertUser(User u);
    9. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    10. boolean updateUser(User u);
    11. @Delete("delete from mybatis.user where id=#{id}")
    12. boolean deleteUser(@Param("id") int id);
    复制代码
12.2 if


  • 使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如:
    1. @Test
    2. public void selectAll(){
    3.         SqlSession sqlSession = MybatisUtils.getSqlSession();
    4.         //底层主要应用反射
    5.         UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    6.   //        List<User> list=mapper.selectAll();
    7.   //        for (User user : list) {
    8.   //            System.out.println(user);
    9.   //        }
    10.   /**
    11.                   User u=mapper.selectUserById(1);
    12.                   System.out.println(u);
    13.    */
    14.   //        boolean isInserted=mapper.insertUser(new User(4,"图拉真","dgsdgs"));
    15.   //       if (mapper.updateUser(new User(6,"寒江雪",null)))
    16.         if (mapper.deleteUser(6))
    17.         for (User user : mapper.selectAll()) {
    18.                 System.out.println(user);
    19.         }
    20.         sqlSession.close();
    21. }
    复制代码
  • 代码演示
    1. <dependency>
    2.         <groupId>org.projectlombok</groupId>
    3.         <artifactId>lombok</artifactId>
    4.         <version>1.18.10</version>
    5. </dependency>
    复制代码
    1.     select * from mybatis.blog where 1=1//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    2. @Select("select * from mybatis.user where id=#{id}")
    3. User selectUserById(@Param("id") int id);
    4. @Select("select * from mybatis.user")
    5. List<User> selectAll();
    6. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    7. boolean insertUser(User u);
    8. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    9. boolean updateUser(User u);
    10. @Delete("delete from mybatis.user where id=#{id}")
    11. boolean deleteUser(@Param("id") int id);   and title = #{title}//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    12. @Select("select * from mybatis.user where id=#{id}")
    13. User selectUserById(@Param("id") int id);
    14. @Select("select * from mybatis.user")
    15. List<User> selectAll();
    16. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    17. boolean insertUser(User u);
    18. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    19. boolean updateUser(User u);
    20. @Delete("delete from mybatis.user where id=#{id}")
    21. boolean deleteUser(@Param("id") int id);       and author = #{author}   
    复制代码
    1. @Data支持: 无参构造,getter&setter,toString,hashCode,equals
    2. @AllArgsConstructor: 有参构造
    3. @NoArgsConstructor: 无参构造
    复制代码
12.3 choose、when、otherwise


  • 有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
  • 还是上面的例子,但是策略变为:传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG(这可能是管理员认为,与其返回大量的无意义随机 Blog,还不如返回一些由管理员挑选的 Blog)。
    1. create table `teacher`(
    2. `id` int not null,
    3. `name` varchar(30) default null,
    4. primary key(`id`)
    5. ) engine=InnoDB default charset=utf8;
    6. insert into teacher values (1,'王老师');
    7. create table `student`(
    8. `id` int not null,
    9. `name` varchar(30) default null,
    10. `tid` int not null,
    11. primary key(`id`),
    12. key `FK_tid` (`tid`),
    13. constraint `FK_tid` foreign key(`tid`) references `teacher`(`id`)
    14. ) engine=InnoDB default charset=utf8;
    复制代码
  • 代码演示
    1. @Data
    2. @AllArgsConstructor
    3. @NoArgsConstructor
    4. public class Student {
    5.         private int id;
    6.         private String name;
    7.         private Teacher teacher;
    8. }
    复制代码
    1.     select * from mybatis.blog//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    2. @Select("select * from mybatis.user where id=#{id}")
    3. User selectUserById(@Param("id") int id);
    4. @Select("select * from mybatis.user")
    5. List<User> selectAll();
    6. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    7. boolean insertUser(User u);
    8. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    9. boolean updateUser(User u);
    10. @Delete("delete from mybatis.user where id=#{id}")
    11. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    12. @Select("select * from mybatis.user where id=#{id}")
    13. User selectUserById(@Param("id") int id);
    14. @Select("select * from mybatis.user")
    15. List<User> selectAll();
    16. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    17. boolean insertUser(User u);
    18. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    19. boolean updateUser(User u);
    20. @Delete("delete from mybatis.user where id=#{id}")
    21. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    22. @Select("select * from mybatis.user where id=#{id}")
    23. User selectUserById(@Param("id") int id);
    24. @Select("select * from mybatis.user")
    25. List<User> selectAll();
    26. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    27. boolean insertUser(User u);
    28. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    29. boolean updateUser(User u);
    30. @Delete("delete from mybatis.user where id=#{id}")
    31. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    32. @Select("select * from mybatis.user where id=#{id}")
    33. User selectUserById(@Param("id") int id);
    34. @Select("select * from mybatis.user")
    35. List<User> selectAll();
    36. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    37. boolean insertUser(User u);
    38. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    39. boolean updateUser(User u);
    40. @Delete("delete from mybatis.user where id=#{id}")
    41. boolean deleteUser(@Param("id") int id);    title=#{title}//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    42. @Select("select * from mybatis.user where id=#{id}")
    43. User selectUserById(@Param("id") int id);
    44. @Select("select * from mybatis.user")
    45. List<User> selectAll();
    46. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    47. boolean insertUser(User u);
    48. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    49. boolean updateUser(User u);
    50. @Delete("delete from mybatis.user where id=#{id}")
    51. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    52. @Select("select * from mybatis.user where id=#{id}")
    53. User selectUserById(@Param("id") int id);
    54. @Select("select * from mybatis.user")
    55. List<User> selectAll();
    56. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    57. boolean insertUser(User u);
    58. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    59. boolean updateUser(User u);
    60. @Delete("delete from mybatis.user where id=#{id}")
    61. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    62. @Select("select * from mybatis.user where id=#{id}")
    63. User selectUserById(@Param("id") int id);
    64. @Select("select * from mybatis.user")
    65. List<User> selectAll();
    66. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    67. boolean insertUser(User u);
    68. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    69. boolean updateUser(User u);
    70. @Delete("delete from mybatis.user where id=#{id}")
    71. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    72. @Select("select * from mybatis.user where id=#{id}")
    73. User selectUserById(@Param("id") int id);
    74. @Select("select * from mybatis.user")
    75. List<User> selectAll();
    76. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    77. boolean insertUser(User u);
    78. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    79. boolean updateUser(User u);
    80. @Delete("delete from mybatis.user where id=#{id}")
    81. boolean deleteUser(@Param("id") int id);    and author=#{author}//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    82. @Select("select * from mybatis.user where id=#{id}")
    83. User selectUserById(@Param("id") int id);
    84. @Select("select * from mybatis.user")
    85. List<User> selectAll();
    86. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    87. boolean insertUser(User u);
    88. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    89. boolean updateUser(User u);
    90. @Delete("delete from mybatis.user where id=#{id}")
    91. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    92. @Select("select * from mybatis.user where id=#{id}")
    93. User selectUserById(@Param("id") int id);
    94. @Select("select * from mybatis.user")
    95. List<User> selectAll();
    96. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    97. boolean insertUser(User u);
    98. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    99. boolean updateUser(User u);
    100. @Delete("delete from mybatis.user where id=#{id}")
    101. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    102. @Select("select * from mybatis.user where id=#{id}")
    103. User selectUserById(@Param("id") int id);
    104. @Select("select * from mybatis.user")
    105. List<User> selectAll();
    106. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    107. boolean insertUser(User u);
    108. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    109. boolean updateUser(User u);
    110. @Delete("delete from mybatis.user where id=#{id}")
    111. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    112. @Select("select * from mybatis.user where id=#{id}")
    113. User selectUserById(@Param("id") int id);
    114. @Select("select * from mybatis.user")
    115. List<User> selectAll();
    116. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    117. boolean insertUser(User u);
    118. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    119. boolean updateUser(User u);
    120. @Delete("delete from mybatis.user where id=#{id}")
    121. boolean deleteUser(@Param("id") int id);    and views=#{views}//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    122. @Select("select * from mybatis.user where id=#{id}")
    123. User selectUserById(@Param("id") int id);
    124. @Select("select * from mybatis.user")
    125. List<User> selectAll();
    126. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    127. boolean insertUser(User u);
    128. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    129. boolean updateUser(User u);
    130. @Delete("delete from mybatis.user where id=#{id}")
    131. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    132. @Select("select * from mybatis.user where id=#{id}")
    133. User selectUserById(@Param("id") int id);
    134. @Select("select * from mybatis.user")
    135. List<User> selectAll();
    136. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    137. boolean insertUser(User u);
    138. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    139. boolean updateUser(User u);
    140. @Delete("delete from mybatis.user where id=#{id}")
    141. boolean deleteUser(@Param("id") int id);      
    复制代码
    1. List<Student> selectAll();
    复制代码
12.4 trim、where、set


  • 前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题。现在回到之前的 “if” 示例,这次我们将 “state = ‘ACTIVE’” 设置成动态条件,看看会发生什么。
    1. <resultMap id="student_teacher" type="Student">
    2.     <result property="id" column="id"/>
    3.     <result property="name" column="name"/>
    4.        
    5.     <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    6. </resultMap>
    7. <select id="selectAll" resultMap="student_teacher">
    8.     select * from mybatis.student
    9. </select>
    10. <select id="getTeacher" resultType="Teacher">
    11.     select * from mybatis.teacher where id=#{tid}
    12. </select>
    复制代码
  • 如果没有匹配的条件会怎么样?最终这条 SQL 会变成这样:
    1. @Test
    2. public void selectAll(){
    3.     SqlSession sqlSession = MybatisUtils.getSqlSession();
    4.     StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    5.     List<Student> studentList = mapper.selectAll();
    6.     for (Student s:
    7.          studentList) {
    8.         System.out.println(s);
    9.     }
    10.     sqlSession.close();
    11. }
    复制代码
  • 这会导致查询失败。如果匹配的只是第二个条件又会怎样?这条 SQL 会是这样:
    1. @Test
    2. public void selectAll(){
    3.     SqlSession sqlSession = MybatisUtils.getSqlSession();
    4.     StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    5.     List<Student> studentList = mapper.selectAll();
    6.     for (Student s:
    7.          studentList) {
    8.         System.out.println(s);
    9.     }
    10.     sqlSession.close();
    11. }AND title like ‘someTitle’
    复制代码
  • 这个查询也会失败。这个问题不能简单地用条件元素来解决。这个问题是如此的难以解决,以至于解决过的人不会再想碰到这种问题。
  • MyBatis 有一个简单且适合大多数场景的解决办法。而在其他场景中,可以对其进行自定义以符合需求。而这,只需要一处简单的改动:
    1. <select id="selectAll2" resultMap="S_T">
    2.     select s.id sid,s.name sname,t.name tname
    3.     from mybatis.student s,mybatis.teacher t
    4.     where s.tid=t.id
    5. </select>
    6. <resultMap id="S_T" type="Student">
    7.     <result property="id" column="sid"/>
    8.     <result property="name" column="sname"/>
    9.     <association property="teacher" javaType="Teacher">
    10.         <result property="name" column="tname"/>
    11.     </association>
    12. </resultMap>
    复制代码
  • where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
  • 如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:
    1. //测试代码
    复制代码
  • prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容
  • 用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。比如:
    1. @Data
    2. @AllArgsConstructor
    3. @NoArgsConstructor
    4. public class Teacher {
    5.         private int id;
    6.         private String name;
    7.         //老师拥有多个学生
    8.         private List<Student> students;
    9. }
    复制代码
  • 如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:
    1.   update Author//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    2. @Select("select * from mybatis.user where id=#{id}")
    3. User selectUserById(@Param("id") int id);
    4. @Select("select * from mybatis.user")
    5. List<User> selectAll();
    6. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    7. boolean insertUser(User u);
    8. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    9. boolean updateUser(User u);
    10. @Delete("delete from mybatis.user where id=#{id}")
    11. boolean deleteUser(@Param("id") int id); username=#{username},      password=#{password},      email=#{email},      bio=#{bio}      where id=#{id}
    复制代码
  • 这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
  • 来看看与 set 元素等价的自定义 trim 元素吧:
    1. //测试代码
    复制代码
  • 代码演示
    1. <select id="selectAll" resultType="Teacher">
    2.     select * from mybatis.teacher
    3. </select>
    4. <select id="getTeacher" resultMap="S_T">
    5.     select t.id tid, t.name tname,s.name sname
    6.     from mybatis.teacher t,mybatis.student s
    7.     where s.tid=tid and tid=#{tid}
    8. </select>
    9. <resultMap id="S_T" type="Teacher">
    10.     <result property="id" column="tid"/>
    11.     <result property="name" column="tname"/>
    12.        
    13.     <collection property="students" ofType="Student">
    14.         <result property="name" column="sname"/>
    15.         <result property="tid" column="tid"/>
    16.     </collection>
    17. </resultMap>
    18. <select id="getTeacher2" resultMap="student_teacher">
    19.     select * from mybatis.teacher where id=#{tid}
    20. </select>
    21. <resultMap id="student_teacher" type="Teacher">
    22.     <result property="id" column="id"/>
    23.     <result property="name" column="name"/>
    24.     <collection property="students" column="id" ofType="Student" select="getStudents"/>
    25. </resultMap>
    26. <select id="getStudents" resultType="Student">
    27.     select * from mybatis.student where tid=#{tid}
    28. </select>
    复制代码
    1.     update mybatis.blog//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    2. @Select("select * from mybatis.user where id=#{id}")
    3. User selectUserById(@Param("id") int id);
    4. @Select("select * from mybatis.user")
    5. List<User> selectAll();
    6. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    7. boolean insertUser(User u);
    8. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    9. boolean updateUser(User u);
    10. @Delete("delete from mybatis.user where id=#{id}")
    11. boolean deleteUser(@Param("id") int id);   title=#{title},        author=#{author}        where id=#{id}
    复制代码
    1. create table blog(
    2. id varchar(50) not null comment '博客id',
    3. title varchar(100) not null comment '博客标题',
    4. author varchar(30) not null comment '博客作者',
    5. ctreate_time datetime not null comment '创建时间',
    6. views int not null comment '浏览量'
    7. )engine=InnoDB default charset=utf8;
    复制代码
  • 所谓动态sql,本质还是SQL语句,只是我们可以在SQL层面,执行逻辑代码
12.5 SQL片段


  • 有的时候,我们可以将一些功能的部分抽取出来(类似函数的封装),方便复用
  • 使用sql标签封装,在需要的地方使用include标签引入
    1. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    2. @Select("select * from mybatis.user where id=#{id}")
    3. User selectUserById(@Param("id") int id);
    4. @Select("select * from mybatis.user")
    5. List<User> selectAll();
    6. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    7. boolean insertUser(User u);
    8. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    9. boolean updateUser(User u);
    10. @Delete("delete from mybatis.user where id=#{id}")
    11. boolean deleteUser(@Param("id") int id);   title = #{title}//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    12. @Select("select * from mybatis.user where id=#{id}")
    13. User selectUserById(@Param("id") int id);
    14. @Select("select * from mybatis.user")
    15. List<User> selectAll();
    16. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    17. boolean insertUser(User u);
    18. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    19. boolean updateUser(User u);
    20. @Delete("delete from mybatis.user where id=#{id}")
    21. boolean deleteUser(@Param("id") int id);       and author = #{author}        select * from mybatis.blog//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    22. @Select("select * from mybatis.user where id=#{id}")
    23. User selectUserById(@Param("id") int id);
    24. @Select("select * from mybatis.user")
    25. List<User> selectAll();
    26. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    27. boolean insertUser(User u);
    28. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    29. boolean updateUser(User u);
    30. @Delete("delete from mybatis.user where id=#{id}")
    31. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    32. @Select("select * from mybatis.user where id=#{id}")
    33. User selectUserById(@Param("id") int id);
    34. @Select("select * from mybatis.user")
    35. List<User> selectAll();
    36. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    37. boolean insertUser(User u);
    38. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    39. boolean updateUser(User u);
    40. @Delete("delete from mybatis.user where id=#{id}")
    41. boolean deleteUser(@Param("id") int id);  
    复制代码
  • 注意事项:

    • 最好基于单表定义SQL片段
    • 不要存在where标签

12.6 foreach


  • 动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:
    1. public interface BlogMapper {}
    复制代码
  • foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
  • 提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
  • 至此,我们已经完成了与 XML 配置及映射文件相关的讨论。下一章将详细探讨 Java API,以便你能充分利用已经创建的映射配置。
  • foreach的作用,就是为了替代下面这种复杂的语句
    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper
    3.                 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4.                 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.yu.dao.BlogMapper">
    6. </mapper>
    复制代码
  • 代码演示(改一下数据库id)
    1. <settings>
    2.     <setting name="logImpl" value="STDOUT_LOGGING"/>
    3.     <setting name="mapUnderscoreToCamelCase" value="true"/>
    4. </settings>
    复制代码
    1.     select * from mybatis.blog//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    2. @Select("select * from mybatis.user where id=#{id}")
    3. User selectUserById(@Param("id") int id);
    4. @Select("select * from mybatis.user")
    5. List<User> selectAll();
    6. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    7. boolean insertUser(User u);
    8. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    9. boolean updateUser(User u);
    10. @Delete("delete from mybatis.user where id=#{id}")
    11. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    12. @Select("select * from mybatis.user where id=#{id}")
    13. User selectUserById(@Param("id") int id);
    14. @Select("select * from mybatis.user")
    15. List<User> selectAll();
    16. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    17. boolean insertUser(User u);
    18. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    19. boolean updateUser(User u);
    20. @Delete("delete from mybatis.user where id=#{id}")
    21. boolean deleteUser(@Param("id") int id);      id=#{id}//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    22. @Select("select * from mybatis.user where id=#{id}")
    23. User selectUserById(@Param("id") int id);
    24. @Select("select * from mybatis.user")
    25. List<User> selectAll();
    26. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    27. boolean insertUser(User u);
    28. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    29. boolean updateUser(User u);
    30. @Delete("delete from mybatis.user where id=#{id}")
    31. boolean deleteUser(@Param("id") int id);   
    复制代码
    1. //查询博客
    2. List<Blog> queryBlogIf(Map<String,Object> map);
    复制代码
    动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式去排列组合
13 缓存

13.1 简介


  • 为什么要使用缓存
    每次查询都要连接数据库,比较耗资源,我们把查询到的数据暂存到内存里面,下次查询的时候,从内存读取,  这个地方就叫缓存。
  • 什么样的数据适用于缓存?
    经常查询且不经常改变的数据
13.2 Mybatis缓存


  • Mybatis系统默认定义了两级缓存

    • 默认情况下,只有一级缓存开启(SqlSession缓存,也称为本地缓存)
    • 二级缓存需要手动配置,它是基于namespace级别的缓存
    • Mybatis定义了缓存接口Cache,可以通过实现Cache接口来自定义二级缓存

13.3 一级缓存


  • 测试步骤

    • 开启日志
    • 测试在一个Session中查询两次的计量局
    • 查看日志输出

  • 代码演示
    1. <select id="queryBlogIf" parameterType="map" resultType="Blog">
    2.     select * from mybatis.blog where 1=1
    3.     <if test="title!=null">
    4.         and title = #{title}
    5.     </if>
    6.     <if test="author!=null">
    7.         and author = #{author}
    8.     </if>
    9. </select>
    复制代码
    1. @Test
    2. public void queryBlogIf(){
    3.     SqlSession sqlSession = MybatisUtils.getSqlSession();
    4.     BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    5.     Map<String,Object> map=new HashMap<String,Object>();
    6.     mapper.queryBlogIf(map);
    7.     System.out.println("==================");
    8.     map.put("title",(String)"MyBatis如此简单");
    9.     mapper.queryBlogIf(map);
    10.     System.out.println("==================");
    11.     map.put("author",(String)"狂神说");
    12.     mapper.queryBlogIf(map);
    13.     System.out.println("==================");
    14.     sqlSession.close();
    15. }
    复制代码
    1. <select id="findActiveBlogLike"
    2.          resultType="Blog">
    3.   SELECT * FROM BLOG WHERE state = ‘ACTIVE’
    4.   <choose>
    5.         <when test="title != null">
    6.           AND title like #{title}
    7.         </when>
    8.         <when test="author != null and author.name != null">
    9.           AND author_name like #{author.name}
    10.         </when>
    11.         <otherwise>
    12.           AND featured = 1
    13.         </otherwise>
    14.   </choose>
    15. </select>
    复制代码

  • 缓存失效的情况

    • 查询不同的Mapper.xml
    • 增删改
    • 查询不同的东西
    • 手动清理缓存(sqlSession.clearCache())

13.4 二级缓存


  • MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。
  • 默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:
    1. [/code]
    2. [*]基本上就是这样。这个简单语句的效果如下:
    3. [code]<select id="queryBlogChoose" parameterType="map" resultType="Blog">
    4.     select * from mybatis.blog
    5.     <where>
    6.         <choose>
    7.             <when test="title!=null">
    8.                 title=#{title}
    9.             </when>
    10.             <when test="author!=null">
    11.                 and author=#{author}
    12.             </when>
    13.             <otherwise>
    14.                 and views=#{views}
    15.             </otherwise>
    16.         </choose>
    17.     </where>
    18. </select>
    复制代码
  • 这些属性可以通过 cache 元素的属性来修改。比如:
    1. [/code]
    2. [*]这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。
    3. [*]使用二级缓存
    4. [list=1]
    5. [*]开启全局缓存
    6. [/list][code]
    复制代码

    • 在要使用二级缓存的Mapper.xml中,写标签
    1. [/code][list=1]
    2. [*]测试使用
    3. [/list][code]SELECT * FROM BLOG
    4. WHERE
    5. AND title like ‘someTitle’
    复制代码


  • 问题

    • 我们需要实体类序列化,否则会抛出异常

  • 小结

    • 二级缓存在同一个Mapper下有效
    • 所有的数据都会先放在一级缓存中
    • 当会话提交或者关闭,数据会被转存到二级缓存中

13.5 缓存原理


  • 图片演示

13.6 自定义缓存ehcache


  • 简介
    EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。
  • 使用

    • 导包
    1. <select id="findActiveBlogLike"
    2.          resultType="Blog">
    3.   SELECT * FROM BLOG
    4.   <where>
    5.         <if test="state != null">
    6.                  state = #{state}
    7.         </if>
    8.         <if test="title != null">
    9.                 AND title like #{title}
    10.         </if>
    11.         <if test="author != null and author.name != null">
    12.                 AND author_name like #{author.name}
    13.         </if>
    14.   </where>
    15. </select>
    复制代码

    • 写入配置文件(resources->ehcache.xml)
    1. //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    2. @Select("select * from mybatis.user where id=#{id}")
    3. User selectUserById(@Param("id") int id);
    4. @Select("select * from mybatis.user")
    5. List<User> selectAll();
    6. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    7. boolean insertUser(User u);
    8. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    9. boolean updateUser(User u);
    10. @Delete("delete from mybatis.user where id=#{id}")
    11. boolean deleteUser(@Param("id") int id);//多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
    12. @Select("select * from mybatis.user where id=#{id}")
    13. User selectUserById(@Param("id") int id);
    14. @Select("select * from mybatis.user")
    15. List<User> selectAll();
    16. @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
    17. boolean insertUser(User u);
    18. @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
    19. boolean updateUser(User u);
    20. @Delete("delete from mybatis.user where id=#{id}")
    21. boolean deleteUser(@Param("id") int id);
    复制代码

    • 在Mapper中指定
    1. [/code][list=1]
    2. [*]测试使用(用之前的代码即可)
    3. [/list]
    4. [*]自定义缓存
    5. 只要实现了org.apache.ibatis.cache.Cache接口,就能定义自己的缓存,但是实现比较复杂,只需要会使用就行,ehcache是继承了AbstractEhcacheCache,该类已经实现了Cache接口。
    6. [code]<update id="updateAuthorIfNecessary">
    7.   update Author
    8.     <set>
    9.       <if test="username != null">username=#{username},</if>
    10.       <if test="password != null">password=#{password},</if>
    11.       <if test="email != null">email=#{email},</if>
    12.       <if test="bio != null">bio=#{bio}</if>
    13.     </set>
    14.   where id=#{id}
    15. </update>
    复制代码
  • 实际开发中使用的缓存

    • 在实际开发中,我们更多的使用Redis来做缓存


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曂沅仴駦

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表