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完成数据访问层的优化.它专注于sql语句.简化了过去JDBC繁琐的访问机制.

怎么获取mybatis?

  • maven仓库

    1. <dependency>
    2. <groupId>org.mybatis</groupId>
    3. <artifactId>mybatis</artifactId>
    4. <version>3.5.6</version>
    5. </dependency>
  • 搜搜jar包的坐标网站:https://mvnrepository.com/

  • mybatis中文文档:https://mybatis.net.cn/

    MyBatis快速入门

    添加所需依赖

    修改pom.xml文件,添加MyBatis需要的依赖

    1. <dependencies>
    2. <!-- 添加mybatis框架依赖 -->
    3. <dependency>
    4. <groupId>org.mybatis</groupId>
    5. <artifactId>mybatis</artifactId>
    6. <version>3.5.6</version>
    7. </dependency>
    8. <!-- 添加mysql依赖 -->
    9. <dependency>
    10. <groupId>mysql</groupId>
    11. <artifactId>mysql-connector-java</artifactId>
    12. <version>5.1.32</version>
    13. </dependency>
    14. </dependencies>

    指定资源文件

    修改pom.xml文件,指定资源文件(保证目录中的所有资源文件都拷贝到target中)

    1. <build>
    2. <resources>
    3. <resource>
    4. <directory>src/main/java</directory>
    5. <includes>
    6. <include>**/*.xml</include>
    7. <include>**/*.properties</include>
    8. </includes>
    9. </resource>
    10. <resource>
    11. <directory>src/main/resources</directory>
    12. <includes>
    13. <include>**/*.xml</include>
    14. <include>**/*.properties</include>
    15. </includes>
    16. </resource>
    17. </resources>
    18. </build>

    添加配置文件

  • jdbc.properties文件

    1. jdbc.driverClassName=com.mysql.jdbc.Driver
    2. jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8
    3. #jdbc.url=jdbc:mysql://localhost:3308/ssm?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    4. jdbc.username=root
    5. jdbc.password=root
  • 添加核心配置文件(SqlMapConfig.xml)

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-config.dtd">

    ```xml <?xml version=”1.0” encoding=”UTF-8” ?> <!DOCTYPE configuration PUBLIC “-//mybatis.org//DTD Config 3.0//EN”

    1. "http://mybatis.org/dtd/mybatis-3-config.dtd">

  1. <environments default="development">
  2. <environment id="development">
  3. <!--配置事务管理器
  4. type:指定事务管理的方式
  5. JDBC:事务的控制交给程序员处理
  6. MANAGED:由容器(如:Spring)来管理事务
  7. 注意:这里的type值必须大写
  8. -->
  9. <transactionManager type="JDBC"></transactionManager>
  10. <!--配置数据源
  11. type:指定不同的配置方式
  12. JNDI:java命名目录接口,在服务器端进行数据库连接池的管理(一般不使用)
  13. POOLED:使用数据库连接池
  14. UNPOOLED:不使用数据库连接池
  15. -->
  16. <dataSource type="POOLED">
  17. <!--配置数据库连接的四个参数-->
  18. <property name="driver" value="${jdbc.driverClassName}"/>
  19. <property name="url" value="${jdbc.url}"/>
  20. <property name="username" value="${jdbc.username}"/>
  21. <property name="password" value="${jdbc.password}"/>
  22. </dataSource>
  23. </environment>
  24. </environments>
  1. <mappers>
  2. <mapper resource="StudentMapper.xml"></mapper>
  3. </mappers>

  1. - 添加StudentMapper.xml文件
  2. ```java
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  5. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <!-- mapper:是整个文件的大标签,用来开始和结束xml文件
  5. 属性:namespace:指定命名空间(相当于包名),用来区分不同mapper.xml文件中相同的id属性
  6. -->
  7. <mapper namespace="xs">
  8. <!--使用JDBC原始方式查询全部学生的方式:List<Student> selectAll();
  9. resultType:指定查询返回的结果集的类型,如果是集合,则必须是泛型的类型
  10. parameterType:如果有参数,则通过它来指定参数的类型(使用别名,查看别名映射表)
  11. -->
  12. <select id="selectAll" resultType="com.ityg.pojo.Student">
  13. select id,name,email,age
  14. from student
  15. </select>
  16. <!--
  17. 按主键id查询学生信息
  18. Student getAllById(Integer id);
  19. -->
  20. <select id="getAllById" resultType="com.ityg.pojo.Student" parameterType="int">
  21. select id,name ,email,age
  22. from student
  23. where id = #{id}
  24. </select>
  25. </mapper>

