Skip to content

Commit de1e39d

Browse files
committed
Update README.md
1 parent 81891a2 commit de1e39d

1 file changed

Lines changed: 294 additions & 4 deletions

File tree

README.md

Lines changed: 294 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
The lib of java database ORM simple implementation
33

44
---
5-
65
#### **Session基本用法**
76
```java
87
// get session instance by its factory
@@ -71,18 +70,309 @@ ConfiguratorFactory.setConfigurator(conf);
7170
Configurator overrideConf = ConfiguratorFactory.getDefaultInstance();
7271
// 方法4: 读取外部文件实例化配置,配置文件名称可以自由命名
7372
File file = new File("C:\path\filename.properties");
74-
Configurator extenConf = ConfiguratorFactory.getInstance(file);
73+
Configurator externalConf = ConfiguratorFactory.getInstance(file);
7574
```
7675

7776
#### **Session高级用法**
7877
##### **实体类定义**
78+
目前支持两种类型的实体类: 继承自Entity类,带有JPA注解的POJO类
79+
80+
openthinks.libs.sql.entity.Entity实例简单对应数据库中的表的一条记录,因此要求该实体类定义时注意以下事项:
81+
82+
1. 该实体类中的字段或属性名需要与对应表列名一样
83+
2. 该实体类中定义的第一个字段作为对应表的主键
84+
3. 该实体类的名称需与表名相同(仅在调用Session的高级API)
85+
86+
例子:
87+
```
88+
//table structure
89+
create table message(
90+
message_id varchar(100),
91+
message_local varchar(100),
92+
message_content varchar(1000)
93+
);
94+
```
95+
```java
96+
public class Message extends Entity {
97+
private String message_id;
98+
private String message_locale;
99+
private String message_content;
100+
public String getContent() {
101+
return message_content;
102+
}
103+
public String getLocale() {
104+
return message_locale;
105+
}
106+
public String getId() {
107+
return message_id;
108+
}
109+
public void setId(String messageId) {
110+
this.message_id = messageId;
111+
}
112+
public void setLocale(String locale) {
113+
this.message_locale = locale;
114+
}
115+
public void setContent(String content) {
116+
this.message_content = content;
117+
}
118+
}
119+
```
120+
121+
JPA注解的POJO类没有额外的限制
122+
```java
123+
import javax.persistence.Column;
124+
import javax.persistence.Entity;
125+
import javax.persistence.Id;
126+
import javax.persistence.Table;
127+
@Entity
128+
@Table(name = "message")
129+
public class MessageJPA {
130+
@Id
131+
@Column(name = "message_id")
132+
private String messageId;
133+
@Column(name = "message_locale")
134+
private String locale;
135+
@Column(name = "message_content")
136+
private String content;
137+
/*
138+
*getter/setter method
139+
*/
140+
}
141+
```
142+
79143
##### **增删改**
144+
在Session的DAO API中分为两大类,一类是无需编写SQL(High level);另一类是需要自行构造SQL(Low level).
145+
146+
```java
147+
//<T> void openthinks.libs.sql.dhibernate.Session.save(T object)
148+
// High level
149+
Session session = SessionFactory.getSession();
150+
MessageJPA messageJPA = new MessageJPA();
151+
messageJPA.setLocale(Locale.US.toString());
152+
messageJPA.setContent("HELLO");
153+
messageJPA.setMessageId("2000");
154+
session.save(messageJPA);
155+
Message messageEntity = new Message();
156+
messageEntity.setLocale(Locale.CHINA.toString());
157+
messageEntity.setContent("你好");
158+
messageEntity.setId("3000");
159+
session.save(messageEntity);
160+
161+
//int openthinks.libs.sql.dhibernate.Session.add(String sql, String[] params)
162+
// Low level
163+
String saveSQL = "INSERT INTO message(message_id,message_locale,message_content) values(?,?,?)";
164+
String[] params = {"4000","en_US","Hello again"};
165+
int affectRow = session.add(saveSQL,params);
166+
session.close();
167+
```
168+
169+
```java
170+
//<T> void openthinks.libs.sql.dhibernate.Session.update(T object)
171+
Session session = SessionFactory.getSession();
172+
MessageJPA message = new MessageJPA();
173+
message.setLocale(Locale.CHINA.toString());
174+
message.setContent("中国你好");
175+
message.setMessageId("2000");
176+
session.update(message);
177+
178+
//int openthinks.libs.sql.dhibernate.Session.update(String sql, String[] params)
179+
String updateSQL = "update message set message_content = ? where message_id =? and message_locale=?";
180+
String[] params = {"您好","zh_CN","2000"};
181+
session.update();
182+
session.close();
183+
```
184+
185+
```java
186+
//<T> void openthinks.libs.sql.dhibernate.Session.delete(T object)
187+
MessageJPA messageJPA = new MessageJPA();
188+
messageJPA.setLocale(Locale.US.toString());
189+
messageJPA.setContent("HELLO");
190+
messageJPA.setMessageId("2000");
191+
Session session = SessionFactory.getSession();
192+
session.delete(messageJPA);
80193

81-
##### **查询**
194+
//int openthinks.libs.sql.dhibernate.Session.delete(String sql, String[] params)
195+
String deleteSQL = "delete message where message_id =? and message_locale=?";
196+
String[] params = {"zh_CN","2000"};
197+
session.delete(deleteSQL,params);
198+
session.close();
199+
```
200+
##### **条件查询**
201+
对于简单根据单一主键获取记录或获取所有表中记录,推荐使用High level API:
202+
```
203+
// 根据id值获取clz类型的实体对象
204+
<T> T openthinks.libs.sql.dhibernate.Session.load(Class<T> clz, Serializable id)
205+
// 获取所有相应实体类的集合列表
206+
<T> List<T> openthinks.libs.sql.dhibernate.Session.list(Class<T> clz)
207+
```
208+
而对于一些复杂的查询,可以使用接下来的方式
82209
###### **直接SQL语句查询**
210+
```java
211+
Session session = SessionFactory.getSession();
212+
String querySQL = "SELECT * FROM message WHERE message_id = ? and message_locale= ? ";
213+
MessgaeJPA messageJPA = session.get(MessageJPA.class, querySQL,new String[]{"2000","zh_CN"});
214+
//Messgae message = session.get(Message.class, querySQL,new String[]{"2000","zh_CN"});
215+
List<MessageJPA> list = session.list(MessageJPA.class, "SELECT * FROM message",new String[]{});
216+
//List<Message> list = session.list(Message.class, "SELECT * FROM message",new String[]{});
217+
// 不指定实体类型时,将使用 openthinks.libs.sql.data.Row
218+
List<Row> rows = session.list("SELECT * FROM message",new String[]{});
219+
session.close();
220+
```
83221
###### **简单条件类查询**
84-
###### **智能QueryFilter查询**
222+
简单条件类: openthinks.libs.sql.lang.Condition是非常底层的,也属于Low level.
223+
Condition对象可以如下创建:
224+
```
225+
Session session = SessionFactory.getSession();
226+
session.createCondition(); // same as Condition.build()
227+
```
228+
```
229+
// where 1=1
230+
Condition condition1 = Condition.build();
231+
// SELECT * FROM message where 1=1
232+
Condition condition2 = Condition.build("SELECT * FROM message");
233+
// SELECT * FROM message where 1=1
234+
Condition condition3 = Condition.build(MessageJPA.class);
235+
```
236+
如何使用:(暂支持 绝对匹配 *=*,模糊匹配 *like*,开始于 *>*,结束于 *<*)
237+
参考以下 test case:
238+
```java
239+
public class ConditionTest {
240+
private static MessageJPA message = new MessageJPA();
241+
private static MessageJPA message2 = new MessageJPA();
242+
@BeforeClass
243+
public static void setUp() {
244+
Session session = SessionFactory.getSession();
245+
message.setMessageId("CONDITION_1");
246+
message.setLocale(Locale.US.toString());
247+
message.setContent("Condition class regular test");
248+
session.save(message);
85249

250+
message2.setMessageId("CONDITION_2");
251+
message2.setLocale(Locale.US.toString());
252+
message2.setContent("Condition class other test");
253+
session.save(message2);
254+
session.close();
255+
}
256+
@Test
257+
public void regularTest() {
258+
Session session = SessionFactory.getSession();
259+
Condition condition = session.createCondition();
260+
condition.setSqlPart("SELECT * FROM message");
261+
// 等效于 Condition.build("SELECT * FROM message");
262+
263+
//第一个参数为条件类型;第二个参数为表字段;第三参数为对应的条件值
264+
condition.addItem(Condition.ABSMATCH, "message_id", "CONDITION_1");
265+
MessageJPA msg = session.get(MessageJPA.class, condition);
266+
Assert.assertNotNull(msg);
267+
Assert.assertEquals(message.getContent(), msg.getContent());
268+
session.close();
269+
}
270+
@Test
271+
public void otherTest() {
272+
Condition condition = Condition.build(MessageJPA.class)
273+
.addItem(Condition.LIKEMATCH, "message_id", "CONDITION%")
274+
.addItem(Condition.ORDER, "message_id", Condition.Order.DESC);//排序
275+
Session session = SessionFactory.getSession();
276+
List<MessageJPA> list = session.list(MessageJPA.class, condition);
277+
Assert.assertTrue(list.size() == 2);
278+
Assert.assertEquals(message2.getMessageId(), list.get(0).getMessageId());
279+
session.close();
280+
}
281+
@AfterClass
282+
public static void tearDown() {
283+
Session session = SessionFactory.getSession();
284+
session.delete(message);
285+
session.delete(message2);
286+
session.close();
287+
}
288+
}
289+
```
290+
###### **智能QueryFilter查询**
291+
```java
292+
Session session = SessionFactory.getSession();
293+
// 获取Query对象
294+
Query<MessageJPA> query = session.createQuery(MessageJPA.class);
295+
// 定义具体的QueryFilter
296+
QueryFilterGroup group = Filters.group();
297+
group.push(Filters.eq("messageId", "4000"));
298+
group.push(Filters.or());
299+
QueryFilterGroup embedGrp = Filters.group();
300+
embedGrp.push(Filters.eq("messageId", "2000"));
301+
embedGrp.push(Filters.eq("locale", "zh_CN"));
302+
group.push(embedGrp);
303+
// 最终SQL(MYSQL):
304+
// select * from `message` where ( `message_id` = '4000' or ( `message_id` = '2000' and message_locale = 'zh_CN') )
305+
// 添加到Query对象
306+
query.addFilter(group);
307+
List<MessageJPA> list = query.execute();
308+
session.close();
309+
```
86310
##### **简单事务**
311+
开启事务 `session.beginTransaction();` 另外 `session.beginTransaction(TransactionLevel.TRANSACTION_READ_UNCOMMITTED)` 设置事务级别
312+
关闭事务 `session.endTransaction();` 另外 `session.close();` 也会默认关闭事务,如果开启的话.
313+
例子:
314+
```java
315+
public class TransactionTest {
316+
private static MessageJPA message = new MessageJPA();
317+
@BeforeClass
318+
public static void setUp() {
319+
Session session = SessionFactory.getSession();
320+
message.setMessageId("TRANSACTION");
321+
message.setLocale(Locale.US.toString());
322+
message.setContent("Transaction test");
323+
session.save(message);
324+
session.close();
325+
}
326+
@Test
327+
public void beginTransactionTest() throws TransactionException {
328+
Session session = SessionFactory.getSession();
329+
session.beginTransaction();
330+
message.setContent("Transaction test rollback");
331+
session.update(message);
332+
int result = session.add("insert into message");//错误语法,新增不成功
333+
if (result == 0) {
334+
session.rollback();
335+
} else {
336+
session.commit();
337+
}
338+
session.endTransaction();
339+
340+
MessageJPA msg = session.load(MessageJPA.class, message.getMessageId());
341+
Assert.assertNotNull(msg);
342+
Assert.assertEquals("Transaction test", msg.getContent());
343+
session.close();
344+
}
345+
@AfterClass
346+
public static void tearDown() {
347+
Session session = SessionFactory.getSession();
348+
session.delete(message);
349+
session.close();
350+
}
351+
}
352+
```
87353

