越简单越好用,越直接越高效。封装JDBC的SQL执行框架,一款简单的ORM微框架。
ideas gathering....
一个轻ORM框架,一个JDBC小工具
面向域的操作风格
单表零SQL增删改查与分页
安全的字符串SQL模版引擎,简单直观高效可扩展
只需在数据库创建一张表,填入一行数据,少量配置,一键生成实体
还有什么?....先来试试看....从建一张表开始,填一行数据,....
如果觉得还可以,您的点赞与star是我继续完善它并坚持的动力。
使实体继承TiEntity.class
在类名上添加注释@TiTable,并申明表名
如果太麻烦,使用 EntityBuilderFactory 生成实体,只需要定义好表,填入一行数据...
如果还太麻烦了,稍等等...,稍后再码一个更好的工具,expecting....
使用之前
需要使用TiDBPoolManager注册数据源,也可以通过TiGlobalConfig配置全局分页工厂
实体使用:
实体可以通过自带的工具一键生成
新建一个实体,继承TiEntity类,配置注解@TiColumn和@TiTable即可使用CRUD接口
CUD接口中,接口名分别为,insert,update,delete;各有无参,字符串SQL参,模版参等三种不同接口
R接口有,query,queryOne,queryList,queryMap,onlyOne,page,count等几种接口
count接口,用于统计记录数
如果是多表查询,你需要新建一个结果实体继承TiEntity类,再通过SqlFactory创建模版sql语句,并通过这个结果实体query接口执行; 如果你只想返回一个map对象,可以通过TiSimpleCore执行模版sql
若需要使用实体的分页,需要注册分页工厂或先注册全局分页工厂
若要新增数据时自动生成主键,需要在@TiColumn中指定主键生成策略
若要新增数据时自动校验非空,需要在@TiColumn中指定字段非空
若要更改字段的默认匹配方式,需要在@TiColumn中指定匹配策略
核心使用:
第一步,通过SqlFactory创建模版sql
第二步,通过TiSimpleCore的相关接口执行模版sql,并将结果转换为实体
package com.example.tisimple;
import com.gitee.oeoe.tisimple.core.TiDBPoolManager;
import com.gitee.oeoe.tisimple.core.TiGlobalConfig;
import com.gitee.oeoe.tisimple.page.mysql.MysqlPageFactory;
import com.gitee.oeoe.tisimple.template.SqlFactory;
import com.gitee.oeoe.tisimple.template.fun.ForeachFunc;
import com.mysql.cj.jdbc.MysqlDataSource;
/**
* 只需要创建任何一个连接池,注册到TiDBPoolManager即可
*/
public class TiConfig {
public static final String url = "jdbc:mysql://localhost:3306/alis";
public static final String username = "mime";
public static final String password = "123";
public static final String driver = "com.mysql.cj.jdbc.Driver";
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setURL(url);
dataSource.setUser(username);
dataSource.setPassword(password);
TiGlobalConfig.setGlobalPageFactory(MysqlPageFactory.class, 5);//注册全局分页工厂,设置默认分页大小
TiDBPoolManager.register(dataSource);//注册连接池
SqlFactory.registerFunc("foreach", ForeachFunc.class);//如果有自定义模版函数,注册模版函数
}
public static long id() {
return System.nanoTime();
}
}
更多使用方式和配置,请看示例项目example-single和example-spring
package com.example.tisimple.advance;
import com.example.tisimple.TiConfig;
import com.example.tisimple.domain.User;
import com.gitee.oeoe.tisimple.page.IPage;
import org.junit.jupiter.api.Test;
import java.util.LinkedList;
import java.util.List;
/**
* 基本功能演示
*/
public class PrimerTest {
static {
TiConfig.id();
}
@Test
void insert() {
User user = new User();
user.setName("测试1");
user.setId(null);//id是int类型的自增,所以这里可以不用设置,可注释掉
user.setAge(9);
user.setAddress("china");
//任何null的属性都将被忽略
int insert = user.insert();
System.out.println(user);
assert insert == 1 : "insert 失败";
}
@Test
void insertBatch() {
List<User> users = new LinkedList<>();//使用linkedList
for (int i = 0; i < 100; i++) {
User user = new User();
user.setName("测试batch" + i);
user.setId(null);//id是int类型的自增,所以这里可以不用设置,可注释掉
user.setAge(i);
user.setAddress("china");
users.add(user);
}
User user = new User();
int insert = user.insert(users);
System.out.println("batch insert rows:" + insert);
System.out.println("look for:\n" + users);//自增id将会被自动设置
}
@Test
void delete() {
User condition = new User();
condition.setName("测试1");
int delete = condition.delete();
System.out.println("delete rows:" + delete);
}
@Test
void update() {
User condition = new User();
condition.setName("测试1");
User up = new User();
up.setAge(99);
up.setAddress("earth");
System.out.println("update before:" + condition.query());
int update = condition.update(up);
System.out.println("update rows:" + update);
System.out.println("update after:" + condition.query());
}
@Test
void page() {
//分页功能必须在注册分页工厂后才能使用,否则将返回null
User condition = new User();
//设置查询条件
condition.setAddress("china");
//本身有默认参数,也可设置分页参数,默认参数在注册分页工厂的时候设置
condition.pageSize(10);//分页大小
condition.pageIndex(1);//当前分页索引
IPage<User> page = condition.page();
System.out.println("page result:\n" + page);
}
@Test
void query() {
User condition = new User();
condition.setName("测试1");
List<User> query = condition.query();
System.out.println("query result:\n" + query);
}
@Test
void onlyOne() {
//查询一条记录,如果返回多条,将抛出异常
//一般用于主键查询
User condition = new User();
condition.setName("测试1");
User one = condition.onlyOne();
System.out.println("query result:\n" + one);
}
@Test
void count() {
User condition = new User();
condition.setAddress("china");
Long count = condition.count();
System.out.println("count result:\n" + count);
}
}
package com.example.tisimple.advance;
import com.example.tisimple.TiConfig;
import com.example.tisimple.domain.Example;
import com.example.tisimple.domain.Order;
import com.gitee.oeoe.tisimple.page.IPage;
import com.gitee.oeoe.tisimple.page.mysql.MysqlPageFactory;
import com.gitee.oeoe.tisimple.template.ISQL;
import com.gitee.oeoe.tisimple.template.SqlFactory;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* 基于实体的进阶用法示例
*/
class AdvanceTest {
public static final Long serialVersionUID = TiConfig.id();
@Test
void insert() {
Order order = new Order();
order.setOrderTime(LocalDateTime.now());
order.setStatus(1);
order.setPayment("zfb");
order.setTotalMoney(BigDecimal.valueOf(335));
order.setActualAmountPaid(BigDecimal.valueOf(236.23));
order.setUserId("1");
order.setUserName("爱德华");
int insert = order.insert();
System.out.println(insert);
System.out.println("=============也可以指定主键自动生成工厂=============");
//在id 列的@TiColumn注解申明属性keyGenerateFactory 指定主键生成工厂UUIDFactory.class
//使用主键自动生成,看一下生成的主键
if (1 == insert) {
System.out.println(order.getId());
}
//自定义sql,对于单表的增删改,不建议使用自定义的sql,提供这些接口只是方便在某些极端业务下有可用的处理方式
String sql = "insert into k_order(id,status,user_id) values({id},{status},{userId})";
order.setId("1234567a");
int insert1 = order.insert(sql);
System.out.println(insert1);
}
@Test
void delete() {
Order condition = new Order();
condition.setStatus(5);
System.out.println(condition.delete());
//如果默认条件匹配不符合,也可以自定义删除sql
System.out.println("=============如果默认条件匹配不符合,也可以自定义删除sql===============");
condition.setOrderTime(LocalDateTime.now());
String sql = "delete from k_order where order_time>{orderTime}";
System.out.println(condition.delete(sql));
}
@Test
void update() {
Order condition = new Order();
condition.setId("12");
Order order = new Order();
order.setUserName("abc");
System.out.println(condition.update(order));
//与删除,都可以自定义更新sql
System.out.println("========自定义更新SQL==========");
//比如需要多表更新
condition.setOrderTime(LocalDateTime.now());
String sql = "update k_order,s_user set k_order.user_name=s_user.name where k_order.user_id=s_user.id and k_order.order_time>{orderTime}";
System.out.println(condition.update(sql));
//如果你需要添加额外的参数,可以这样写
System.out.println("========多表更新==========");
ArrayList<Integer> statusList = new ArrayList<>();
statusList.add(1);
statusList.add(2);
statusList.add(3);
sql = "update k_order,s_user set k_order.user_name=s_user.name where k_order.user_id=s_user.id and k_order.order_time>{orderTime} and status in [foreach@list#(|,|)]";
ISQL template = SqlFactory.sql(sql, condition).addParam("list", statusList);//statusList是一个列表,或是其他值
System.out.println(condition.update(template));
}
@Test
void query() {
Order condition = new Order();
List<Order> list = condition.query();
//设置查询条件值,默认所有字段匹配类型为等于
condition.setUserId("1");
System.out.println(condition.query());
System.out.println(list);
//如果默认的不能满足要求,也可以拼写自己的查询sql
System.out.println("=============指定sql语句==================");
String sql = "select id,status from k_order where order_time<{orderTime}";
condition.setOrderTime(LocalDateTime.now());
System.out.println(condition.queryList(sql));
System.out.println("=============更改字段的默认匹配方式==================");
//如果觉得对order_time字段的匹配方式所有地方都应该是小于,那就在Order.class 中的此字段上设置注解属性 fieldMatchTypeFactory
// @TiColumn(value="order_time",comment="下单时间",fieldMatchTypeFactory = LeTypeFactory.class)
// private java.time.LocalDateTime orderTime;
System.out.println(condition.query());
//如果发现Order中的属性都不满足自己的条件,需要额外添加条件
System.out.println("==========额外添加参数到参数空间==========");
ArrayList<Integer> statusList = new ArrayList<>();
statusList.add(1);
statusList.add(2);
statusList.add(3);
sql = "select id,status from k_order where status in [foreach@statusList#(|,|)]";
//一种更好的写法,select id,status from k_order [foreach@statusList#where status in(|,|)]
ISQL template = SqlFactory.sql(sql, condition);//先添加Order对象到参数空间
template.addParam("statusList", statusList);//再添加一个List参数到参数空间
System.out.println(condition.queryList(template));
//如果一个要查询多个表中的字段并返回,那么只需要新建一个实体包含这些字段,字段若是基本类型,必须用包装类,继承类TiEntity.class即可
System.out.println("==========多表查询,返回的字段来自多个表==========");
//所有继承类TiEntity.class的实体类都必须是一个public申明的类,意味着它不能是内部类,内部静态类
Example example = new Example();
sql = "select a.age,a.name as user_name,b.id as order_id from k_order b,s_user a where a.id=b.user_id and order_time<{orderTime}";
ISQL template1 = SqlFactory.sql(sql, condition);
System.out.println(example.queryList(template1));
}
@Test
void page() {
Order condition = new Order();
IPage<Order> page = condition.page();
System.out.println(page);
System.out.println("========设置分页参数=========");
//也可以手动设置分页大小
condition.pageSize(2);
condition.pageIndex(1);
System.out.println(condition.page());
System.out.println("========设置自己的分页工厂=========");
//如果你有自己的分页工厂,也可以指定此次使用的分页工厂
MysqlPageFactory factory = new MysqlPageFactory();
//也可以设置默认的分页大小
factory.setDefaultPageSize(5);
condition.setPageFactory(factory);
System.out.println(condition.page());
System.out.println("=========使用自己的分页查询SQL===========");
//如果觉得默认的分页查询方式不满足要求,也可以手动书写查询SQL
String sql = "select id,status from k_order where order_time<{orderTime}";
condition.setOrderTime(LocalDateTime.now());
System.out.println(condition.page(sql));
}
@Test
void count() {
Order condition = new Order();
System.out.println(condition.count());
System.out.println("========使用自己的统计方式============");
//如果默认的统计方式不符合要求,可以使用自己的统计sql
condition.setOrderTime(LocalDateTime.now());
String sql = "select count(*)as total from k_order b,s_user a where a.id=b.user_id and order_time<{orderTime}";
System.out.println(condition.queryCount(sql, "total"));
//也可以是这样的
System.out.println("===========也可以是这样的===============");
ArrayList<Integer> statusList = new ArrayList<>();
statusList.add(1);
statusList.add(2);
statusList.add(3);
sql = "select count(*) as sum from k_order where status in [foreach@list#(|,|)]";
ISQL template = SqlFactory.sql(sql, statusList);//sqlL()允许参数是一个list,会在参数空间给予默认参数名list
//如果你还需要Order对象中的参数作为条件,可以这样写 SqlTemplate.sqlO(sql, condition).addParam("list", statusList)
System.out.println(condition.queryCount(template, "sum"));//sum 为count(*)的别名
}
@Test
void queryList() {
Order condition = new Order();
String sql = "select id,status from k_order where order_time<{orderTime}";
condition.setOrderTime(LocalDateTime.now());
List<Order> objects = condition.queryList(sql);
System.out.println(objects);
}
@Test
void queryOne() {
}
@Test
void queryCount() {
}
@Test
void testPage() {
}
}
第一类:?占位符形式,使用 '?' 占位参数,参数将按照顺序填入
第二类:{1}序列编号形式,使用 '{number}' ,number指定参数的位置
第三类:命名参数形式,使用 '{varName}' 指定参数
示例如下:
package com.example.tisimple.advance;
import com.example.tisimple.domain.User;
import com.gitee.oeoe.tisimple.core.TiSimpleCore;
import com.gitee.oeoe.tisimple.exception.SqlInjectionException;
import com.gitee.oeoe.tisimple.template.ISQL;
import com.gitee.oeoe.tisimple.template.SqlFactory;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.HashMap;
/**
* 模版用法
*/
public class TemplateUseTest {
/**
* 无参sql
*/
@Test
public void zero() {
String sql = "select * from s_user where id=1 and age=18 and address='china'";
ISQL template = SqlFactory.sql(sql);
//解析后的sql与原sql没有变化
System.out.println("parsed SQL:" + template.getParsedSql());
}
/**
* ?占位符
*/
@Test
public void one() {
String sql = "select * from s_user where id=? and age=? and address=?";
ISQL template = SqlFactory.sql(sql, 1, 18, "china");
//解析后的sql与原sql没有变化
System.out.println("parsed SQL:" + template.getParsedSql());
//组合参数后的参考sql:select * from s_user where id='1' and age='18' and address='china'
System.out.println("refer SQL:" + template.getReferSql());
}
/**
* {1}序列编号
*/
@Test
public void two() {
String sql = "select * from user where id={2} and age={3} and address={1} ";
//{2}对应的是第二个参数位置上的参数,花括号中的数字代表者参数位置,从1开始。
ISQL template = SqlFactory.sql(sql, "china", 1, 18);
//解析后的sql将变成?占位符形式的sql,select * from s_user where id=? and age=? and address=?
System.out.println("parsed SQL:" + template.getParsedSql());
//组合参数后的参考sql:select * from s_user where id='1' and age='18' and address='china'
System.out.println("refer SQL:" + template.getReferSql());
}
/**
* {name}命名参数-map对象
*/
@Test
public void three() {
String sql = "select * from user where id={id} and age={age} and address={address} ";
HashMap<String, Object> param = new HashMap<>();
param.put("id", 1);
param.put("age", 18);
param.put("address", "china");
//花括号中的名称即参数名称,是map对象中key
ISQL template = SqlFactory.sql(sql, param);
//如果觉得创建map太麻烦,可以直接向ISQL中添加参数,如下:
template.addParam("id", 1)
.addParam("age", 18)
.addParam("address", "china");
//解析后的sql将变成?占位符形式的sql,select * from s_user where id=? and age=? and address=?
System.out.println("parsed SQL:" + template.getParsedSql());
//组合参数后的参考sql:select * from s_user where id='1' and age='18' and address='china'
System.out.println("refer SQL:" + template.getReferSql());
}
/**
* {name}命名参数-实体对象
*/
@Test
public void four() {
String sql = "select * from user where id={id} and age={age} and address={address} ";
User user = new User();
user.setId(1);
user.setAge(18);
user.setAddress("china");
//花括号中的命名参数名称必须要与实体中的字段一致,默认所有的命名参数的值为字符串null
ISQL template = SqlFactory.sql(sql, user);
//解析后的sql将变成?占位符形式的sql,select * from s_user where id=? and age=? and address=?
System.out.println("parsed SQL:" + template.getParsedSql());
//组合参数后的参考sql:select * from s_user where id='1' and age='18' and address='china'
System.out.println("refer SQL:" + template.getReferSql());
}
/**
* {name}命名参数-list对象
*/
@Test
public void five() {
//[foreach@list#where id in(|,|)] 是foreach模版函数的用法,一般用于遍历集合,生成in 类型的sql
String sql = "select * from user [foreach@list#where id in(|,|)]";
ArrayList<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
//参数是collection类型,将会默认给予一个叫list的参数
ISQL template = SqlFactory.sql(sql, ids);
//它等同于下面的方式
template.addParam("list", ids);
//解析后的sql将变成?占位符形式的sql,select * from user where id in(?,?,?)
System.out.println("parsed SQL:" + template.getParsedSql());
//组合参数后的参考sql:select * from user where id in('1','2','3')
System.out.println("refer SQL:" + template.getReferSql());
}
/**
* {#name}特殊命名参数-命名参数以#开头,进行直接替换,不会生成预编译语句
*/
@Test
public void six() throws SqlInjectionException {
String sql = "select * from user where id={#id} and age={#age} and address={#address} ";
User user = new User();
user.setId(1);
user.setAge(18);
user.setAddress("'china'");
//如果花括号中的命名参数名称前以#开头,将会进行直接替换,不会生成预编译语句
ISQL template = SqlFactory.sql(sql, user);
//这种方式存在sql注入风险,可以调用下面的方法进行检查
TiSimpleCore.checkSqlInjection(user.getAddress());
//解析后的sql将变成,select * from user where id=1 and age=18 and address=china
System.out.println("parsed SQL:" + template.getParsedSql());
//组合参数后的参考sql:select * from user where id=1 and age=18 and address=china
System.out.println("refer SQL:" + template.getReferSql());
}
/**
* 自定义参数
*/
@Test
public void seven() {
String sql = "select * from user where id={id}";
ISQL template = SqlFactory.sql(sql);
//参数可以通过如下进行添加
template.addParam("id", 1);
//也可以获取参数进行查看
Object id = template.getParam("id");
System.out.println(id);
//也可以复制一个模版,这个模版和原模版是两个对象
ISQL copy = template.copy();
System.out.println(copy);
//也可以保留原模版的参数空间,更改原模版的sql
String newSql = "select * from user where id>{id}";
ISQL copy1 = template.copy(newSql);
System.out.println(copy1);
}
/**
* 限制的存储过程
*/
@Test
public void eight() {
ISQL template = SqlFactory.sql("{call getOrderById3(?,?)}", 1, "爱德华");
//解析后的sql不变
System.out.println("parsed SQL:" + template.getParsedSql());
//组合参数后的参考sql:{call getOrderById3('1','爱德华')}
System.out.println("refer SQL:" + template.getReferSql());
}
}
模版函数调用规则:
一个模版函数调用以 [ 开头,以 ] 结束,紧跟 [ 之后的funName是函数名,表示要调用的模版方法, @ 与 # 之间的表示主参数,一般是参数空间中的属性, # 之后的是副参数部分,副参数只会被当做字符串处理(随着模版函数的丰富,后期可能会扩展类型),以 | 分隔为副参数列表
目前内置模版函数:
null 函数,格式:[null@主参数#副参数1|副参数2], 如果主参数为 对象null 或 字符度空 或 集合长度0 则返回副参数1,否则返回副参数2
select * from user [null@name#|where name={name}]
如果name为空,整个sql为:select * from user,如果不为空,整个sql为:select * from user where name={name}
foreach 函数,格式:[foreach@主参数#副参数1|副参数2|副参数3|副参数4], 主参数为集合对象且不为空,此函数才会执行。迭代此集合对象,并拼接返回。 副参数2为拼接字符串,副参数1为返回的前缀字符串,副参数3为返回的后缀字符串,参数4控制此次是直接拼接还是占位拼接,默认是占位拼接,只要此参数不为空即表示需要直接拼接。
select * from user where address in [foreach@list#(|,|)]
如果list为['大海','天空'],sql为:select * from user where address in (?,?)。这是一种安全的sql。
select * from user where address in [foreach@list#(|,|)|false]
如果list为['大海','天空'],sql为:select * from user where address in ('大海','天空')。这是一种不安全的sql,如果不确定list的内容, 不建议使用第四个副参数。
select * from user [foreach@list#where address in(|,|)]
这种写法更好,如果list为空,sql为:select * from user。
建议这些注解都由实体生成工具生成,keyGenerateFactory由用户指定
@TiColumn
主要用于关联实体属性和表列名,如果在实体上不加此注解,默认为实体属性名即为表列名
设置 fieldMatchTypeFactory 属性,可设置字段在默认查询中的匹配规则,默认是等于(=), 目前可用有大于(>),大于等于(>=),小于(<),小于等于(<=),不等于(!=),全模糊匹配(like '%xxx%'),左模糊匹配(like '%xxx'),右模糊匹配(like 'xxx%')。
设置 keyGenerateFactory和 key 属性,可自动生成主键值,可自定义主键生成规则。
设置 nullAble 属性,申明此字段在新增的时候校验此属性是否可为null,默认true,可为空,如果设置为false,将不允许为空。
设置 autoIncrement 属性,申明此字段是否是自增字段,默认false,用于新增的时候进行非空校验与id返回设置。
@TiTable
主要用于关联实体和表,如果实体不添加此注解,将无法使用基本的CRUD,即接口 IBaseAbility.class中的功能无法使用。
设置 wrapChar属性,基本CRUD sql中的字段将自动加上设置的字符为前后缀, 在mysql中如果字段中有系统字段,字段通常需要加反引号,此时即可设置为 ' ` '。
待补充...
TX.open() 开启一个事务,ITxManager.join()将一个实体上的sql操作加入到一个事务中。
ITxManager.commit()提交事务,ITxManager.rollback()回滚事务。
entity.getTxManager()获取当前的事务,考虑加入还是新建,还是以非事务方式执行
事务执行结束一定要执行ITxManager.close(),否则此entity对象将一直运行在事务模式,任何CUD将无效,且还会有锁表的风险,建议使用try source避免。
灵活使用ITxManager.join()和entity.getTxManager()可以处理比较多的事务场景。
注意,默认实现只能处理单数据源的事务。
package com.example.tisimple.advance;
import com.example.tisimple.TiConfig;
import com.example.tisimple.domain.Order;
import com.example.tisimple.domain.User;
import com.gitee.oeoe.tisimple.transaction.ITxManager;
import com.gitee.oeoe.tisimple.transaction.TX;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
/**
* 事务使用用例
*/
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class TxTest {
public static final Long serialVersionUID = TiConfig.id();
/**
* 事务使用示例1
*/
@Test
boolean txTest1() {
User user = new User();
user.setName("cef");
user.setAge(888);
user.setId(111000);
User condition = new User();
condition.setAge(888);
User up = new User();
up.setName("笑笑");
up.setAge(888);
ITxManager txManager = TX.open();
try (ITxManager tx = txManager) {//try是必要的
tx.join(user).join(condition).join(up);//将在三个对象上的sql操作加入事务中
int insert = user.insert();
if (insert == 1) {
//tx.commit();//如果需要和后面的操作互不影响,此处放开注释,提交一次到数据库,
} else {
return false;
}
int update = condition.update(up);
if (update == 1) {
tx.commit();//如果更新成功,则提交事务,在此处的commit将insert和update串联成一个事务,此insert和update也不一定是同一个表
return true;
}
Object o = method1(condition);//此处在事务中调用另外一个方法
return false;
} catch (Exception e) {//如果期间出现任何异常,都回滚,也可根据业务判断指定的异常才回滚
e.printStackTrace();
txManager.rollback();
}
return false;
}
public Object method1(User condition) {
Order order = new Order();
order.setUserName("abc");
ITxManager txManager = condition.getTxManager();//此处获取已有的事务
//如果事务不存在,可以根据情况,是创建一个新事务,还是加入当前事务,也可以注释掉此行以非事务方式运行
txManager = txManager == null ? txManager = TX.open() : txManager.join(order);
try (ITxManager tx = txManager) {//如果txManager不是新事务,则不要try source,否则会导致此方法类执行结束后关闭事务,上一级方法中sql操作失败
//...
}
return null;
}
}
待补充..
待补充..
待补充..
待补充...
例子使用MySQL数据库
-- auto-generated definition
create table s_user
(
id int auto_increment comment '主键' primary key,
name varchar(32) null comment '用户名',
age int default 0 null comment '年龄',
address varchar(1024) null comment '地址'
);
INSERT INTO alis.s_user (id, name, age, address)
VALUES (1, '掌声', 118, '大海');
INSERT INTO alis.s_user (id, name, age, address)
VALUES (2, '鲜花', 118, '山坡');
INSERT INTO alis.s_user (id, name, age, address)
VALUES (3, '烈阳', 11, '天空');
INSERT INTO alis.s_user (id, name, age, address)
VALUES (4, '你在哪儿', 118, '我在你身边');
INSERT INTO alis.s_user (id, name, age, address)
VALUES (5, '你在哪儿', 118, '我在你身边');
INSERT INTO alis.s_user (id, name, age, address)
VALUES (6, '你在哪儿', 118, '我在你身边');
INSERT INTO alis.s_user (id, name, age, address)
VALUES (138430, '平方', 19, '共和国');
create table k_order
(
id varchar(64) not null comment '订单号'
primary key,
status int null comment '订单状态,0未支付,1已支付,2待发货,3已发货,4待收货,5已完成',
order_time datetime null comment '下单时间',
total_money decimal null comment '订单总金额',
actual_amount_paid decimal null comment '实际支付金额',
payment varchar(32) null comment '支付方式',
user_id varchar(64) null comment '顾客ID',
user_name varchar(64) null comment '顾客昵称'
) comment '订单';
INSERT INTO alis.k_order (id, status, order_time, total_money, actual_amount_paid, payment, user_id, user_name)
VALUES ('1', 1, '2022-01-12 09:59:06', 188, 100, 'wx', '1', null);
INSERT INTO alis.k_order (id, status, order_time, total_money, actual_amount_paid, payment, user_id, user_name)
VALUES ('b61d932caf954530897fd24524a39551', 1, '2022-01-12 10:08:59', 335, 236, 'zfb', null, null);
INSERT INTO alis.k_order (id, status, order_time, total_money, actual_amount_paid, payment, user_id, user_name)
VALUES ('b8da1ee90d454b2f9776f77071492774', 1, '2022-01-12 12:33:39', 335, 236, 'zfb', '1', '爱德华');
INSERT INTO alis.k_order (id, status, order_time, total_money, actual_amount_paid, payment, user_id, user_name)
VALUES ('fb04c149da4d422aa963634afa696d12', 1, '2022-01-12 10:06:57', 335, 236, 'zfb', null, null);
配置
package com.example.tisimple;
import com.mysql.cj.jdbc.MysqlDataSource;
import we.us.tisimple.core.TiDBPoolManager;
import we.us.tisimple.core.TiGlobalConfig;
import we.us.tisimple.extra.pagefactory.mysql.MysqlPageFactory;
/**
* 只需要创建任何一个连接池,注册到TiDBPoolManager即可
*/
public class TiConfig {
public static final String url = "jdbc:mysql://localhost:3306/alis";
public static final String username = "mime";
public static final String password = "123";
public static final String driver = "com.mysql.cj.jdbc.Driver";
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setURL(url);
dataSource.setUser(username);
dataSource.setPassword(password);
TiDBPoolManager.register(dataSource);//注册连接池
TiGlobalConfig.setGlobalPageFactory(MysqlPageFactory.class, 5);//注册全局分页工厂,设置默认分页大小
}
public static long id() {
return System.nanoTime();
}
}
代码配置生成
package com.example.tisimple;
import we.us.tisimple.core.TiDBPoolManager;
import we.us.tisimple.entityfactory.EntityBuilderFactory;
import we.us.tisimple.entityfactory.mysql.MysqlTableInfoFactory;
import we.us.tisimple.exception.ConditionNotMetException;
import we.us.tisimple.exception.ObtainConnectionException;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 从表中生成实体
*/
public class GenerateUser {
public static final Long serialVersionUID = TiConfig.id();
public static void main(String[] args) throws ObtainConnectionException, ConditionNotMetException, SQLException, IOException {
String path = new File("").getAbsoluteFile().getPath();
path = path + "/example-single/src/main/java/com/example/tisimple/domain/";
try (Connection connection = TiDBPoolManager.getConnection()) {
PreparedStatement preparedStatement = connection.prepareStatement("select * from s_user limit 1");
ResultSet resultSet = preparedStatement.executeQuery();
EntityBuilderFactory.build()
.setPackName("com.example.tisimple.domain")
.setClassName("User")
.setTableName("s_user")
.setResultSet(resultSet)
.setOutPath(path)
.setInfoFactory(MysqlTableInfoFactory.class)//设置获取表信息工厂
.generate();
}
}
}
package com.example.tisimple;
import we.us.tisimple.core.TiDBPoolManager;
import we.us.tisimple.entityfactory.EntityBuilderFactory;
import we.us.tisimple.entityfactory.mysql.MysqlTableInfoFactory;
import we.us.tisimple.exception.ConditionNotMetException;
import we.us.tisimple.exception.ObtainConnectionException;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 从表中生成实体
*/
public class GenerateOrder {
public static final Long serialVersionUID = TiConfig.id();
public static void main(String[] args) throws ObtainConnectionException, ConditionNotMetException, SQLException, IOException {
String path = new File("").getAbsoluteFile().getPath();
path = path + "/example-single/src/main/java/com/example/tisimple/domain/";
try (Connection connection = TiDBPoolManager.getConnection()) {
PreparedStatement preparedStatement = connection.prepareStatement("select * from k_order limit 1");
ResultSet resultSet = preparedStatement.executeQuery();
EntityBuilderFactory.build()
.setPackName("com.example.tisimple.domain")
.setClassName("Order")
.setTableName("k_order")
.setResultSet(resultSet)
.setOutPath(path)
.setInfoFactory(MysqlTableInfoFactory.class)
.generate();
}
}
}
yaml配置生成,文件名为 entity.yaml
#项目绝对路径
rootPath: D:\idea\gitee\tisimple\example-single\src\main\java
#如果配置的fileOutPath不存在,是否创建
autoCreateFileOutPath: true
#默认的包名,可以为空或不写
defaultPackagePathName: com.example.tisimple.domain2
#默认的文件输出路径
defaultFileOutPath: ./com/example/tisimple/domain2
#默认的表信息获取工厂
defaultTableInfoFactoryClass: we.us.tisimple.entityfactory.mysql.MysqlTableInfoFactory
#具体各个实体生成配置
details:
#生成的类名
- className: User
#对应的表名
tableName: s_user
#指定查询一条当前表中记录的sql,这些记录的所有列都不能为空,必须有值,否则无法通过校验生成实体
selectOneSql: select * from s_user limit 1
#类的包名,可以留空或不写,则会继承上面配的默认包名
packagePathName: com.example.tisimple.domain2
#生成的文件输出路径,可以留空或不写,则会继承上面配的默认输出路径,完整路径是rootPath+fileOutPath,一定要以点开头(./)
fileOutPath: ./com/example/tisimple/domain2
#表信息获取工厂,可以留空或不写,则会继承上面配的默认表信息获取工厂
tableInfoFactoryClass: we.us.tisimple.entityfactory.mysql.MysqlTableInfoFactory
- className: Order
tableName: k_order
selectOneSql: select * from k_order limit 1
#使用默认的包名
#packagePathName: com.example.tisimple.domain2
#使用默认的文件输出路径
#fileOutPath: ./com/example/tisimple/domain2
#使用默认的表信息获取工厂
#tableInfoFactoryClass: we.us.tisimple.entityfactory.mysql.MysqlTableInfoFactory
package com.example.tisimple.entitybuilder;
import com.example.tisimple.TiConfig;
import we.us.tisimple.core.TiDBPoolManager;
import we.us.tisimple.entityfactory.EntityBuilderFactory;
import we.us.tisimple.entityfactory.mysql.MysqlTableInfoFactory;
import we.us.tisimple.exception.ConditionNotMetException;
import we.us.tisimple.exception.ObtainConnectionException;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 通过yaml配置,从表中生成实体
*
*/
public class GenerateFormYaml {
public static final Long serialVersionUID = TiConfig.id();
public static void main(String[] args) {
//classpath 目录下配置一个 entity.yaml 文件即可
EntityBuilderFactory.buildFromYaml();
}
}
生成的文件
package com.example.tisimple.domain;
import we.us.tisimple.ability.TiEntity;
import we.us.tisimple.annotation.TiColumn;
import we.us.tisimple.annotation.TiTable;
import we.us.tisimple.extra.keygenertefactory.UUIDFactory;
import we.us.tisimple.extra.matchtypefactory.LeTypeFactory;
@TiTable(value = "k_order")
public class Order extends TiEntity<Order> {
@TiColumn(value = "id", comment = "订单号", nullAble = false, key = true, keyGenerateFactory = UUIDFactory.class)
private java.lang.String id;
@TiColumn(value = "status", comment = "订单状态,0未支付,1已支付,2待发货,3已发货,4待收货,5已完成")
private java.lang.Integer status;
@TiColumn(value = "order_time", comment = "下单时间", fieldMatchTypeFactory = LeTypeFactory.class)//更改默认类型匹配
private java.time.LocalDateTime orderTime;
@TiColumn(value = "total_money", comment = "订单总金额")
private java.math.BigDecimal totalMoney;
@TiColumn(value = "actual_amount_paid", comment = "实际支付金额")
private java.math.BigDecimal actualAmountPaid;
@TiColumn(value = "payment", comment = "支付方式")
private java.lang.String payment;
@TiColumn(value = "user_id", comment = "顾客ID")
private java.lang.String userId;
@TiColumn(value = "user_name", comment = "顾客昵称")
private java.lang.String userName;
public void setId(java.lang.String id) {
this.id = id;
}
public java.lang.String getId() {
return this.id;
}
public void setStatus(java.lang.Integer status) {
this.status = status;
}
public java.lang.Integer getStatus() {
return this.status;
}
public void setOrderTime(java.time.LocalDateTime orderTime) {
this.orderTime = orderTime;
}
public java.time.LocalDateTime getOrderTime() {
return this.orderTime;
}
public void setTotalMoney(java.math.BigDecimal totalMoney) {
this.totalMoney = totalMoney;
}
public java.math.BigDecimal getTotalMoney() {
return this.totalMoney;
}
public void setActualAmountPaid(java.math.BigDecimal actualAmountPaid) {
this.actualAmountPaid = actualAmountPaid;
}
public java.math.BigDecimal getActualAmountPaid() {
return this.actualAmountPaid;
}
public void setPayment(java.lang.String payment) {
this.payment = payment;
}
public java.lang.String getPayment() {
return this.payment;
}
public void setUserId(java.lang.String userId) {
this.userId = userId;
}
public java.lang.String getUserId() {
return this.userId;
}
public void setUserName(java.lang.String userName) {
this.userName = userName;
}
public java.lang.String getUserName() {
return this.userName;
}
@Override
public String toString() {
return "Order{" +
"id=" + id + "," +
"status=" + status + "," +
"orderTime=" + orderTime + "," +
"totalMoney=" + totalMoney + "," +
"actualAmountPaid=" + actualAmountPaid + "," +
"payment=" + payment + "," +
"userId=" + userId + "," +
"userName=" + userName +
"}";
}
}
package com.example.tisimple.domain;
import com.gitee.oeoe.tisimple.ability.TiEntity;
import com.gitee.oeoe.tisimple.annotation.TiColumn;
import com.gitee.oeoe.tisimple.annotation.TiTable;
@TiTable(value = "s_user")
public class User extends TiEntity<User> {
@TiColumn(value = "id", comment = "主键", nullAble = false, key = true, autoIncrement = true)
private java.lang.Integer id;
@TiColumn(value = "name", comment = "用户名")
private java.lang.String name;
@TiColumn(value = "age", comment = "年龄")
private java.lang.Integer age;
@TiColumn(value = "address", comment = "地址")
private java.lang.String address;
public void setId(java.lang.Integer id) {
this.id = id;
}
public java.lang.Integer getId() {
return this.id;
}
public void setName(java.lang.String name) {
this.name = name;
}
public java.lang.String getName() {
return this.name;
}
public void setAge(java.lang.Integer age) {
this.age = age;
}
public java.lang.Integer getAge() {
return this.age;
}
public void setAddress(java.lang.String address) {
this.address = address;
}
public java.lang.String getAddress() {
return this.address;
}
@Override
public String toString() {
return "User{" +
"id=" + id + "," +
"name=" + name + "," +
"age=" + age + "," +
"address=" + address +
"}";
}
}
package com.example.tisimple.domain;
import we.us.tisimple.ability.TiEntity;
import we.us.tisimple.annotation.TiColumn;
import we.us.tisimple.annotation.TiTable;
@TiTable(value = "m_type", wrapChar = "`")
public class MysqlType extends TiEntity<MysqlType> {
@TiColumn(value = "id", nullAble = false, key = true)
private java.lang.String id;
@TiColumn(value = "order", nullAble = false)
private java.lang.Integer order;
@TiColumn(value = "TINYINT")
private java.lang.Integer tinyint;
@TiColumn(value = "SMALLINT")
private java.lang.Integer smallint;
@TiColumn(value = "INTEGER")
private java.lang.Integer integer;
@TiColumn(value = "BIGINT")
private java.lang.Long bigint;
@TiColumn(value = "DECIMAL")
private java.math.BigDecimal decimal;
@TiColumn(value = "DATE")
private java.sql.Date date;
@TiColumn(value = "TIME")
private java.lang.String time;
@TiColumn(value = "YEAR")
private java.sql.Date year;//year类型的对应java中date类型,是无法进行正常插入的
@TiColumn(value = "DATETIME")
private java.time.LocalDateTime datetime;
@TiColumn(value = "TIMESTAMP")
private java.sql.Timestamp timestamp;
@TiColumn(value = "CHAR")
private java.lang.String char1;
@TiColumn(value = "VARCHAR")
private java.lang.String varchar;
@TiColumn(value = "TINYBLOB")
private byte[] tinyblob;
@TiColumn(value = "TINYTEXT")
private java.lang.String tinytext;
@TiColumn(value = "BLOB")
private byte[] blob;
@TiColumn(value = "TEXT")
private java.lang.String text;
@TiColumn(value = "MEDIUMBLOB")
private byte[] mediumblob;
@TiColumn(value = "MEDIUMTEXT")
private java.lang.String mediumtext;
@TiColumn(value = "LONGBLOB")
private byte[] longblob;
@TiColumn(value = "LONGTEXT")
private java.lang.String longtext;
public void setId(java.lang.String id) {
this.id = id;
}
public java.lang.String getId() {
return this.id;
}
public void setOrder(java.lang.Integer order) {
this.order = order;
}
public java.lang.Integer getOrder() {
return this.order;
}
public void setTinyint(java.lang.Integer tinyint) {
this.tinyint = tinyint;
}
public java.lang.Integer getTinyint() {
return this.tinyint;
}
public void setSmallint(java.lang.Integer smallint) {
this.smallint = smallint;
}
public java.lang.Integer getSmallint() {
return this.smallint;
}
public void setInteger(java.lang.Integer integer) {
this.integer = integer;
}
public java.lang.Integer getInteger() {
return this.integer;
}
public void setBigint(java.lang.Long bigint) {
this.bigint = bigint;
}
public java.lang.Long getBigint() {
return this.bigint;
}
public void setDecimal(java.math.BigDecimal decimal) {
this.decimal = decimal;
}
public java.math.BigDecimal getDecimal() {
return this.decimal;
}
public void setDate(java.sql.Date date) {
this.date = date;
}
public java.sql.Date getDate() {
return this.date;
}
public void setTime(java.lang.String time) {
this.time = time;
}
public java.lang.String getTime() {
return this.time;
}
public void setYear(java.sql.Date year) {
this.year = year;
}
public java.sql.Date getYear() {
return this.year;
}
public void setDatetime(java.time.LocalDateTime datetime) {
this.datetime = datetime;
}
public java.time.LocalDateTime getDatetime() {
return this.datetime;
}
public void setTimestamp(java.sql.Timestamp timestamp) {
this.timestamp = timestamp;
}
public java.sql.Timestamp getTimestamp() {
return this.timestamp;
}
public void setChar(java.lang.String char1) {
this.char1 = char1;
}
public java.lang.String getChar() {
return this.char1;
}
public void setVarchar(java.lang.String varchar) {
this.varchar = varchar;
}
public java.lang.String getVarchar() {
return this.varchar;
}
public void setTinyblob(byte[] tinyblob) {
this.tinyblob = tinyblob;
}
public byte[] getTinyblob() {
return this.tinyblob;
}
public void setTinytext(java.lang.String tinytext) {
this.tinytext = tinytext;
}
public java.lang.String getTinytext() {
return this.tinytext;
}
public void setBlob(byte[] blob) {
this.blob = blob;
}
public byte[] getBlob() {
return this.blob;
}
public void setText(java.lang.String text) {
this.text = text;
}
public java.lang.String getText() {
return this.text;
}
public void setMediumblob(byte[] mediumblob) {
this.mediumblob = mediumblob;
}
public byte[] getMediumblob() {
return this.mediumblob;
}
public void setMediumtext(java.lang.String mediumtext) {
this.mediumtext = mediumtext;
}
public java.lang.String getMediumtext() {
return this.mediumtext;
}
public void setLongblob(byte[] longblob) {
this.longblob = longblob;
}
public byte[] getLongblob() {
return this.longblob;
}
public void setLongtext(java.lang.String longtext) {
this.longtext = longtext;
}
public java.lang.String getLongtext() {
return this.longtext;
}
@Override
public String toString() {
return "MysqlType{" +
"id=" + id + "," +
"order=" + order + "," +
"tinyint=" + tinyint + "," +
"smallint=" + smallint + "," +
"integer=" + integer + "," +
"bigint=" + bigint + "," +
"decimal=" + decimal + "," +
"date=" + date + "," +
"time=" + time + "," +
"year=" + year + "," +
"datetime=" + datetime + "," +
"timestamp=" + timestamp + "," +
"char=" + char1 + "," +
"varchar=" + varchar + "," +
"tinyblob=" + tinyblob + "," +
"tinytext=" + tinytext + "," +
"blob=" + blob + "," +
"text=" + text + "," +
"mediumblob=" + mediumblob + "," +
"mediumtext=" + mediumtext + "," +
"longblob=" + longblob + "," +
"longtext=" + longtext +
"}";
}
}
多表查询结果实体定义示例
package com.example.tisimple.domain;
import we.us.tisimple.ability.TiEntity;
import we.us.tisimple.annotation.TiColumn;
public class Example extends TiEntity<Example> {
private Integer age;
@TiColumn("order_id")
private String orderId;
@TiColumn("user_name")
private String userName;
@Override
public String toString() {
return "Example{" +
"age=" + age +
", orderId='" + orderId + '\'' +
", userName='" + userName + '\'' +
'}';
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
2022-1-10 文本版本 v1.0.0
2022-1-11 文本版本 v1.1.0
2022-1-12 文本版本 v1.1.1
2022-1-16 文本版本 v1.1.2
2022-1-28 文本版本 v1.1.3
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。