标签: mybatis
- 最近在折腾一个项目,持久层用的是mybatis,遇到一些之前没有遇到的东西,记录下
- 首先我们可以通过mybatsi-generator自动生成数据库对应的javaBean、mapper等
- 新建一个数据库表file
CREATE TABLE file(
fileid INT NOT NULL PRIMARY KEY,
filename VARCHAR NOT NULL
)ENGINE=innoDB DEFAULT CHARSET=utf8;
- 新建一个web maven项目,并在pom.xml加入mybatis-generator的插件
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>${mybatis.generator.version}</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
- 在项目的resouece目录下建立一个generatorConfig.xml文件,在里面配置数据库的连接、自动生成那些数据库表,已经生成数据存放的位置等信息
<?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>
<!--指定特定数据库的jdbc驱动jar包的位置 -->
<classPathEntry location="D:\\m2\\respository\\mysql\\mysql-connector-java\\5.1.29\\mysql-connector-java-5.1.29.jar"/>
<context id="default" targetRuntime="MyBatis3">
<!-- optional,旨在创建class时,对注释进行控制 true:不生成-->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--jdbc的数据库连接 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=UTF-8" userId="root" password="....">
</jdbcConnection>
<!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
targetPackage 指定生成的model生成所在的包名
targetProject 指定在该项目下所在的路径
-->
<javaModelGenerator targetPackage="com.module" targetProject="src/main/java">
<!-- 是否对model添加 构造函数 -->
<property name="constructorBased" value="true"/>
<!-- 是否允许子包,即targetPackage.schemaName.tableName -->
<property name="enableSubPackages" value="false"/>
<!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 -->
<property name="immutable" value="false"/>
<!-- 给Model添加一个父类 -->
<!--<property name="rootClass" value=""/>-->
<!-- 是否对类CHAR类型的列的数据进行trim操作 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
<sqlMapGenerator targetPackage="com.module" targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
-->
<javaClientGenerator targetPackage="com.module" targetProject="src/main/java" type="XMLMAPPER">
<property name="enableSubPackages" value=""/>
<!--
定义Maper.java 源代码中的ByExample() 方法的可视性,可选的值有:
public;
private;
protected;
default
注意:如果 targetRuntime="MyBatis3",此参数被忽略
-->
<property name="exampleMethodVisibility" value=""/>
<!--
方法名计数器
Important note: this property is ignored if the target runtime is MyBatis3.
-->
<property name="methodNameCalculator" value=""/>
<!--
为生成的接口添加父接口
-->
<property name="rootInterface" value=""/>
</javaClientGenerator>
<!--需要生成的表 tableName:数据库中表的表名 domainObjectName:生成映射类的类名,不指定就为当前的表名-->
<table tableName="file" domainObjectName="File"/>
</context>
</generatorConfiguration>
- 在table标签中还有一些配置是否允许生成example类等,默认是允许,一开始的时候我认为这些是不需要生成,但是我觉得生成example肯定有其他的作用,可以在table标签中设置下列属性,也可以不设置,因为默认是允许的
enableCountByExample="true" enableDeleteByPrimaryKey="true" enableUpdateByExample="true" enableSelectByExample="true" enableDeleteByExample="true"
- 使用maven+mybatis-generator插件自动生成,使用命令
mybatis-generator:generate -e
当看到build success就可以了,这个时候代码也都自动生成了
打开我们的module层会发现多出来了一个FileExample
- 这个FileExample应该是File类的工具类,也是模板类,我们可以使用这个类进行任意我们需要的查询条件附上核心方法
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria andFileidIsNull() {
addCriterion("fileid is null");
return (Criteria) this;
}
public Criteria andFileidIsNotNull() {
addCriterion("fileid is not null");
return (Criteria) this;
}
public Criteria andFileidEqualTo(Integer value) {
addCriterion("fileid =", value, "fileid");
return (Criteria) this;
}
public Criteria andFileidNotEqualTo(Integer value) {
addCriterion("fileid <>", value, "fileid");
return (Criteria) this;
}
public Criteria andFileidGreaterThan(Integer value) {
addCriterion("fileid >", value, "fileid");
return (Criteria) this;
}
public Criteria andFileidGreaterThanOrEqualTo(Integer value) {
addCriterion("fileid >=", value, "fileid");
return (Criteria) this;
}
public Criteria andFileidLessThan(Integer value) {
addCriterion("fileid <", value, "fileid");
return (Criteria) this;
}
public Criteria andFileidLessThanOrEqualTo(Integer value) {
addCriterion("fileid <=", value, "fileid");
return (Criteria) this;
}
public Criteria andFileidIn(List<Integer> values) {
addCriterion("fileid in", values, "fileid");
return (Criteria) this;
}
public Criteria andFileidNotIn(List<Integer> values) {
addCriterion("fileid not in", values, "fileid");
return (Criteria) this;
}
public Criteria andFileidBetween(Integer value1, Integer value2) {
addCriterion("fileid between", value1, value2, "fileid");
return (Criteria) this;
}
public Criteria andFileidNotBetween(Integer value1, Integer value2) {
addCriterion("fileid not between", value1, value2, "fileid");
return (Criteria) this;
}
public Criteria andFilenameIsNull() {
addCriterion("filename is null");
return (Criteria) this;
}
public Criteria andFilenameIsNotNull() {
addCriterion("filename is not null");
return (Criteria) this;
}
public Criteria andFilenameEqualTo(String value) {
addCriterion("filename =", value, "filename");
return (Criteria) this;
}
public Criteria andFilenameNotEqualTo(String value) {
addCriterion("filename <>", value, "filename");
return (Criteria) this;
}
public Criteria andFilenameGreaterThan(String value) {
addCriterion("filename >", value, "filename");
return (Criteria) this;
}
public Criteria andFilenameGreaterThanOrEqualTo(String value) {
addCriterion("filename >=", value, "filename");
return (Criteria) this;
}
public Criteria andFilenameLessThan(String value) {
addCriterion("filename <", value, "filename");
return (Criteria) this;
}
public Criteria andFilenameLessThanOrEqualTo(String value) {
addCriterion("filename <=", value, "filename");
return (Criteria) this;
}
public Criteria andFilenameLike(String value) {
addCriterion("filename like", value, "filename");
return (Criteria) this;
}
public Criteria andFilenameNotLike(String value) {
addCriterion("filename not like", value, "filename");
return (Criteria) this;
}
public Criteria andFilenameIn(List<String> values) {
addCriterion("filename in", values, "filename");
return (Criteria) this;
}
public Criteria andFilenameNotIn(List<String> values) {
addCriterion("filename not in", values, "filename");
return (Criteria) this;
}
public Criteria andFilenameBetween(String value1, String value2) {
addCriterion("filename between", value1, value2, "filename");
return (Criteria) this;
}
public Criteria andFilenameNotBetween(String value1, String value2) {
addCriterion("filename not between", value1, value2, "filename");
return (Criteria) this;
}
- 通过这个example类已经它的内部类,可以进行任何查询语句
FileMapper.java
package com.bim.module;
import com.bim.module.File;
import com.bim.module.FileExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
@Component
public interface FileMapper {
int countByExample(FileExample example);
int deleteByExample(FileExample example);
int deleteByPrimaryKey(Integer fileid);
int insert(File record);
int insertSelective(File record);
List<File> selectByExample(FileExample example);
File selectByPrimaryKey(Integer fileid);
int updateByExampleSelective(@Param("record") File record, @Param("example") FileExample example);
int updateByExample(@Param("record") File record, @Param("example") FileExample example);
int updateByPrimaryKeySelective(File record);
int updateByPrimaryKey(File record);
}
- 再通过FileMapper.xml中mybatis的判断语句进行判断那些条件是满足的为空的就跳过不查询
<sql id="Example_Where_Clause" >
<where >
<foreach collection="oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
- 比如我们要查询一个文件名为test的文件,可以这样查
FileExample fileExample = new FileExample();
FileExample.Criteria criteria = fileExample.createCriteria();
criteria.andFilenameEqualTo("test");
List<File> list = fileMapper.selectByExample(fileExample);
等同于sql
select * from file where filename='test';
- 基本原理:就是将查询条件与在一起,当需要或者条件是调用or函数即可
sql形式:
select * from tableName where (? AND ?...) OR (? AND ? ..) OR(...)
还有其他高级的用法,比如查询符合在两个数之间的值的记录等也都能轻松实现
FileExample fileExample1 = new FileExample();
FileExample.Criteria criteria1 = fileExample1.createCriteria();
criteria.andFileidBetween(1, 2);
List<File> list1 = fileMapper.selectByExample(fileExample1);
将FileExample声明为类的成员变量在需要使用到地方clear,就能继续使用
private FileExample fileExample1 = new FileExample();
public List<File> getFiles(int first,int second){
fileExample1.clear();
fileExample1.or().andFileidBetween(first, second);
return fileMapper.selectByExample(fileExample1);
}