關於easymybatis——mybatis開發利器
阿新 • • 發佈:2019-02-03
easymybatis是一個mybatis增強類庫,目的為簡化mybatis的開發,讓開發更高效。
Demo
特色
- 無需編寫xml檔案即可完成CRUD操作。
- 支援多表查詢、聚合查詢、分頁查詢(支援多種資料庫)。
- 支援批量新增,指定欄位批量新增。
- 支援Dao層訪問控制,如某個dao只有查詢功能,某個dao有crud功能等。
- 支援自定義sql,sql語句可以寫在配置檔案中,同樣支援mybatis標籤。
- 支援mysql,sqlserver,oracle,其它資料庫擴充套件方便(增加一個模板檔案即可)。
- 使用方式不變,與Spring整合只改了一處配置。
- 沒有修改框架原始碼(無外掛),採用動態程式碼生成實現功能。
例子
entity檔案 TUser.java
@Table(name = "t_user")
public class TUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "username")
private String username;
@Column(name = "state")
private Byte state;
@Column(name = "isdel" )
private Boolean isdel;
@Column(name = "remark")
private String remark;
@Column(name = "add_time")
private Date addTime;
@Column(name = "money")
private BigDecimal money;
@Column(name = "left_money")
private Float leftMoney;
// 省略get set
}
dao檔案 TUserDao.java.Dao層簡單繼承即可,表示這個dao具有CRUD功能
public interface TUserDao extends CrudDao<TUser> {
}
測試檔案 TUserDaoTest.java
// 根據主鍵查詢
@Test
public void testGet() {
TUser user = dao.get(3);
print(user);
}
// 根據欄位查詢一條記錄
@Test
public void testGetByProperty() {
TUser user = dao.getByProperty("username", "王五");
print(user);
}
// 根據條件查詢一條記錄
@Test
public void testGetByExpression() {
// 查詢ID=3的使用者
Query query = Query.build().eq("id", 3);
TUser user = dao.getByExpression(query);
print(user);
}
// 條件查詢
// 查詢username='張三'的使用者
@Test
public void testFind() {
Query query = new Query();
// 新增查詢條件
query.eq("username", "張三");
List<TUser> list = dao.find(query); // 獲取結果集
long count = dao.countTotal(query); // 獲取總數
print("count:" + count);
for (TUser user : list) {
System.out.println(user);
}
}
// 分頁查詢,支援mysql,sqlserver2005+,oracle
@Test
public void testPage() {
Query query = new Query();
query.setPage(2, 2) // 設定pageIndex,pageSize
.addSort("id", "desc"); // 新增排序
;
// 查詢後的結果,包含總記錄數,結果集,總頁數等資訊
PageInfo<TUser> pageInfo = QueryUtils.query(dao, query);
List<TUser> rows = pageInfo.getList();
for (TUser user : rows) {
System.out.println(user);
}
}
// 自定義返回欄位查詢,只返回兩個欄位
// SELECT t.id,t.username FROM `t_user` t LIMIT 0,10
@Test
public void testSelfColumns() {
Query query = new Query();
// 只返回id,username
query.setColumns(Arrays.asList("t.id","t.username"));
List<TUser> list = dao.find(query);
for (TUser user : list) {
System.out.println(user);
}
}
// 多表查詢,left join
// 適用場景:獲取兩張表裡面的欄位資訊返回給前端
/*
* MYSQL生成如下sql:
SELECT
t.`id` , t.`username` , t.`state` , t.`isdel` , t.`remark`
, t.`add_time` , t.`money` , t.`left_money`
, t2.city , t2.address
FROM `t_user` t left join user_info t2 on t.id = t2.user_id
WHERE t2.id = ?
ORDER BY id ASC
LIMIT ?,?
*/
@Test
public void testJoin() {
Query query = new Query();
// 新增第二張表的欄位,跟主表字段一起返回
query.addOtherColumns(
"t2.city"
,"t2.address"
);
// 左連線查詢,主表的alias預設為t
query.join("left join user_info t2 on t.id = t2.user_id");
//新增條件
query.eq("t2.id", 2);
query.addSort("t.id");
List<TUser> list = dao.find(query);
System.out.println("==============");
for (TUser user : list) {
System.out.println(
user.getId()
+ " " + user.getUsername()
// 下面兩個欄位是第二張表裡面的
+ " " + user.getCity()
+ " " + user.getAddress()
);
}
System.out.println("==============");
}
/*
* 聚合查詢
* 按state分組統計money和,並且按照state升序
* 並且money大於200的state
*
* SELECT
* state AS s , SUM(money) AS m
* FROM `t_user` t
* WHERE money > 0
* GROUP BY state
* HAVING m > 200
* ORDER BY state asc
*/
@Test
public void testProjection() {
ProjectionQuery query = new ProjectionQuery();
// 新增列
query.addProjection(Projections.column("state", "s"));
query.addProjection(Projections.sum("money", "m"));
// 新增where
query.addExpression(new ValueExpression("money",">",0));
// 新增group by
query.addGroupBy("state");
// 新增having
query.addHaving(new ValueExpression("SUM(money)", ">" ,200));
query.addSort("state", "asc");
List<Map<String, Object>> list = dao.findProjection(query);
Assert.notEmpty(list);
print(list);
}
// 自定義sql,見TUserDao.xml
// 注意mapper檔名必須跟Dao類一致
@Test
public void testSelfSql() {
TUser user = dao.selectByName("張三");
print(user);
}
// 新增-儲存所有欄位
@Test
public void testInsert() {
TUser user = new TUser();
user.setAddTime(new Date());
user.setIsdel(false);
user.setLeftMoney(22.1F);
user.setMoney(new BigDecimal(100.5));
user.setRemark("備註");
user.setState((byte)0);
user.setUsername("張三");
dao.save(user);
print("新增後的主鍵:" + user.getId());
print(user);
}
// 新增-儲存非空欄位
@Test
public void testInsertIgnoreNull() {
TUser user = new TUser();
user.setAddTime(new Date());
user.setIsdel(true);
user.setMoney(new BigDecimal(100.5));
user.setState((byte)0);
user.setUsername("張三notnull");
user.setLeftMoney(null);
user.setRemark(null);
dao.saveIgnoreNull(user);
print("新增後的主鍵:" + user.getId());
print(user);
}
// 批量新增
/*
* 支援mysql,sqlserver2008。如需支援其它資料庫使用saveMulti方法
* INSERT INTO person (id, name, age)
VALUES
(1, 'Kelvin', 22),
(2, 'ini_always', 23);
*/
@Test
public void testInsertBatch() {
List<TUser> users = new ArrayList<>();
for (int i = 0; i < 3; i++) { // 建立3個物件
TUser user = new TUser();
user.setUsername("username" + i);
user.setMoney(new BigDecimal(i));
user.setRemark("remark" + i);
user.setState((byte)0);
user.setIsdel(false);
user.setAddTime(new Date());
user.setLeftMoney(200F);
users.add(user);
}
int i = dao.saveBatch(users); // 返回成功數
System.out.println("saveBatch --> " + i);
}
/**
* 批量新增,相容更多資料庫版本,採用union all
* INSERT INTO [t_user] ( [username] , [state] , [isdel]
, [remark] , [add_time] , [money] , [left_money] )
* SELECT ? , ? , ? , ? , ? , ? , ?
* UNION ALL SELECT ? , ? , ? , ? , ? , ? , ?
* UNION ALL SELECT ? , ? , ? , ? , ? , ? , ?
*/
@Test
public void testInsertMulti() {
List<TUser> users = new ArrayList<>();
for (int i = 0; i < 3; i++) { // 建立3個物件
TUser user = new TUser();
user.setUsername("username" + i);
user.setMoney(new BigDecimal(i));
user.setRemark("remark" + i);
user.setState((byte)3);
user.setIsdel(false);
user.setAddTime(new Date());
user.setLeftMoney(200F);
users.add(user);
}
int i = dao.saveMulti(users); // 返回成功數
System.out.println("saveMulti --> " + i);
}
// 批量新增指定欄位,僅支援msyql,sqlserver2008,如需支援其它資料庫使用saveMulti方法
@Test
public void testInsertBatchWithColumns() {
List<TUser> users = new ArrayList<>();
for (int i = 0; i < 3; i++) { // 建立3個物件
TUser user = new TUser();
user.setUsername("usernameWithColumns" + i);
user.setMoney(new BigDecimal(i));
user.setAddTime(new Date());
users.add(user);
}
/*
* INSERT INTO `t_user` ( username , money , add_time )
* VALUES ( ? , ? , ? ) , ( ? , ? , ? ) , ( ? , ? , ? )
*/
int i= dao.saveBatchWithColumns(Arrays.asList(
new Column("username", "username") // 第一個是資料庫欄位,第二個是java欄位
,new Column("money", "money")
,new Column("add_time", "addTime")
), users);
System.out.println("saveBatchWithColumns --> " + i);
}
/*
* // 批量新增指定欄位,相容
* INSERT INTO [t_user] ( [username] , [money] , [add_time] )
* SELECT ? , ? , ?
* UNION ALL SELECT ? , ? , ?
* UNION ALL SELECT ? , ? , ?
*/
@Test
public void testInsertMultiWithColumns() {
List<TUser> users = new ArrayList<>();
for (int i = 0; i < 3; i++) { // 建立3個物件
TUser user = new TUser();
user.setUsername("usernameWithColumns" + i);
user.setMoney(new BigDecimal(i));
user.setAddTime(new Date());
users.add(user);
}
int i= dao.saveMultiWithColumns(Arrays.asList(
new Column("username", "username") // 第一個是資料庫欄位,第二個是java欄位
,new Column("money", "money")
,new Column("add_time", "addTime")
), users);
System.out.println("saveMultiWithColumns --> " + i);
}
// 更新所有欄位
@Test
public void testUpdate() {
TUser user = dao.get(3);
user.setUsername("李四");
user.setMoney(user.getMoney().add(new BigDecimal(0.1)));
user.setIsdel(true);
int i = dao.update(user);
print("testUpdate --> " + i);
}
// 更新不為null的欄位
/*
*UPDATE [t_user] SET [username]=?, [isdel]=? WHERE [id] = ?
*/
@Test
public void updateIgnoreNull() {
TUser user = new TUser();
user.setId(3);
user.setUsername("王五");
user.setIsdel(false);
int i = dao.updateIgnoreNull(user);
print("updateNotNull --> " + i);
}
// 根據條件更新
// UPDATE t_user SET remark = '批量修改備註' WHERE state = 0
@Test
public void testUpdateNotNullByExpression() {
Query query = new Query();
query.eq("state", 0);
TUser user = new TUser();
user.setRemark("批量修改備註");
int i = dao.updateIgnoreNullByExpression(user, query);
print("testUpdateNotNullByExpression --> " + i);
}
// 刪除
@Test
public void testDel() {
TUser user = new TUser();
user.setId(14);
int i = dao.del(user);
print("del --> " + i);
}
// 根據條件刪除
// DELETE FROM `t_user` WHERE state = ?
@Test
public void delByExpression() {
Query query = new Query();
query.eq("state", 3);
int i = dao.delByExpression(query);
print("delByExpression --> " + i);
}
更多列子可以檢視demo中的測試用例。
常用方法
Dao層方法
查詢條件
使用方法(springmvc)
maven依賴:
<dependency>
<groupId>net.oschina.durcframework</groupId>
<artifactId>easymybatis</artifactId>
<version>最新版本</version>
</dependency>
替換org.mybatis.spring.SqlSessionFactoryBean即可
<!-- 替換SqlSessionFactoryBean -->
<bean id="sqlSessionFactory"
class="net.oschina.durcframework.easymybatis.ext.SqlSessionFactoryBeanExt">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:mybatis/mybatisConfig.xml</value>
</property>
<property name="mapperLocations">
<list>
<value>classpath:mybatis/mapper/*.xml</value>
</list>
</property>
<!-- 以下是附加屬性 -->
<!-- 參見net.oschina.durcframework.easymybatis.DbType,預設mysql -->
<property name="dbType" value="mysql" />
<!-- dao所在的包名,跟MapperScannerConfigurer的basePackage一致
多個用;隔開
-->
<property name="basePackage" value="com.myapp.dao" />
</bean>
意見交流
QQ群:328419269