junit测试

student为基本的JavaBean实体类。

  1. public class test {
  2. @Test
  3. public void testSelectAll(){
  4. InputStream in = null;
  5. SqlSessionFactory factory = null;
  6. SqlSession sqlSession = null;
  7. try {
  8. //1.使用文件流读取核心配置文件(SqlMapConfig.xml)
  9. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  10. //2.创建SqlSessionFactory工厂
  11. factory = new SqlSessionFactoryBuilder().build(in);
  12. //3.获取sqlSession对象
  13. sqlSession = factory.openSession();
  14. //4.完成查询操作
  15. List<Object> list = sqlSession.selectList("selectAll");
  16. list.forEach(student -> System.out.println(student));
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. }finally {
  20. //5.关闭sqlSession
  21. if (sqlSession!=null) {
  22. sqlSession.close();
  23. }
  24. }
  25. }
  26. }

为实体类注册别名

  • 单个注册

    1. <typeAliases>
    2. <typeAlias type="com.ityg.pojo.Student" alias="student"></typeAlias>
    3. </typeAliases>
    4. /*
    5. type:实体类的全限定名
    6. alias:别名
    7. */
  • 批量注册

    1. <package name="com.ityg.pojo"></package>
    2. //name:实体类的包路径
    3. //别名为类名的驼峰命名法

设置日志输出

  1. <!--设置日志输出底层执行的代码
  2. name和value就设置这两个值
  3. -->
  4. <settings>
  5. <setting name="logImpl" value="STDOUT_LOGGING"/>
  6. </settings>

注意标签的书写位置(顺序) properties, settings, typeAliases, environments, mappers(依次从上到下)

使用动态代理

动态代理存在的意义:在三层架构中,业务逻辑层需要通过接口访问数据库访问层的功能。然而使用了MyBatis框架,无法在业务逻辑层访问xml文件中的功能。
动态代理可以实现。

