一、通用Mapper

作用:替我们生成常用增删改查操作的SQL语句,减轻负担 通用mapper官方文档:https://github.com/abel533/Mapper/wiki/1.integration

1、准备环境

1.1 首先的有一张表

1.2 然后要有一个对应表的实体类

  1. 实体类的要求:必须都是包装类,double—->Double int—-> Integer
  2. 当然了,在开发中 实体类中尽量不要使用 基本数据类型,都是用对应的包装类型
  3. 在实体类的类名上添加@Table注解,此注解表示这个实体类对应的数据库中的表名

    1. @Table(name = "table_emp")
    2. public class Employee {
    3. @Id
    4. @GeneratedValue(strategy = GenerationType.IDENTITY)
    5. private Integer empId;
    6. private String empName;
    7. private Double empSalary;
    8. private Integer empAge;
    9. @Transient
    10. private String name;

    1.3 搭建mybatis+spring的开发环境

    jdbc.properites

    1. jdbc.url=jdbc:mysql://localhost:3306/mybatis
    2. jdbc.username=root
    3. jdbc.password=0000
    4. jdbc.max=20

    applicationContext.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    6. <!--把数据库的配置文件(jdbc.properties引入进来)-->
    7. <context:property-placeholder location="classpath:jdbc.properties"/>
    8. <!--声明数据源,DataSource,作用是连接数据库的,不用MyBatis原来的POOLED了-->
    9. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    10. <!--使用外部的properties文件语法 ${}-->
    11. <property name="url" value="${jdbc.url}"/>
    12. <property name="username" value="${jdbc.username}"/>
    13. <property name="password" value="${jdbc.password}"/>
    14. <property name="maxActive" value="${jdbc.max}"/>
    15. </bean>
    16. <!--声明mybatis中所提供的SqlSessionFactoryBean类,这个类的内部是创建SqlSessionFactory的-->
    17. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    18. <property name="dataSource" ref="dataSource"/>
    19. <property name="configLocation" value="classpath:mybatis-config.xml"/>
    20. </bean>
    21. <!--创建dao对象,使用SqlSession的getMapper(User.class)-->
    22. <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
    23. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    24. <property name="basePackage" value="com.yixuexi.dao"/>
    25. </bean>
    26. <!--通过注解的方式创建对象-->
    27. <context:component-scan base-package="com.yixuexi"/>
    28. </beans>

    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. <!--设置别名-->
    7. <typeAliases>
    8. <package name="com.yixuexi.entity"/>
    9. </typeAliases>
    10. <mappers>
    11. </mappers>
    12. </configuration>

    1.4 添加通用Mapper的依赖

    1. <dependency>
    2. <groupId>tk.mybatis</groupId>
    3. <artifactId>mapper</artifactId>
    4. <version>最新版本</version>
    5. </dependency>

    1.5 修改spring配置文件,整合通用mapper

    把applicationContext.xml文件中的 <bean class="``org``.xxx.xxx.MapperScannerConfigurer">org改成``tk

1.6 在dao中创建EmployeeDao接口继承Mapper

【接口和接口之间的继承 extends】

继承Mapper接口,后面的泛型传入对应的实体类 【Mapper接口:通用Mapper提供的核心接口】

  1. //在继承那里传入一个 泛型,此泛型就是这个接口对应的实体类的表
  2. public interface EmployeeDao extends Mapper<Employee> {
  3. }

1.7 然后就可以使用了,此时的EmployeeDao接口里面,表面是没有抽象方法的,但是他继承了Mapper接口,他暗地里有方法

未命名图片.png

2、注意事项

  1. 数据库的表名叫table_emp,而实体类得名字叫Employee

    • 所以不要忘记在实体类上添加@Table(name =”表名”)注解
    • 他的默认规则是 类名Employee ——> 表名employee
  2. 不需要在mybatis-config中配置mapper信息,通用Mapper自己配置了

    • 标签里面配置你的自己写的mapper就行了
  3. 实体类中属性和表中的字段不一致也没关系,通用Mapper会将 empName —转化—> emp_name

    • 默认规则: 属性empName ——>字段 emp_name
    • 如果没有按照默认规则的话,可以在属性上使用@Column注解 @Column(name=”字段名”)
  4. 但凡是遇到了 **xxxxPrimaryKey()**的方法 都需要使用@Id注解 在实体类中的属性上面添加 来明确哪个是主键

3、会使用到的注解

  1. **@Table(name="表名")** : 在实体类上定义,表示类和数据库中表的映射关系

    • 默认规则:类名Employee ——> 表名employee
  2. **@Column(name="字段名") ** :定义在属性上,表示属性和字段的映射关系

    • 默认规则:属性empName ——>字段 emp_name
  3. **@Id** :定义在实体类的属性上,告诉通用mapper这是 主键字段

    • 在调用selectByPrimaryKey()方法的时候,是通过主键来查询,但是他不知道哪个字段是主键,所以要用@Id注解来告诉程序,这个是属性是主键
  4. **@GeneratedValue(strategy = GenerationType.IDENTITY)**

    • 定义在主键上,调用完insert方法后,将新自增的id属性封装进 实体类那个对象的empId属性
  5. **@Transient** 一般实体类的字段都是和数据库字段一一对应的,如果有额外的属性可以使用@T``ransient来表示

    • 查询的 时候会忽略被这个注解修饰的属性

4、通用Mapper里面常用的方法

  1. **selectOne(Emp e)** //根据条件查询一个

    • 实体类封装查询条件生成WHERE子句的规则:
      • 传过来的对象中,非null的属性 会被拼装成where子句
      • 在条件表达式中 比较的都是相等的关系,where id = 1
    • 只能返回一个,如果根据的条件能返回多个的话 会报错
  2. **selectByPrimaryKey( Integer id )** //根据主键查询,返回一个实体类对象

    • 需要在实体类的主键属性上添加@Id注解,告诉这个是主键,通过这个查询
    • 如果没有@Id注解的话,会造成查询结果为null
      • 之所以会是null,是因为通用Mapper将类中所有的字段都当成主键,结果成了联合主键
    • 但凡是遇到了 **xxxxPrimaryKey()**的方法 都需要使用@Id注解 来明确哪个是主键
  3. **existsWithPrimaryKey**``**(Integer id)** //根据主键查询,看看有没有,返回一个Boolean

    • 注意需要在实体类上 表明谁是主键 @Id

  1. **Insert(Emp e)** //把提供的一个对象保存到数据库中去
    • 还有一个功能,将刚刚插入的主键封装进 实体类对象,只需在实体类的主键属性上加入注解
    • **@GeneratedValue(strategy = GenerationType.IDENTITY)**
    • 这样插入完成之后 在调用实体类对象的 **getEmpId()** 方法,可以获取到刚插入自增的id 【e.getEmpId()】


  1. **insertSelective()** //有选择的保存一个对象,对象中属性有值的保存,没值的不保存
    • 为null的属性不会写入到sql语句中,但是主键为null依然会写到主键中
    • 字段多的时候,使用这个能减少数据库压力

  1. **updateByPrimaryKey()** //根据主键更新,字段为null的属性也会拼装到SQL语句中

    • 如果为null的属性 被拼装到SQL中 会导致数据库中的原有数据被覆盖
  2. **updateByPrimaryKeySelective()** //根据主键有选择的更新,为null的字段不会拼装到SQL中

    • 常用于更新,为null的属性不拼装到SQL中,为null的属性不会影响数据库原有的数据

  1. **delete(Emp e)** //删除记录,根据传过来的对象的属性来删除,where 字段 = 属性不为null的

    • 一次可以删除多条记录【如果有多个叫张三的可以删除多个张三】
    • 如果传入一个null,那么就是没有指定删除条件,所有的记录都会被删除【没有 where子句的部分】
    • 实际使用中对 实体类对象进行 非空判断
  2. **deleteByPrimaryKey(Integer id)** // 通过主键来进行删除

    • 一次只能删除一条记录【where emp_id = empId】

5、QBC查询

概念:Query By Criteria 根据标准查询 使用QBC查询,可以通过像搭积木的方法来进行复杂 SQL的拼装

示例
想要拼装的SQL语句的where部分为
Where (emp_salary > ? And emp_age < ?) or ( emp_salary < ? And emp_age > ?);
使用Dao中的方法为:**selectByExample(example)** ; //通过条件查询

在测试方法中需要这样写

  1. 先创建出来Example对象,传入一个实体类的class字节码

Example example = new Example(Employee.class);

  1. 通过example对象创建 Criteria对象【直接 example. 就有了】

Example.Criteria criteria 01 = example.createCriteria();
因为条件有两个所以创建两个Criteria对象,拼装起来
Example.Criteria criteria 02 = example.createCriteria();

  1. 在两个Criteria对象中分别设置查询条件

andGreaterThan()方法 :properties > value【支持链式变成,可以直接在后面写 年龄 < ?】
andLessThan() 方法 :properties < value?
第一个参数 properties :实体类的属性名
第二个参数 value:实体类的属性值
criteria01.andGreaterThan("empSalary",2000).andLessThan("empAge",50);
第二个条件
criteria02.andLessThan("empSalary",5000).andGreaterThan("empAge",30);

  1. 使用example对象的or关键词组装两个Criteria对象
    • `example.or(criteria02); //此时的example就是 criteria01的那个条件

`

  1. 执行查询
    • 调用service写好的List<Employee> employees = employeeService.selectByExample(example);
    • 此时 在service类里有一个 employeeDao.selectByExample(obj); 这样的方法在执行

5.1 QBC查询其他的属性 这些都是通用mapper的 selectByExample()方法

  1. 设置排序信息

根据主要条件工资的升序和次要条件年龄的降序进行排序
Example example = new Example(Employee.class);`` //``创建ex``ample``对象
//支持链式编程,直接在asc后面添加次要条件就行 【orderBy()方法 跟一个要排序实体类的属性名】
**example.orderBy("empSalary").asc().orderBy("empAge").desc();**
employeeService.selectByExampleOrder(example); //调用service方法 把 example传进去就行

  1. 设置去重

Example example = new Example(Employee.class);
example.setDistinct(true);//设置为true就行

  1. 设置select字段
    1. 查询不是都查询出来,而是查询设置的这些内容

Example e = new Example(Employee.class);
**e.selectProperties("empName","empSalary");** [查询两个字段,别的都是null]

  1. 分页,不需要使用,因为是假分页,是全部查出来后在内存中做分页的,并没有在sql语句上拼装limit语句

    5.2 会使用的方法

  • Example example = **new Example**(Employee.class);//创建example对象,传入一个实体类的class
  • Example.Criteria criteria02 = **example**.**createCriteria**(); //创建条件 | 标准,如果有多个 可创建多个
  • criteria01.**andGreaterThan**("实体类的属性名",value); // 实体类 大于 value
  • criteria02.**andLessThan**("实体类的属性名",value) 实体类 小于 value
  • example.or(criteria02); // 通过使用 or 把两个条件拼装起来,此时的example就是 01, 只需要把 02传进去

二、逆向工程 MyBatis Generator MBG

简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的根据表生成对应的映射文件,接口,实体类。支持基本的增删改查,以及QBC风格的条件查询,但是表连接,存储过程这些复杂的SQL的定义需要我们手工编写

1、起步

官方文档 起步教程:http://mybatis.org/generator/configreference/xmlconfig.html

1.1 导入maven依赖【MySQL,MyBatis,MyBatis Generator】

  1. <!--逆向工程-->
  2. <dependency>
  3. <groupId>org.mybatis.generator</groupId>
  4. <artifactId>mybatis-generator-core</artifactId>
  5. <version>1.4.0</version>
  6. </dependency>

1.2 在resouces目录下创建 mbg.xml配置文件

  1. 内容可以在起步教程那里复制过来
  2. **jdbcConnection** 配置数据库连接信息
  3. **javaModelGenerator** 配置java实体类的生成策略
  4. **sqlMapGenerator **配置sql映射文件的生成策略
  5. **javaClientGenerator **配置Mapper接口的生成策略
  6. **Table **配置逆向解析的数据表
  1. <a name="EZ7m0"></a>
  2. ### 1.3 执行
  3. ```java
  4. List<String> warnings = new ArrayList<String>();
  5. boolean overwrite = true;
  6. File configFile = new File("E:\\javaWeb\\framework\\MyBatis\\MyBatisPlugins\\MyBatis_generator\\src\\main\\resources\\mgb.xml");
  7. ConfigurationParser cp = new ConfigurationParser(warnings);
  8. Configuration config = cp.parseConfiguration(configFile);
  9. DefaultShellCallback callback = new DefaultShellCallback(overwrite);
  10. MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
  11. myBatisGenerator.generate(null);

1.4 注意

  • 逆向工程不会生成MyBatis的主配置文件,主配置文件需要自己写

三、分页mapper

1、起步

1.1 导入maven依赖

  1. <dependency>
  2. <groupId>com.github.pagehelper</groupId>
  3. <artifactId>pagehelper</artifactId>
  4. <version>5.2.0</version>
  5. </dependency>

1.2 在mybatis-config.xml文件中配置分页插件

  1. <plugins>
  2. <plugin interceptor="com.github.pagehelper.PageInterceptor">
  3. <!--分页参数合理化,不可能达到一个不正确的页码,如-1,超过总页数,查询最后一页-->
  4. <property name="reasonable" value="true"/>
  5. </plugin>
  6. </plugins>

1.3 在查询之前调用一下pageHelper.startPage()方法

  1. //第一个参数传入:第几页,第二个参数传入:每页多少条数据
  2. PageHelper.startPage(1,5);
  3. //调用查询方法
  4. List<Employee> employees = mapper.selectByExample(null);
  5. //创建PageInfo对象,传进去结果,和每页多少条数据
  6. PageInfo info = new PageInfo(employees,5);
  7. //通过调用info对象里面的方法 就能得到所有的分页信息,分页总页数,总记录数
  8. // info.getList();方法就是得到查询到的分页数据,返回一个list集合