88354
##### **连接池**
355+
目前支持简单的连接池实现 `openthinks.libs.sql.dao.pool.impl.SimpleConnectionPool`;
356+
可以自行扩展 `openthinks.libs.sql.dao.pool.ConnectionPool`接口,并替换默认的实现:
357+
```java
358+
MyConnectionPool connPool = new MyConnectionPool();// your implemented ConnectionPool
359+
ConnectionPoolManager.setSingletonPoolInstance(connPool);// make it replace the default pool
360+
```
361+
当然使用连接池前,必须配置,在配置文件 dbconfig.properties 中, 加入:
362+
```
363+
USEPOOL=true
364+
#可选,不配的话默认无限制
365+
MAX_ACTIVE=100
366+
#可选,不配的话默认无限制
367+
MAX_IDLE=10
368+
```
369+
对于扩展的ConnectionPool, 除了如上所述使用Code替换默认实现, 亦可以在配置文件中指明实现类名称
370+
```
371+
USEPOOL=true
372+
POOL_CLASS=openthinks.libs.sql.MyConnectionPool
373+
```
374+
需要注意事项是构造函数的定义:
375+
376+
1. MyConnectionPool(Configuration) 和 MyConnectionPool() 至少需要定义一个
377+
2. MyConnectionPool() 需要自行获取配置类,以确保获取到数据库连接
378+
3. 优先使用 MyConnectionPool(Configuration) 构造函数

0 commit comments

Comments
 (0)