1. 程式人生 > >關於easymybatis——mybatis開發利器

關於easymybatis——mybatis開發利器

easymybatis

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層方法

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