1. pageHelper 分页插件
1.1 maven 导入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
1.2 在MyBatis的xml文件中配置
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="offsetAsPageNum" value="true"/>
<!--配置数据库方言 4.0版本以后不用写-->
<!--<property name="helperDialect" value="mysql"/>-->
<!--是否做count查询-->
<property name="rowBoundsWithCount" value="true"/>
<!--合理化分页-->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
1.3 使用
2. 插件开发(拦截器)
MyBatis拦截器为了供用户在某些时候可以实现自己的逻辑而不必去动MyBatis固有的逻辑;通过MyBatis拦截器我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法。
MyBatis拦截器并不是每个对象里面的方法都可以被拦截的,拦截器只能拦截Executor、ParameterHandler、StatementHandler、ResultSetHandler四个对象里面的方法,MyBatis允许在映射语句执行过程中的某一点进行拦截调用,默认情况下,MyBatis允许使用插件来拦截的方法调用包括:
对象名称 | 对象作用 |
ParameterHandler | 处理用户提交参数对象 |
StatementHandler | 预编译SQL语句对象 |
Executor | 执行SQL语句对象 |
ResultSetHandler | 处理返回结果集对象 |
2.1 接口
Executor 是 Mybatis 的内部执行器,负责调用StatementHandler操作数据库,并把结果集通过 ResultSetHandler 进行自动映射,同时还处理了二级缓存的操作(故我们可以通过插件来实现自定义的二级缓存);
StatemenHandler 是 Mybatis 直接和数据库执行 sql 脚本的对象,也实现了Mybatis的一级缓存(可以使用插件来实现对一级缓存的操作(禁用等));
ParameterHandler 是 Mybatis 实现 Sql 入参设置的对象(插件可以该改变sql的参数默认设置);
ResuSetHandler 是 Mybatis 把 ResultSet 集合映射成 POJO 的接口对象(可以定义插件对Mybatis 的结果集自动映射进行修改)。
2.2 自定义拦截器(分页插件)
只需要实现 interceptor 接口,并指定想要拦截的方法签名即可。
@Intercepts(
@Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class,Integer.class}
)
)
public class MyPageInterceptor implements Interceptor {
}
属性名称 | 属性作用 |
@Intercepts | 标记这是一个interceptor |
@Signature | 定义拦截点 |
@type | 拦截对象 |
@method | 拦截对象中的某一个方法 |
@args | 拦截方法上对应的参数 |
2.3 接口interceptor方法
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
2.4 实现过程
Mybatis 在执行 sql 语句前会产生一个包含 Sql 语句的 Statement 对象,在 生成 statement 之前修改 sql 语句,把 原来的sql 语句改成对应分页查询 sql 语句。
2.5 将插件注册到全局配置文件中
<plugins>
<plugin interceptor="com.interceptor.MyPageInterceptor">
<property name="start" value="0"/>
<property name="end" value="3"/>
</plugin>
</plugins>
2.6 具体代码
public class MyPageInterceptor implements Interceptor {
private String start;
private String end;
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget();
MetaObject metaObject = SystemMetaObject.forObject(target);
String oldSql = metaObject.getValue("delegate.boundSql.sql").toString();
System.out.println("oldSql:"+oldSql);
String newSql = oldSql+" limit "+start+","+end;
System.out.println("newSql"+newSql);
metaObject.setValue("delegate.boundSql.sql",newSql);
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
if(target instanceof StatementHandler){
return Plugin.wrap(target, this);
}
return target;
}
@Override
public void setProperties(Properties properties) {
start = properties.getProperty("start");
end = properties.getProperty("end");
}
}
3. 通用mapper
2. 使用通用 Mapper
通用mapper的作用,在mybatis框架基础上,封装了单表增删改查的操作(不需要定义mapper文件,就可以实现相应功能)
3.1 加 jar
<dependency>
<groupId>com.github.abel533</groupId>
<artifactId>mapper</artifactId>
<version>3.0.1</version>
</dependency>
3.2 配置插件(Mapper在Mybtis的拦截器)
<plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor">
<!--主键自增回写方法,默认值MYSQL -->
<!--<property name="IDENTITY" value="MYSQL" />-->
<!--通用Mapper默认接口,我们定义的Mapper需要实现该接口 -->
<property name="mappers" value="com.github.abel533.mapper.Mapper" />
</plugin>
3.3 编写接口继承Mapper
public interface IGoodsDaoCo extends Mapper<Goods> {
}
3.4 配置实体类与表之间的关系
@Data
@Table(name = "tb_goods")
public class Goods implements Serializable {
@Id
private Integer goodsId;
@Column(name = "goods_name")
private String goodsName;
private Double price;
private Date produceDate;
private String address;
private Integer categoryId;
}
3.5 测试
@Test
public void IGoodsDaoCo(){
IGoodsDaoCo mapper = session.getMapper(IGoodsDaoCo.class);
List<Goods> select = mapper.select(null);
System.out.println(select);
Goods goods = mapper.selectByPrimaryKey(19);
System.out.println(goods);
session.close();
}
自定义条件查询:
@Test
public void testSelectByExample(){
Example example = new Example(Goods.class);
example.createCriteria().andBetween("goodsId",15,19);
example.or(example.createCriteria().andLike("goodsName","%茶%"));
example.setOrderByClause("goodsId desc");
IGoodsDaoCo mapper = session.getMapper(IGoodsDaoCo.class);
mapper.selectByExample(example).forEach(System.out::println);
}
3.6 小结
4. 逆向工程
通过逆向工程插件(代码生成工具),根据数据库中的表,自动生成Java代码类。
MyBatis Generator Core – Introduction to MyBatis Generator
4.1 jar
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
4.2 配置文件(单独的)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<!-- 配置pojo的序列化 -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="false" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/lay-first?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai" userId="root"
password="123456">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.entity"
targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.mapper"
targetProject=".\src\main\resources">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.mapper"
targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table schema="" tableName="tb_goods" enableCountByExample="false" domainObjectName="Goods"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"
/>
</context>
</generatorConfiguration>
4.3 测试类(生成代码)
@Test
public void generator() throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//指定 逆向工程配置文件
File configFile = new File("E:\\Desktop\\Java_dev\\0819\\MBG\\src\\main\\resources\\mybatis-config-gen.xml");
//配置解析器
ConfigurationParser cp = new ConfigurationParser(warnings);
//配置对象
Configuration config = cp.parseConfiguration(configFile);
//回调设置
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
//构建mybatis代码生成工具对象
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
//进行代码生成
myBatisGenerator.generate(null);
}