动态代理的规范

  1. UsersMapper.xml文件与UsersMapper.java的接口必须同一个目录下.
  2. UsersMapper.xml文件与UsersMapper.java的接口的文件名必须一致,后缀不管.
  3. UserMapper.xml文件中标签的id值与与UserMapper.java的接口中方法的名称完全一致.
  4. UserMapper.xml文件中标签的parameterType属性值与与UserMapper.java的接口中方法的参数类型完全一致.
  5. UserMapper.xml文件中标签的resultType值与与UserMapper.java的接口中方法的返回值类型完全一致.
  6. UserMapper.xml文件中namespace属性必须是接口的完全限定名称com.ityg.mapper.UsersMapper
  7. 在SqlMapConfig.xml文件中注册mapper文件时,使用class=接口的完全限定名称com.ityg.mapper.UsersMapper.(一般使用package方式注册

QQ截图20220703162501.png

使用动态代理访问CRUD操作步骤:

  1. 创建数据表(Users)
  2. 新建maven工程 ,修改目录,添加实体类
  3. 修改pom.xml文件,添加依赖
  4. 添加jdbc.propertis文件到resources目录下
  5. 添加SqlMapConfig.xml(MyBatis核心配置)文件
  6. 添加mapper文件夹,新建UsersMapper接口
  7. 在mapper文件夹下,新建UsersMapper.xml文件,完成增删改查功能
  8. 添加测试类,测试功能

代码实现:
这里从第5步开始
5-创建MyBatis核心配置文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  4. <configuration>
  5. <!--1.读取属性文件 jdbc.properties-->
  6. <properties resource="jdbc.properties"></properties>
  7. <!--2.设置控制台日志输出-->
  8. <settings>
  9. <setting name="logImpl" value="STDOUT_LOGGING"/>
  10. </settings>
  11. <!--3.给实体类注册别名-->
  12. <typeAliases>
  13. <!--为该目录下所有实体自动注册别名-->
  14. <package name="com/ityg/pojo"/>
  15. </typeAliases>
  16. <!--4.配置数据库环境变量-->
  17. <environments default="development">
  18. <environment id="development">
  19. <transactionManager type="JDBC"></transactionManager>
  20. <dataSource type="POOLED">
  21. <property name="driver" value="${jdbc.driverClassName}"/>
  22. <property name="url" value="${jdbc.url}"/>
  23. <property name="username" value="${jdbc.username}"/>
  24. <property name="password" value="${jdbc.password}"/>
  25. </dataSource>
  26. </environment>
  27. </environments>
  28. <!--5.注册mapper.xml文件-->
  29. <mappers>
  30. <!--注意这里使用类的全限定名,打点的方式-->
  31. <!--<mapper class="com.ityg.mapper.UsersMapper"></mapper>-->
  32. <!--批量注册-->
  33. <package name="com.ityg.mapper"/>
  34. </mappers>
  35. </configuration>

6-创建业务接口(UsersMapper接口)

  1. public interface UsersMapper {
  2. //查询所有用户
  3. List<Users> getAll();
  4. //根据主键查询用户
  5. Users getById(int id);
  6. //根据用户名模糊查询
  7. List<Users> getByName(String name);
  8. //用户的更新
  9. int update(Users users);
  10. //增加用户
  11. int insert(Users users);
  12. //根据主键删除用户
  13. int delete(int id);
  14. }

7-创建执行业务操作的xml配置文件(UsersMapper.xml)

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.ityg.mapper.UsersMapper">
  5. <!-- //查询所有用户
  6. List<Users> getAll();
  7. -->
  8. <select id="getAll" resultType="users">
  9. select id,username,birthday,sex,address from users
  10. </select>
  11. <!--//根据主键查询用户
  12. Users getUserById(int id);-->
  13. <select id="getUserById" parameterType="int" resultType="users">
  14. select id,username,birthday,sex,address from users
  15. where id=#{id}
  16. </select>
  17. <!--//根据用户名模糊查询
  18. List<Users> getByName(String name);-->
  19. <select id="getByName" parameterType="string" resultType="users">
  20. select id,username,birthday,sex,address from users where username like '%${name}%'
  21. </select>
  22. <!-- //用户的更新
  23. int update(Users users);
  24. private Integer id;
  25. private String userName;
  26. private Date birthday;
  27. private String sex;
  28. private String address;-->
  29. <update id="update" parameterType="users">
  30. update users set username=#{userName},birthday=#{birthday},sex=#{sex},address=#{address}
  31. where id=#{id}
  32. </update>
  33. <!--//增加用户
  34. int insert(Users users);-->
  35. <insert id="insert" parameterType="users">
  36. insert into users(username,birthday,sex,address)
  37. values(#{userName},#{birthday},#{sex},#{address})
  38. </insert>
  39. <!--//根据主键删除用户
  40. int delete(int id);-->
  41. <delete id="delete" parameterType="int" >
  42. delete from users where id=#{id}
  43. </delete>
  44. </mapper>

8-测试

  1. public class mapperTest {
  2. SqlSession sqlSession = null;
  3. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  4. //取出动态代理的对象,完成接口中方法的调用,实则是调用xml文件中的相应标签的功能
  5. UsersMapper mapper = null;
  6. @Before
  7. public void openSqlSession() throws IOException {
  8. InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
  9. SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
  10. sqlSession = factory.openSession();
  11. mapper = sqlSession.getMapper(UsersMapper.class);
  12. }
  13. @After
  14. public void closeSqlSession(){
  15. sqlSession.close();
  16. }
  17. @Test
  18. public void testGetUserById(){
  19. //取出动态代理的对象,完成接口中方法的调用,实则是调用xml文件中的相应标签的功能
  20. UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
  21. Users user = usersMapper.getById(8);
  22. System.out.println(user);
  23. }
  24. @Test
  25. public void testUpdate() throws ParseException {
  26. Users user = new Users(7,"haha",sdf.parse("2000-01-01"),"1","十堰");
  27. int count = mapper.update(user);
  28. System.out.println(count);
  29. //切记切记切记,增删改 必须要手工提交事务
  30. sqlSession.commit();
  31. }
  32. @Test
  33. public void testInsert() throws IOException, ParseException {
  34. mapper.insert(new Users("heeh",sdf.parse("2022-01-02"),"2","武汉"));
  35. sqlSession.commit();
  36. }
  37. @Test
  38. public void testDelete(){
  39. int i = mapper.delete(27);
  40. System.out.println(i);
  41. sqlSession.commit();
  42. }
  43. }

优化mapper.xml文件注册

  1. <!--注册mapper.xml文件-->
  2. <mappers>
  3. <!--绝对路径注册-->
  4. <mapper url="/////"></mapper>
  5. <!--非动态代理方式下的注册
  6. UsersMapper.xml文件放在resource目录下
  7. -->
  8. <mapper resource="UsersMapper.xml"></mapper>
  9. <!--动态代理方式下的单个mapper.xml文件注册-->
  10. <mapper class="com.ityg.mapper.UsersMapper"></mapper>
  11. <!--批量注册-->
  12. <package name="com.ityg.mapper"></package>
  13. </mappers>

#{}:占位符,${}:字符串拼接或替换

传参时大部分使用#{}传参,它的底层使用的是PreparedStatement对象,是安全的数据库访问 ,防止sql注入.

  • {}里如何写,看parameterType参数的类型

    1)如果parameterType的类型是简单类型(8种基本(封装)+String),则#{}里随便写 2)parameterType的类型是实体类的类型,则#{}里只能是类中成员变量的名称,而且区分大小写.

  • ${}字符串拼接或字符串替换

字符串拼接,一般用于模糊查询中.建议少用,因为有sql注入的风险.

  • 如果parameterType的类型是简单类型,则${}里随便写,但是分版本,如果是3.5.1及以下的版本,只以写value
  • 如果parameterType的类型是实体类的类型,则${}里只能是类中成员变量的名称.(现在已经少用)
  • 优化后的模糊查询(以后都要使用这种方式)

parameterType属性

  1. 如果是一个参数需要写
  2. 如果是两个参数,则不写

@Param()的使用

字符串替换

需求:模糊地址或用户名查询(根据传入的参数,动态的执行是按用户名还是地址进行模糊查询) select from users where username like ‘%小%’; select from users where address like ‘%市%’

  1. //为参数添加注解
  2. List<Users> getByNameOrAddress(
  3. @Param("columnName") String columnName,
  4. @Param("columnValue") String columnValue);
  5. <!-- 此处使用的是@Param注解里的名称
  6. where ${columnName}:这里也还存在sql注入问题
  7. 没有弄明白
  8. -->
  9. <select id="getByNameOrAddress" parameterType="string" resultType="users">
  10. select id,username,birthday,sex,address from users
  11. where ${columnName} like concat('%',#{columnValue },'%')
  12. </select>

如果参数超过一个,则parameterType不写

返回当前插入数据的主键

需要在insert标签中加入下面代码

select last_insert_id();

标签的参数详解: keyProperty: 实体类对象(users)的哪个属性来接返回的主键值 resultType:返回的主键的类型 order:在插入语句执行前,还是执行后返回主键的值

  1. <!--//增加用户
  2. int insert(Users users);-->
  3. <insert id="insert" parameterType="users">
  4. <selectKey keyProperty="id" resultType="int" order="AFTER">
  5. select last_insert_id();
  6. </selectKey>
  7. insert into users(username,birthday,sex,address)
  8. values(#{userName},#{birthday},#{sex},#{address})
  9. </insert>

UUID(生成全球唯一随机字符串)

  1. @Test
  2. public void testUuid(){
  3. UUID uuid = UUID.randomUUID();
  4. System.out.println(uuid.toString());
  5. }

动态sql

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

标签

  • :当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。
  • :引用中定义的常量。

    1. <!-- 定义代码片段-->
    2. <sql id="allColumn">
    3. id,username,birthday,sex,address
    4. </sql>
    5. <select id="getAll" resultType="users">
    6. select
    7. -- 引用定义的代码片段
    8. <include refid="allColumn"></include>
    9. from users
    10. </select>

    标签

  • :进行条件判断,test条件判断的取值可以是实体类的成员变量,可以是map的key,可以是@Param注解的名称。

  • :进行多条件拼接,在查询,删除,更新中使用,一般开发复杂业务的查询条件时,如果有多个查询条件,通常会使用标签来进行控制。标签可以自动的将第一个条件前面的逻辑运算符 (or ,and) 去掉。
    1. <!--根据User给的属性,进行模糊查询
    2. List<Users> getByCondition(Users users);
    3. -->
    4. <select id="getByCondition" parameterType="users" resultType="users">
    5. select <include refid="allColumn"></include> from users
    6. <where>
    7. <if test="userName != null and userName != ''">
    8. and username like concat('%',#{userName},'%')
    9. </if>
    10. <if test="birthday != null">
    11. and birthday = #{birthday}
    12. </if>
    13. <if test="sex != null and sex != ''">
    14. and sex = #{sex}
    15. </if>
    16. <if test="address != null and address != ''">
    17. and address like concat('%',#{address},'%')
    18. </if>
    19. </where>
    20. </select>

    注意每一个if里面的语句前面需要加一个and

标签

使用set标签可以将动态的配置 SET 关键字,并剔除追加到条件末尾的任何不相关的逗号。使用 if+set 标签修改后,在进行表单更新的操作中,哪个字段中有值才去更新,如果某项为 null 则不进行更新,而是保持数据库原值。切记:至少更新一列

  1. <!-- 根据user的属性值有无来更新
  2. int updateBySet(Users users);
  3. -->
  4. <update id="updateBySet" parameterType="users">
  5. update users
  6. <set>
  7. <if test="userName != null and userName != ''">
  8. username = #{userName},
  9. </if>
  10. <if test="birthday != null">
  11. birthday = #{birthday},
  12. </if>
  13. <if test="sex != null and sex != ''">
  14. sex = #{sex},
  15. </if>
  16. <if test="address != null and address != ''">
  17. address = #{address},
  18. </if>
  19. </set>
  20. where id = #{id}
  21. </update>

注意每个if里面的语句后面需要加一个’,’逗号

标签

主要用来进行集合或数组的遍历,主要参数有:

  • collection:接受过来的参数,属性值有list,array,map;它们对应的参数类型分别是:List,数组,Map集合
  • item:循环体的具体对象,支持属性的点路径访问,如item.age,item.info.details,在list和数组中是其中的对象,在map中是value。
  • separator:表示元素之间的分隔符,例如在in()的时候,separator=”,”会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
  • open:表示该语句以什么开始
  • close:表示该语句以什么结束
  • index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。

    循环遍历参数集合

    1. <!-- //查询所有id查
    2. List<Users> getByIds(int[] array);
    3. -->
    4. <select id="getByIds" resultType="users">
    5. select
    6. <include refid="allColumn"></include>
    7. from users where id in<!--(
    8. <foreach collection="array" item="id" separator=",">
    9. #{id}
    10. </foreach>
    11. )-->
    12. <foreach collection="array" item="id" separator="," open="(" close=")">
    13. #{id}
    14. </foreach>
    15. </select>

    批量增加

    1. <!--//批量增加
    2. int insertBatch(List<Users> users);-->
    3. <insert id="insertBatch" parameterType="users">
    4. insert into users(username,birthday,sex,address) values
    5. <foreach collection="list" item="user" separator=",">
    6. (#{user.userName},#{user.birthday},#{user.sex},#{user.address})
    7. </foreach>
    8. </insert>

    批量删除

    1. <!--//批量删除
    2. int deleteBeach(int[] array);-->
    3. <delete id="deleteBeach">
    4. delete from users where id in
    5. <foreach collection="array" item="id" separator="," open="(" close=")">
    6. #{id}
    7. </foreach>
    8. </delete>

    批量更新

    1. <!--//批量更新
    2. int updateBeach(List<Users> users);-->
    3. <update id="updateBeach">
    4. <foreach collection="list" item="user" separator=";">
    5. update users
    6. <set>
    7. <if test="user.userName != null and user.userName != ''">
    8. username = #{user.userName},
    9. </if>
    10. <if test="user.birthday != null">
    11. birthday = #{user.birthday},
    12. </if>
    13. <if test="user.sex != null and user.sex != ''">
    14. sex = #{user.sex},
    15. </if>
    16. <if test="user.address!= null and user.address != ''">
    17. address = #{user.address},
    18. </if>
    19. </set>
    20. where id = #{user.id}
    21. </foreach>
    22. </update>
    注意:要使用批量更新,必须在jdbc.properties属性文件中的url中添加 &allowMultiQueries=true,允许多行操作。

参数问题

指定参数位置

可以不使用对象的属性名进行参数值绑定,使用下标值

  1. <!--//查询指定出生日期区间的
  2. List<Users> getBirthday(Date begin,Date end);-->
  3. <select id="getBirthday" resultType="users">
  4. select <include refid="allColumn"></include>
  5. from users
  6. where birthday between #{arg0} and #{arg1}
  7. </select>

@Param 指定参数名称

UserMapper.java接口:

  1. //切换列名进行模糊查询
  2. //@Param("columnName"):这里定义的columnName的名称是要在xml文件中的${引用定义的名称}
  3. //为参数添加注解
  4. List<Users> getByNameOrAddress(
  5. @Param("columnName") String columnName,
  6. @Param("columnValue") String columnValue);

UserMapper.xml中:

  1. <select id="getByNameOrAddress" parameterType="string" resultType="users">
  2. select <include refid="allColumn"></include> from users
  3. where ${columnName} like concat('%',#{columnValue },'%')
  4. </select>

入参是map

入参是map,是因为当传递的数据有多个,不适合使用指定下标或指定名称的方式来进行传参,又加上参数不一定与对象的成员变量一致,考虑使用map集合来进行传递.map使用的是键值对的方式.当在sql语句中使用的时候#{键名},${键名},用的是键的名称.

  1. <!-- //入参是map
  2. List<Users> getByMap(Map<String,Date> map);-->
  3. <select id="getByMap" resultType="users">
  4. select <include refid="allColumn"></include>
  5. from users
  6. where birthday between #{birthdayBegin} and #{birthdayEnd}
  7. </select>

返回值是map

  1. <!--//返回值是map一行-->
  2. <!--Map<String,Object> getReturnMap(Integer id);-->
  3. <select id="getReturnMap" resultType="map" parameterType="int">
  4. select username,address
  5. from users where id = #{id}
  6. </select>
  7. <!--//返回值是map多行
  8. List<Map<String,Object>> getMulMap();-->
  9. <select id="getMulMap" resultType="map">
  10. select username,address
  11. from users
  12. </select>

列名与类中成员变量名不一致问题

  • 解决方法一:使用列的别名,别名与类中的成员变量名一样,即可完成注入。
  • 解决方法二:使用标签进行映射。

    表的关联关系

    总结:无论是什么关联关系,如果某方持有另一方的集合,则使用标签完成映射,如果某方持有另一方的对象,则使用标签完成映射。

    一对一关系

    一对多关系

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.ityg.mapper.CustomerMapper">
    5. <!--//根据客户id查询客户信息以及该客户的所有订单
    6. Customer getCustomerById(int id);
    7. 实体类的属性:
    8. private Integer id;
    9. private String name;
    10. private Integer age;
    11. //该客户名下的所有订单的集合
    12. private List<Order> orders;
    13. -->
    14. <resultMap id="cmap" type="customer">
    15. <!--主键绑定-->
    16. <id property="id" column="cid"></id>
    17. <!--非主键绑定-->
    18. <result property="name" column="name"></result>
    19. <result property="age" column="age"></result>
    20. <!--其他实体的部分orders
    21. private Integer id;
    22. private String num;
    23. private double price;
    24. -->
    25. <collection property="orders" ofType="order">
    26. <id property="id" column="oid"></id>
    27. <result property="num" column="orderNumber"></result>
    28. <result property="price" column="orderPrice"></result>
    29. </collection>
    30. </resultMap>
    31. <select id="getCustomerById" parameterType="int" resultMap="cmap">
    32. select c.id cid,name,age,o.id oid,orderNumber,orderPrice,customer_id
    33. from customer c left join orders o on c.id=o.customer_id
    34. where c.id = #{id}
    35. </select>
    36. </mapper>

    多对一关系

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.ityg.mapper.OrderMapper">
    5. <!--//根据订单id查询订单以及该订单的客户
    6. Order getOrderById(int id);
    7. 实体类属性
    8. private Integer id;
    9. private String num;
    10. private double price;
    11. //关联下此订单的客户信息,多方持有一方的对象
    12. private Customer customer;
    13. -->
    14. <resultMap id="omap" type="order">
    15. <id property="id" column="oid"></id>
    16. <result property="num" column="orderNumber"></result>
    17. <result property="price" column="orderPrice"></result>
    18. <association property="customer" column="customer">
    19. <id property="id" column="cid"></id>
    20. <result property="name" column="name"></result>
    21. <result property="age" column="age"></result>
    22. </association>
    23. </resultMap>
    24. <select id="getOrderById" parameterType="int" resultMap="omap">
    25. select o.id oid,orderNumber,orderPrice,c.id cid,name,age
    26. from orders o inner join customer c on customer_id = c.id
    27. where o.id = #{id}
    28. </select>
    29. </mapper>

    多对多关系

    事务

ORM

ORM(Object Relational Mapping):对象关系映射
编写程序的时候,以面向对象的方式处理数据,保存数据的时候,却以关系型数据库的方式存储。
持久化的操作:将对象保存到关系型数据库中,将关系型数据库中的数据读取出来以对象的形式封装

缓存