MyBatis Generator 工具能夠用來生成一些工具類和XML模板,用於爲用戶使用Java語言訪問數據庫提供便利。java
我使用的數據庫版本爲Oracle11g,JDK版本爲1.8。sql
建表語句以下:數據庫
CREATE TABLE PERSON_INFO ( ID NUMBER(12, 0) PRIMARY KEY, NAME VARCHAR(50), COMPANY VARCHAR(200) ); INSERT INTO PERSON_INFO (ID, NAME, COMPANY) VALUES (1, 'Tsybius', 'Dog Head Inc'); INSERT INTO PERSON_INFO (ID, NAME, COMPANY) VALUES (2, 'Galatea', 'Dog Head Inc'); INSERT INTO PERSON_INFO (ID, NAME, COMPANY) VALUES (3, 'Quintus', 'Dog Head Inc'); INSERT INTO PERSON_INFO (ID, NAME, COMPANY) VALUES (4, 'Gaius', 'State Grid Corporation of Mars'); INSERT INTO PERSON_INFO (ID, NAME, COMPANY) VALUES (5, 'Titus', 'Tyrannosaurus Company Limited'); INSERT INTO PERSON_INFO (ID, NAME, COMPANY) VALUES (6, 'Test1', 'Dog Head%'); INSERT INTO PERSON_INFO (ID, NAME, COMPANY) VALUES (7, 'Test2', 'Dog Head%Test'); INSERT INTO PERSON_INFO (ID, NAME, COMPANY) VALUES (8, 'Test3', 'Test%Dog Head%Test'); COMMIT; /
若是咱們要在這個表中查詢全部COMPANY字段包含「Head%」的數據,能夠使用下面的SQL:apache
SELECT * FROM PERSON_INFO WHERE COMPANY LIKE '%Dog Head/%%' ESCAPE '/' ORDER BY ID ASC
查詢結果以下:session
咱們使用 MyBatis Generator 工具生成四個文件:mybatis
一、PersonInfoMapper.javaoracle
二、PersonInfoMapper.xmlapp
三、PersonInfo.javaide
四、PersonInfoExample.java函數
生成方法可參考下面兩篇博客:
一、http://my.oschina.net/Tsybius2014/blog/676973
二、http://my.oschina.net/Tsybius2014/blog/678840
PersonInfoExample類中會生成andNameLike、andNameNotLike、andCompanyLike、andCompanyNotLike四個函數,但這四個函數並不能知足咱們上面例子中的要求:一是傳入的value必須左右手工添加百分號,二是這樣傳入的value不能支持查詢「%」和「_」兩個通配符(即oracle中的escape關鍵字)
爲了支持在模糊查詢時能夠準確查詢出通配符「_」和「%」,須要對PersonInfoExample.java和PersonInfoMapper.xml進行修改。
一、對PersonInfoExample.java的改動
修改的部分都用「【新加入的代碼】」作了標記,改動的地方包括:
1)對全部Like和NotLike函數都作了改造
2)新加了一個布爾型的變量escapeValue,用於標記Like和NotLike須要轉義
3)爲Criterion類新加了一個構造函數,用於爲Like和NotLike兩類條件建立Criterion
package GenTarget.object_example_java; import java.util.ArrayList; import java.util.List; public class PersonInfoExample { protected String orderByClause; protected boolean distinct; protected List<Criteria> oredCriteria; public PersonInfoExample() { oredCriteria = new ArrayList<Criteria>(); } public void setOrderByClause(String orderByClause) { this.orderByClause = orderByClause; } public String getOrderByClause() { return orderByClause; } public void setDistinct(boolean distinct) { this.distinct = distinct; } public boolean isDistinct() { return distinct; } public List<Criteria> getOredCriteria() { return oredCriteria; } public void or(Criteria criteria) { oredCriteria.add(criteria); } public Criteria or() { Criteria criteria = createCriteriaInternal(); oredCriteria.add(criteria); return criteria; } public Criteria createCriteria() { Criteria criteria = createCriteriaInternal(); if (oredCriteria.size() == 0) { oredCriteria.add(criteria); } return criteria; } protected Criteria createCriteriaInternal() { Criteria criteria = new Criteria(); return criteria; } public void clear() { oredCriteria.clear(); orderByClause = null; distinct = false; } protected abstract static class GeneratedCriteria { protected List<Criterion> criteria; protected GeneratedCriteria() { super(); criteria = new ArrayList<Criterion>(); } public boolean isValid() { return criteria.size() > 0; } public List<Criterion> getAllCriteria() { return criteria; } public List<Criterion> getCriteria() { return criteria; } protected void addCriterion(String condition) { if (condition == null) { throw new RuntimeException("Value for condition cannot be null"); } criteria.add(new Criterion(condition)); } protected void addCriterion(String condition, Object value, String property) { if (value == null) { throw new RuntimeException("Value for " + property + " cannot be null"); } criteria.add(new Criterion(condition, value)); } protected void addCriterion(String condition, Object value1, Object value2, String property) { if (value1 == null || value2 == null) { throw new RuntimeException("Between values for " + property + " cannot be null"); } criteria.add(new Criterion(condition, value1, value2)); } /** * 【新加入的代碼】生成帶有轉義字符的Criterion * @param condition * @param value1 * @param value2 * @param property */ protected void addCriterionEscape(String condition, Object value1, Object value2, String property) { if (value1 == null || value2 == null) { throw new RuntimeException("Value or escape for " + property + " cannot be null"); } criteria.add(new Criterion(condition, value1, value2, null, null)); } public Criteria andIdIsNull() { addCriterion("ID is null"); return (Criteria) this; } public Criteria andIdIsNotNull() { addCriterion("ID is not null"); return (Criteria) this; } public Criteria andIdEqualTo(Long value) { addCriterion("ID =", value, "id"); return (Criteria) this; } public Criteria andIdNotEqualTo(Long value) { addCriterion("ID <>", value, "id"); return (Criteria) this; } public Criteria andIdGreaterThan(Long value) { addCriterion("ID >", value, "id"); return (Criteria) this; } public Criteria andIdGreaterThanOrEqualTo(Long value) { addCriterion("ID >=", value, "id"); return (Criteria) this; } public Criteria andIdLessThan(Long value) { addCriterion("ID <", value, "id"); return (Criteria) this; } public Criteria andIdLessThanOrEqualTo(Long value) { addCriterion("ID <=", value, "id"); return (Criteria) this; } public Criteria andIdIn(List<Long> values) { addCriterion("ID in", values, "id"); return (Criteria) this; } public Criteria andIdNotIn(List<Long> values) { addCriterion("ID not in", values, "id"); return (Criteria) this; } public Criteria andIdBetween(Long value1, Long value2) { addCriterion("ID between", value1, value2, "id"); return (Criteria) this; } public Criteria andIdNotBetween(Long value1, Long value2) { addCriterion("ID not between", value1, value2, "id"); return (Criteria) this; } public Criteria andNameIsNull() { addCriterion("NAME is null"); return (Criteria) this; } public Criteria andNameIsNotNull() { addCriterion("NAME is not null"); return (Criteria) this; } public Criteria andNameEqualTo(String value) { addCriterion("NAME =", value, "name"); return (Criteria) this; } public Criteria andNameNotEqualTo(String value) { addCriterion("NAME <>", value, "name"); return (Criteria) this; } public Criteria andNameGreaterThan(String value) { addCriterion("NAME >", value, "name"); return (Criteria) this; } public Criteria andNameGreaterThanOrEqualTo(String value) { addCriterion("NAME >=", value, "name"); return (Criteria) this; } public Criteria andNameLessThan(String value) { addCriterion("NAME <", value, "name"); return (Criteria) this; } public Criteria andNameLessThanOrEqualTo(String value) { addCriterion("NAME <=", value, "name"); return (Criteria) this; } /** * 【新加入的代碼】模糊查詢 * @param value * @return */ public Criteria andNameLike(String value) { if(value != null){ value = value.replaceAll("/", "//").replaceAll("%", "/%").replaceAll("_", "/_"); value = "%" + value + "%"; } addCriterionEscape("NAME like", value, "/", "name"); return (Criteria) this; } /** * 【新加入的代碼】模糊查詢 * @param value * @return */ public Criteria andNameNotLike(String value) { //模糊匹配的通配符 if(value != null){ value = value.replaceAll("/", "//").replaceAll("%", "/%").replaceAll("_", "/_"); value = "%" + value + "%"; } addCriterionEscape("NAME not like", value, "/", "name"); return (Criteria) this; } public Criteria andNameIn(List<String> values) { addCriterion("NAME in", values, "name"); return (Criteria) this; } public Criteria andNameNotIn(List<String> values) { addCriterion("NAME not in", values, "name"); return (Criteria) this; } public Criteria andNameBetween(String value1, String value2) { addCriterion("NAME between", value1, value2, "name"); return (Criteria) this; } public Criteria andNameNotBetween(String value1, String value2) { addCriterion("NAME not between", value1, value2, "name"); return (Criteria) this; } public Criteria andCompanyIsNull() { addCriterion("COMPANY is null"); return (Criteria) this; } public Criteria andCompanyIsNotNull() { addCriterion("COMPANY is not null"); return (Criteria) this; } public Criteria andCompanyEqualTo(String value) { addCriterion("COMPANY =", value, "company"); return (Criteria) this; } public Criteria andCompanyNotEqualTo(String value) { addCriterion("COMPANY <>", value, "company"); return (Criteria) this; } public Criteria andCompanyGreaterThan(String value) { addCriterion("COMPANY >", value, "company"); return (Criteria) this; } public Criteria andCompanyGreaterThanOrEqualTo(String value) { addCriterion("COMPANY >=", value, "company"); return (Criteria) this; } public Criteria andCompanyLessThan(String value) { addCriterion("COMPANY <", value, "company"); return (Criteria) this; } public Criteria andCompanyLessThanOrEqualTo(String value) { addCriterion("COMPANY <=", value, "company"); return (Criteria) this; } /** * 【新加入的代碼】模糊查詢 * @param value * @return */ public Criteria andCompanyLike(String value) { //模糊匹配的通配符 if(value != null){ value = value.replaceAll("/", "//").replaceAll("%", "/%").replaceAll("_", "/_"); value = "%" + value + "%"; } addCriterionEscape("COMPANY like", value, "/", "company"); return (Criteria) this; } /** * 【新加入的代碼】模糊查詢 * @param value * @return */ public Criteria andCompanyNotLike(String value) { if(value != null){ value = value.replaceAll("/", "//").replaceAll("%", "/%").replaceAll("_", "/_"); value = "%" + value + "%"; } addCriterionEscape("COMPANY not like", value, "/", "company"); return (Criteria) this; } public Criteria andCompanyIn(List<String> values) { addCriterion("COMPANY in", values, "company"); return (Criteria) this; } public Criteria andCompanyNotIn(List<String> values) { addCriterion("COMPANY not in", values, "company"); return (Criteria) this; } public Criteria andCompanyBetween(String value1, String value2) { addCriterion("COMPANY between", value1, value2, "company"); return (Criteria) this; } public Criteria andCompanyNotBetween(String value1, String value2) { addCriterion("COMPANY not between", value1, value2, "company"); return (Criteria) this; } } public static class Criteria extends GeneratedCriteria { protected Criteria() { super(); } } public static class Criterion { private String condition; private Object value; private Object secondValue; private boolean noValue; private boolean singleValue; private boolean betweenValue; /** 【新加入的代碼】爲true時按轉義字符處理添加escape關鍵字 */ private boolean escapeValue; private boolean listValue; private String typeHandler; public String getCondition() { return condition; } public Object getValue() { return value; } public Object getSecondValue() { return secondValue; } public boolean isNoValue() { return noValue; } public boolean isSingleValue() { return singleValue; } public boolean isBetweenValue() { return betweenValue; } /** * 【新加入的代碼】爲true時按轉義字符處理添加escape關鍵字 * @return */ public boolean isEscapeValue() { return escapeValue; } public boolean isListValue() { return listValue; } public String getTypeHandler() { return typeHandler; } protected Criterion(String condition) { super(); this.condition = condition; this.typeHandler = null; this.noValue = true; } protected Criterion(String condition, Object value, String typeHandler) { super(); this.condition = condition; this.value = value; this.typeHandler = typeHandler; if (value instanceof List<?>) { this.listValue = true; } else { this.singleValue = true; } } protected Criterion(String condition, Object value) { this(condition, value, null); } protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { super(); this.condition = condition; this.value = value; this.secondValue = secondValue; this.typeHandler = typeHandler; this.betweenValue = true; } protected Criterion(String condition, Object value, Object secondValue) { this(condition, value, secondValue, null); } /** * 【新加入的代碼】生成帶有轉義字符的Criterion * @param condition * @param value * @param escapeValue * @param typeHandler * @param dummy */ protected Criterion(String condition, Object value, Object escapeValue, String typeHandler, Object dummy) { super(); this.condition = condition; this.value = value; this.secondValue = escapeValue; this.typeHandler = typeHandler; this.escapeValue = true; } } }
二、對PersonInfoMapper.xml的改動
修改的部分都用「【新加入的代碼】」作了標記,改動的地方包括:
1)sql代碼段:Example_Where_Clause
2)sql代碼段:Update_By_Example_Where_Clause
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="GenTarget.mapper_java.PersonInfoMapper" > <resultMap id="BaseResultMap" type="GenTarget.object_example_java.PersonInfo" > <id column="ID" property="id" jdbcType="DECIMAL" /> <result column="NAME" property="name" jdbcType="VARCHAR" /> <result column="COMPANY" property="company" jdbcType="VARCHAR" /> </resultMap> <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> <!-- 【新加入的代碼】添加轉義字符 START --> <when test="criterion.escapeValue" > and ${criterion.condition} #{criterion.value} escape #{criterion.secondValue} </when> <!-- 【新加入的代碼】添加轉義字符 END --> <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> <sql id="Update_By_Example_Where_Clause" > <where > <foreach collection="example.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> <!-- 【新加入的代碼】添加轉義字符 START --> <when test="criterion.escapeValue" > and ${criterion.condition} #{criterion.value} escape #{criterion.secondValue} </when> <!-- 【新加入的代碼】添加轉義字符 END --> <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> <sql id="Base_Column_List" > ID, NAME, COMPANY </sql> <select id="selectByExample" resultMap="BaseResultMap" parameterType="GenTarget.object_example_java.PersonInfoExample" > select <if test="distinct" > distinct </if> <include refid="Base_Column_List" /> from PERSON_INFO <if test="_parameter != null" > <include refid="Example_Where_Clause" /> </if> <if test="orderByClause != null" > order by ${orderByClause} </if> </select> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" > select <include refid="Base_Column_List" /> from PERSON_INFO where ID = #{id,jdbcType=DECIMAL} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.Long" > delete from PERSON_INFO where ID = #{id,jdbcType=DECIMAL} </delete> <delete id="deleteByExample" parameterType="GenTarget.object_example_java.PersonInfoExample" > delete from PERSON_INFO <if test="_parameter != null" > <include refid="Example_Where_Clause" /> </if> </delete> <insert id="insert" parameterType="GenTarget.object_example_java.PersonInfo" > insert into PERSON_INFO (ID, NAME, COMPANY ) values (#{id,jdbcType=DECIMAL}, #{name,jdbcType=VARCHAR}, #{company,jdbcType=VARCHAR} ) </insert> <insert id="insertSelective" parameterType="GenTarget.object_example_java.PersonInfo" > insert into PERSON_INFO <trim prefix="(" suffix=")" suffixOverrides="," > <if test="id != null" > ID, </if> <if test="name != null" > NAME, </if> <if test="company != null" > COMPANY, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides="," > <if test="id != null" > #{id,jdbcType=DECIMAL}, </if> <if test="name != null" > #{name,jdbcType=VARCHAR}, </if> <if test="company != null" > #{company,jdbcType=VARCHAR}, </if> </trim> </insert> <select id="countByExample" parameterType="GenTarget.object_example_java.PersonInfoExample" resultType="java.lang.Integer" > select count(*) from PERSON_INFO <if test="_parameter != null" > <include refid="Example_Where_Clause" /> </if> </select> <update id="updateByExampleSelective" parameterType="map" > update PERSON_INFO <set > <if test="record.id != null" > ID = #{record.id,jdbcType=DECIMAL}, </if> <if test="record.name != null" > NAME = #{record.name,jdbcType=VARCHAR}, </if> <if test="record.company != null" > COMPANY = #{record.company,jdbcType=VARCHAR}, </if> </set> <if test="_parameter != null" > <include refid="Update_By_Example_Where_Clause" /> </if> </update> <update id="updateByExample" parameterType="map" > update PERSON_INFO set ID = #{record.id,jdbcType=DECIMAL}, NAME = #{record.name,jdbcType=VARCHAR}, COMPANY = #{record.company,jdbcType=VARCHAR} <if test="_parameter != null" > <include refid="Update_By_Example_Where_Clause" /> </if> </update> <update id="updateByPrimaryKeySelective" parameterType="GenTarget.object_example_java.PersonInfo" > update PERSON_INFO <set > <if test="name != null" > NAME = #{name,jdbcType=VARCHAR}, </if> <if test="company != null" > COMPANY = #{company,jdbcType=VARCHAR}, </if> </set> where ID = #{id,jdbcType=DECIMAL} </update> <update id="updateByPrimaryKey" parameterType="GenTarget.object_example_java.PersonInfo" > update PERSON_INFO set NAME = #{name,jdbcType=VARCHAR}, COMPANY = #{company,jdbcType=VARCHAR} where ID = #{id,jdbcType=DECIMAL} </update> </mapper>
調用此功能的Java代碼以下:
package GenMyBatisTest; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import GenTarget.mapper_java.PersonInfoMapper; import GenTarget.object_example_java.PersonInfo; import GenTarget.object_example_java.PersonInfoExample; /** * MyBatis使用測試 * @author Tsybius2014 * @date 2016年5月22日 * @time 下午10:44:06 * @remark */ public class MyBatisTest { public static void main(String[] args) { try { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); try { PersonInfoMapper mapper = session.getMapper(PersonInfoMapper.class); //模糊查詢 PersonInfoExample example = new PersonInfoExample(); PersonInfoExample.Criteria criteria = example.createCriteria(); criteria.andCompanyLike("Dog Head%"); example.setOrderByClause("id desc"); List<PersonInfo> personInfoList = new ArrayList<PersonInfo>(); personInfoList.addAll(mapper.selectByExample(example)); if (personInfoList != null && personInfoList.size() > 0) { for (PersonInfo personInfo : personInfoList) { System.out.println( "id:" + personInfo.getId() + ";" + "name:" + personInfo.getName() + ";" + "company:" + personInfo.getCompany()); } } else { System.out.println("personInfoList is emply"); } System.out.println("done."); } finally { session.close(); } } catch (Exception ex) { StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); ex.printStackTrace(printWriter); System.out.println(stringWriter.toString()); } } }
Console中輸出的結果以下:
id:8;name:Test3;company:Test%Dog Head%Test id:7;name:Test2;company:Dog Head%Test id:6;name:Test1;company:Dog Head% done.
注:本文中介紹的只是實現此類功能的一種方法,僅供參考。
END