文章內(nèi)容輸出來源:拉勾教育Java高薪訓(xùn)練營
介紹
Mybatis使用注解開發(fā),可以減少編寫XML文件,對于不復(fù)雜的數(shù)據(jù)邏輯處理也是比較簡單適用。
本文演示Mybatis使用注解開發(fā)的增刪改查操作。
注解介紹
@Insert:插入
@Update:更新
@Delete:刪除
@Select:查詢
-
@Result:封裝結(jié)果集。對應(yīng)xml文件中的<resultMap>中的<result>子標簽
- id:是否主鍵字段
- column:數(shù)據(jù)庫列名
- property:屬性名
- one:一對一@One注解
- many:一對多@Many注解
如果列和屬性的名稱一樣,則可以省略@result,mybatis會自動映射
@Results:多個封裝結(jié)果集,與@Result一起使用。對應(yīng)xml文件中的<resultMap>標簽
-
@ResultMap:引用映射結(jié)果集,減少冗余
eg:@ResultMap(value="studentMap")。其中value值為@Results中定義的id屬性
-
@One:一對一結(jié)果集封裝。對應(yīng)xml文件中的<association>標簽
- select:指定多表查詢的mapper
- fetchType:加載方式,會覆蓋全局的配置參數(shù)
lazyLoadingEnabled - column:關(guān)聯(lián)的外鍵ID
- property:屬性名
fetchType:FetchType.EAGER表示立即加載,F(xiàn)etchType.LAZY表示延遲加載
eg:@Result(column=" ",property="",one=@One(select="")) -
@Many:一對多結(jié)果集封裝。對應(yīng)xml文件中的<collection>標簽
- select:指定多表查詢的mapper
- fetchType:加載方式,會覆蓋全局的配置參數(shù)
lazyLoadingEnabled - column:關(guān)聯(lián)的外鍵ID
- property:屬性名
- javaType:屬性的類型,一般為List.class
eg:@Result(property="",column="",javaType=List.class,many=@Many(select=""))
-
@Options:這個注解對應(yīng)映射語句中的屬性配置。常用屬性如下:
- useCache=true,
- flushCache=false,
- resultSetType=FORWARD_ONLY,
- statementType=PREPARED,
- fetchSize= -1
- timeout=-1 ,
- useGeneratedKeys=false
- keyProperty="id"
-
@Param:參數(shù)注解
當(dāng)需要多個參數(shù)時,此注解用于給每一個參數(shù)定義名稱。否則就會被以它們的順序位置命名,如#{1}、#{2}等。
使用@Param(“person”),SQL中參數(shù)解析就可以使用#{person} -
@SelectKey:插入后,獲取id的值
eg:@SelectKey(statement = "select last_insert_id()" ,keyProperty = "id",keyColumn = "id",resultType = int.class,before = false)
其中before屬性,默認是true,在執(zhí)行插入語句之前,執(zhí)行select last_insert_id()。如果設(shè)置為flase,則在插入這個語句之后,執(zhí)行select last_insert_id()
在已經(jīng)被@Insert/@InsertProvider/@Update/@UpdateProvider注解了的方法上使用才有效 -
@InsertProvider、@DeleteProvider、@UpdateProvider、@SelectProvider:用于生成插入、刪除、更新、查詢的SQL語句
eg:@SelectProvider(type = SqlProvider.class, method = "selectUser")
示例
一、開始之前的配置
項目代碼鏈接:mybatis_demo_01_annoation
1、基于order訂單表和user表的操作,兩張表的實體如下
- OrderEntity
public class OrderEntity {
private Integer id;
private Integer userId;
private BigDecimal amount;
//訂單關(guān)聯(lián)的用戶
private UserEntity user;
//ignore setter/getter
}
- UserEntity
public class UserEntity {
private Integer id;
private String name;
//用戶關(guān)聯(lián)的訂單數(shù)據(jù)
private List<OrderEntity> orders;
//ignore setter/getter
}
2、創(chuàng)建OrderDao和UserDao接口
3、在mybatis配置文件上配置對應(yīng)的mapper,或者直接配置mapper所在的package包路徑
<configuration>
<mappers>
<!--<mapper class="com.yyh.demo.dao.OrderDao"/>
<mapper class="com.yyh.demo.dao.UserDao"/>-->
<package name="com.yyh.demo.dao"/>
</mappers>
</configuration>
4、創(chuàng)建OrderTest和UserTest的單元測試類
二、新增訂單數(shù)據(jù)
- 多參數(shù)新增訂單
/**
* 多參數(shù)添加訂單數(shù)據(jù)
* @param userId 用戶ID
* @param amount 金額
* @return 返回值大于0表示插入成功
*/
@Insert("INSERT INTO `order`(user_id, amount) VALUES(#{userId}, #{amount})")
int insert(@Param("userId") Integer userId, @Param("amount") BigDecimal amount);
- 實體參數(shù)新增訂單
/**
* 實體參數(shù)添加訂單數(shù)據(jù)
* @param order 訂單實體
* @return 返回值大于0表示插入成功
*/
@Insert("INSERT INTO `order`(user_id, amount) VALUES(#{order.userId}, #{order.amount})")
int insertWithEntity(@Param("order") OrderEntity order);
- 實體參數(shù)新增訂單,并返回新增的訂單ID
/**
* 實體參數(shù)添加訂單數(shù)據(jù),并返回訂單ID
* @param order 訂單實體
* @return 返回值大于0表示插入成功
*/
@Insert("INSERT INTO `order`(user_id, amount) VALUES(#{order.userId}, #{order.amount})")
@Options(useGeneratedKeys = true, keyProperty = "order.id", keyColumn = "id")
int insertWithEntityAndReturnId(@Param("order") OrderEntity order);
三、更新訂單數(shù)據(jù)
- 多參數(shù)更新訂單金額
/**
* 更新某訂單的金額
* @param id 訂單ID
* @param amount 金額
* @return 返回值大于0表示更新成功
*/
@Update("UPDATE `order` SET amount=#{amount} WHERE id=#{id}")
int updateAmount(@Param("id") Integer id, @Param("amount") BigDecimal amount);
- 實體參數(shù)更新訂單金額
/**
* 更新某訂單的金額
* @param order 訂單實體
* @return 返回值大于0表示更新成功
*/
@Update("UPDATE `order` SET amount=#{order.amount} WHERE id=#{order.id}")
int updateAmountWithEntity(@Param("order") OrderEntity order);
四、刪除訂單數(shù)據(jù)
/**
* 根據(jù)訂單ID刪除訂單
* @param id 訂單ID
* @return 返回值大于0表示刪除成功
*/
@Delete("DELETE FROM `order` WHERE id=#{id}")
int delete(@Param("id") Integer id);
五、查詢?nèi)坑唵螖?shù)據(jù)
@Select("SELECT * FROM `order`")
List<OrderEntity> selectList();
六、查詢單條訂單數(shù)據(jù)
/**
* 根據(jù)訂單ID查詢訂單數(shù)據(jù)
* @param id 訂單ID
* @return
*/
@Select("SELECT * FROM `order` WHERE id=#{id}")
OrderEntity selectOne(@Param("id") Integer id);
七、查詢訂單以及關(guān)聯(lián)的用戶數(shù)據(jù)
- 聯(lián)合查詢
/**
* 獲取訂單數(shù)據(jù)以及關(guān)聯(lián)的用戶信息
* @param id 訂單ID
* @return
*/
@Select("SELECT t1.id,t1.amount,t1.user_id,t2.name as user_name FROM `order` t1,user t2 where t1.user_id=t2.id AND t1.id=#{id}")
@Results({
@Result(id=true, column = "id", property = "id"),
@Result(column = "amount", property = "amount"),
@Result(column = "user_id", property = "userId"),
@Result(column = "user_id", property = "user.id"),
@Result(column = "user_name", property = "user.name")
})
OrderEntity selectOneWithUser(Integer id);
- 嵌套查詢
/**
* 獲取訂單數(shù)據(jù)以及關(guān)聯(lián)的用戶信息
* @param id 訂單ID
* @return
*/
@Select("SELECT * FROM `order` WHERE id=#{id}")
@Results({
@Result(id=true, column = "id", property = "id"),
@Result(column = "amount", property = "amount"),
@Result(column = "user_id", property = "user",
javaType = UserEntity.class, one = @One(select = "com.yyh.demo.dao.UserDao.selectOne"))
})
OrderEntity selectOneWithUser2(Integer id);
八、查詢用戶以及關(guān)聯(lián)的訂單數(shù)據(jù)
- 嵌套查詢,延遲加載
/**
* 獲取某用戶的數(shù)據(jù)以及關(guān)聯(lián)訂單數(shù)據(jù)。延遲加載
* @param id
* @return
*/
@Select("select * from user where id=#{id}")
@Results({
@Result(id=true, column = "id", property = "id"),
@Result(column = "name", property = "name"),
@Result(property = "orders", column = "id",
javaType = List.class, many = @Many(select = "com.yyh.demo.dao.OrderDao.selectListByUser", fetchType = FetchType.LAZY))
})
UserEntity selectOneWithOrders(Integer id);
- 嵌套查詢
/**
* 獲取某用戶的數(shù)據(jù)以及關(guān)聯(lián)訂單數(shù)據(jù)
* @param id
* @return
*/
@Select("select * from user where id=#{id}")
@Results({
@Result(id=true, column = "id", property = "id"),
@Result(column = "name", property = "name"),
@Result(property = "orders", column = "id",
javaType = List.class, many = @Many(select = "com.yyh.demo.dao.OrderDao.selectListByUser"))
})
UserEntity selectOneWithOrders2(Integer id);
九、使用動態(tài)SQL支持復(fù)雜條件的查詢訂單數(shù)據(jù)
- 用script標簽包裹,像xml文件編寫腳本
public class OrderParam {
//最小金額
private BigDecimal minAmount;
//最大金額
private BigDecimal maxAmount;
//用戶ID
private Integer userId;
//ignore getter/setter
}
/**
* 復(fù)雜的查詢訂單數(shù)據(jù)
* @param param
* @return
*/
@Select({
"<script>",
"SELECT * FROM `order`",
"<where> ",
"<if test='null != userId'>and user_id=#{userId}</if>",
"<if test='null != minAmount'>and amount >= #{minAmount}</if>",
"<if test='null != maxAmount'>and amount <= #{maxAmount}</if>",
"</where>",
"</script>"
})
List<OrderEntity> selectListByCondition2(OrderParam param);
- 用Provider去實現(xiàn)SQL拼接
- 示例1
public class OrderProvider {
public String selectListByCondition(OrderParam param) {
SQL sql = new SQL().SELECT("*").FROM("`order`");
if(null != param.getUserId()) {
sql.WHERE("user_id=#{userId}");
}
if(null != param.getMinAmount()) {
sql.WHERE("amount>=#{minAmount}");
}
if(null != param.getMaxAmount()) {
sql.WHERE("amount<=#{maxAmount}");
}
return sql.toString();
}
}
/**
* 復(fù)雜的查詢訂單數(shù)據(jù)
* @param param
* @return
*/
@SelectProvider(type = OrderProvider.class, method="selectListByCondition")
List<OrderEntity> selectListByCondition(OrderParam param);
- 示例2
public class OrderProvider {
public String selectListByCondition2(Map<String, Object> param) {
SQL sql = new SQL().SELECT("*").FROM("`order`");
if(null != param.get("userId")) {
sql.WHERE("user_id=#{userId}");
}
if(null != param.get("minAmount")) {
sql.WHERE("amount>=#{minAmount}");
}
if(null != param.get("maxAmount")) {
sql.WHERE("amount<=#{maxAmount}");
}
return sql.toString();
}
}
/**
* 復(fù)雜的查詢訂單數(shù)據(jù)
* @param userId 用戶ID
* @param minAmount 最小金額
* @param maxAmount 最大金額
* @return
*/
@SelectProvider(type = OrderProvider.class, method="selectListByCondition2")
List<OrderEntity> selectListByCondition3(@Param("userId") Integer userId, @Param("minAmount") BigDecimal minAmount, @Param("maxAmount") BigDecimal maxAmount);
如果接口有多個參數(shù),在provider中要使用Map<String, Object>來進行接收