二Mybatis 常用工具类
Posted archerLuo罗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二Mybatis 常用工具类相关的知识,希望对你有一定的参考价值。
-
源码地址:https://github.com/RononoaZoro/mybatis-book/tree/master 的 mybatis-book ( mybatis-chapter03 )
-
文章内容出自《Mybatis 3 源码深度解析》第三章
资源文件 -
create-table.sql
drop table user if exists;
create table user (
id int generated by default as identity,
create_time varchar(20) ,
name varchar(20),
password varchar(36),
phone varchar(20),
nick_name varchar(20),
primary key (id)
);
- init-data.sql
insert into user (create_time, name, password, phone, nick_name) values('2010-10-23 10:20:30', 'User1', 'test', '18700001111', 'User1');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-24 10:20:30', 'User2', 'test', '18700001111', 'User2');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-25 10:20:30', 'User3', 'test', '18700001111', 'User3');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User4', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User5', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User6', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User7', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User8', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User9', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User10', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User11', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User12', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User13', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User14', 'test', '18700001111', 'User4');
1、使用 SQL 类生成语句
- SQL 类用于生成 sql 语句
package com.blog4java.mybatis;
import org.apache.ibatis.jdbc.SQL;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SQLExample {
@Test
public void testSelectSQL() {
String orgSql = "SELECT P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME, P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON\\n" +
"FROM PERSON P, ACCOUNT A\\n" +
"INNER JOIN DEPARTMENT D on D.ID = P.DEPARTMENT_ID\\n" +
"INNER JOIN COMPANY C on D.COMPANY_ID = C.ID\\n" +
"WHERE (P.ID = A.ID AND P.FIRST_NAME like ?) \\n" +
"OR (P.LAST_NAME like ?)\\n" +
"GROUP BY P.ID\\n" +
"HAVING (P.LAST_NAME like ?) \\n" +
"OR (P.FIRST_NAME like ?)\\n" +
"ORDER BY P.ID, P.FULL_NAME";
String newSql = new SQL() {{
SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME");
SELECT("P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON");
FROM("PERSON P");
FROM("ACCOUNT A");
INNER_JOIN("DEPARTMENT D on D.ID = P.DEPARTMENT_ID");
INNER_JOIN("COMPANY C on D.COMPANY_ID = C.ID");
WHERE("P.ID = A.ID");
WHERE("P.FIRST_NAME like ?");
OR();
WHERE("P.LAST_NAME like ?");
GROUP_BY("P.ID");
HAVING("P.LAST_NAME like ?");
OR();
HAVING("P.FIRST_NAME like ?");
ORDER_BY("P.ID");
ORDER_BY("P.FULL_NAME");
}}.toString();
assertEquals(orgSql, newSql);
}
@Test
public void testDynamicSQL() {
selectPerson(null,null,null);
}
public String selectPerson(final String id, final String firstName, final String lastName) {
return new SQL() {{
SELECT("P.ID, P.USERNAME, P.PASSWORD");
SELECT("P.FIRST_NAME, P.LAST_NAME");
FROM("PERSON P");
if (id != null) {
WHERE("P.ID = #{id}");
}
if (firstName != null) {
WHERE("P.FIRST_NAME = #{firstName}");
}
if (lastName != null) {
WHERE("P.LAST_NAME = #{lastName}");
}
ORDER_BY("P.LAST_NAME");
}}.toString();
}
@Test
public void testInsertSql() {
String insertSql = new SQL().
INSERT_INTO("PERSON").
VALUES("ID, FIRST_NAME", "#{id}, #{firstName}").
VALUES("LAST_NAME", "#{lastName}").toString();
System.out.println(insertSql);
}
@Test
public void testDeleteSql() {
String deleteSql = new SQL() {{
DELETE_FROM("PERSON");
WHERE("ID = #{id}");
}}.toString();
System.out.println(deleteSql);
}
@Test
public void testUpdateSql() {
String updateSql = new SQL() {{
UPDATE("PERSON");
SET("FIRST_NAME = #{firstName}");
WHERE("ID = #{id}");
}}.toString();
System.out.println(updateSql);
}
}
2、使用 ScriptRunner 执行脚本
- ScriptRunner 类用于执行外部资源的 sql 脚本
package com.blog4java.mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
public class ScriptRunnerExample {
@Test
public void testScriptRunner() {
try {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mybatis",
"sa", "");
ScriptRunner scriptRunner = new ScriptRunner(connection);
scriptRunner.runScript(Resources.getResourceAsReader("create-table.sql"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、使用 SqlRunner 操作数据库
- SqlRunner 用于执行 sql 语句
package com.blog4java.mybatis;
import com.alibaba.fastjson.JSON;
import com.blog4java.common.IOUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.apache.ibatis.jdbc.SqlRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
public class SqlRunnerExample {
Connection connection = null;
@Before
public void initTable() throws SQLException, IOException {
connection = DriverManager.getConnection("jdbc:hsqldb:mem:mybatis",
"sa", "");
ScriptRunner scriptRunner = new ScriptRunner(connection);
scriptRunner.setLogWriter(null);
scriptRunner.runScript(Resources.getResourceAsReader("create-table.sql"));
scriptRunner.runScript(Resources.getResourceAsReader("init-data.sql"));
}
@Test
public void testSelectOne() throws SQLException {
SqlRunner sqlRunner = new SqlRunner(connection);
String qryUserSql = new SQL() {{
SELECT("*");
FROM("user");
WHERE("id = ?");
}}.toString();
Map<String, Object> resultMap = sqlRunner.selectOne(qryUserSql, Integer.valueOf(1));
System.out.println(JSON.toJSONString(resultMap));
}
@Test
public void testDelete() throws SQLException {
SqlRunner sqlRunner = new SqlRunner(connection);
String deleteUserSql = new SQL(){{
DELETE_FROM("user");
WHERE("id = ?");
}}.toString();
sqlRunner.delete(deleteUserSql, Integer.valueOf(1));
}
@Test
public void testUpdate() throws SQLException {
SqlRunner sqlRunner = new SqlRunner(connection);
String updateUserSql = new SQL(){{
UPDATE("user");
SET("nick_name = ?");
WHERE("id = ?");
}}.toString();
sqlRunner.update(updateUserSql, "Jane", Integer.valueOf(1));
}
@Test
public void testInsert() throws SQLException {
SqlRunner sqlRunner = new SqlRunner(connection);
String insertUserSql = new SQL(){{
INSERT_INTO("user");
INTO_COLUMNS("create_time,name,password,phone,nick_name");
INTO_VALUES("?,?,?,?,?");
}}.toString();
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
sqlRunner.insert(insertUserSql,createTime,"Jane","test","18700000000","J");
}
@After
public void closeConnection() {
IOUtils.closeQuietly(connection);
}
}
4、MetaObject 详解
- MetaObject 用于通过反射获取和设置对象的属性值
package com.blog4java.mybatis;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class MetaObjectExample {
@Data
@AllArgsConstructor
private static class User {
List<Order> orders;
String name;
Integer age;
}
@Data
@AllArgsConstructor
private static class Order {
String orderNo;
String goodsName;
}
@Test
public void testMetaObject() {
List<Order> orders = new ArrayList() {
{
add(new Order("order20171024010246", "《Mybatis源码深度解析》图书"));
add(new Order("order20171024010248", "《AngularJS入门与进阶》图书"));
}
};
User user = new User(orders, "archerLuo", 3);
MetaObject metaObject = SystemMetaObject.forObject(user);
// 获取第一笔订单的商品名称
System.out.println(metaObject.getValue("orders[0].goodsName"));
// 获取第二笔订单的商品名称
System.out.println(metaObject.getValue("orders[1].goodsName"));
// 为属性设置值
metaObject.setValue("orders[1].orderNo","order20181113010139");
// 判断User对象是否有orderNo属性
System.out.println("是否有orderNo属性且orderNo属性有对应的Getter方法:" + metaObject.hasGetter("orderNo"));
// 判断User对象是否有name属性
System.out.println("是否有name属性且orderNo属性有对应的name方法:" + metaObject.hasGetter("name"));
}
}
5、MetaClass 详解
- MetaClass 用于获取类(对象的 Class 对象)的信息
package com.blog4java.mybatis;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaClass;
import org.apache.ibatis.reflection.invoker.Invoker;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
public class MetaClassExample {
@Data
@AllArgsConstructor
private static class Order {
String orderNo;
String goodsName;
}
@Test
public void testMetaClass() {
MetaClass metaClass = MetaClass.forClass(Order.class, new DefaultReflectorFactory());
// 获取所有有Getter方法的属性名
String[] getterNames = metaClass.getGetterNames();
System.out.println(JSON.toJSONString(getterNames));
// 是否有默认构造方法
System.out.println("是否有默认构造方法:" + metaClass.hasDefaultConstructor());
// 某属性是否有对应的Getter/Setter方法
System.out.println("orderNo属性是否有对应的Getter方法:" + metaClass.hasGetter("orderNo"));
System.out.println("orderNo属性是否有对应的Setter方法:" + metaClass.hasSetter("orderNo"));
System.out.println("orderNo属性类型:" + metaClass.getGetterType("orderNo"));
// 获取属性Getter方法
Invoker invoker = metaClass.getGetInvoker("orderNo");
try {
// 通过Invoker对象调用Getter方法获取属性值
Object orderNo = invoker.invoke(new Order("order20171024010248","《Mybatis源码深度解析》图书"), null);
System.out.println(orderNo);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
6、ObjectFactory 详解
- ObjectFactory 用于生成所需的通用对象
package com.blog4java.mybatis;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
impo以上是关于二Mybatis 常用工具类的主要内容,如果未能解决你的问题,请参考以下文章
Springboot Mybatis Plus代码自动生成工具类
Springboot Mybatis Plus代码自动生成工具类