1 Mapper層註解
Mapper
層註解@Reponsitory
和@Mapper
經常使用但是不知道區別,就學習記錄下
1.1 @Repository
@Repository
:@Repository
的作用與@Controller
,@Service
的作用都是把對象交給Spring
管理。@Repository
是標註在Dao
層接口上,作用是將接口的一個實現類交給Spring
管理。
注意
:
- 使用這個註解的前提是必須在啓動類上添加
@MapperScan("Mapper接口層路徑")
註解
這個@Repository
完全可以省略不寫,也完全可以實現自動注入,但是在IDEA
中會存在一個紅色的波浪線。原因如下:
Spring
配置文件中配置了MapperScannerConfiguer
這個Bean
,它會掃描持久層接口創建實現類並交給Spring
管理。SpringBoot
的啓動類上標註了@MapperScanner
,它的作用和上面的MapperScannerConfiguer
作用一樣
1.2 @Mapper
@Mapper
: 這個註解一般使用在Dao
層接口上,相當於一個mapper.xml
文件,它的作用就是將接口生成一個動態代理類。加入了@Mapper
註解,目的就是爲了不再寫mapper
映射文件。這個註解就是用來映射mapper.xml
文件的。
使用@mapper
後,不需要在spring
配置中設置掃描地址,通過mapper.xml
裏面的namespace
屬性對應相關的mapper
類,spring
將動態的生成Bean
後注入到ServiceImpl
中
注意
:
在Dao
層不要存在相同名字的接口,也就是在Dao
不要寫重載。因爲mapper
文件是通過id
與接口進行對應的,如果寫了兩個同名的接口,就會導致mapper
文件映射出錯。
1.3 @Mapper和@MapperScan區別
@Mapper
註解寫在每個Dao
接口層的接口類上,@MapperScan
註解寫在SpringBoot
的啓動類上。
當我們的一個項目中存在多個Dao
層接口的時候,此時我們需要對每個接口類都寫上@Mapper
註解,非常的麻煩,此時可以使用@MapperScan
註解來解決這個問題。讓這個接口進行一次性的注入,不需要在寫@Mapper
註解
@SpringBootApplication
@MapperScan("cn.gyyx.mapper")
// 這個註解可以掃描 cn.gyyx.mapper 這個包下面的所有接口類,可以把這個接口類全部的進行動態代理。
public class WardenApplication {
public static void main(String[] args) {
SpringApplication.run(WardenApplication.class,args);
}
}
@Mapper
註解相當於是@Reponsitory
註解和@MapperScan
註解的和,會自動的進行配置加載。@MapperScan
註解多個包,@Mapper
只能把當前接口類進行動態代理。
在實際開發中,如何使用@Mapper、@MapperSacn、@Repository
註解
- 在
SpringBoot
的啓動類上給定@MapperSacn
註解。此時Dao
層可以省略@Mapper
註解,當讓@Repository
註解可寫可不寫,最好還是寫上。
當使用@Mapper
註解的時候,可以省略@MapperSacn
以及@Repository
。
建議:
- 以後在使用的時候,在啓動類上給定
@MapperScan("Dao層接口所在的包路徑")
。在Dao
層上不寫@Mapper
註解,寫上@Repository
即可
1.4 動態SQL註解
MyBatis
的動態SQL
註解開發是基於Java註解和接口方法的,通過在接口方法上使用註解,可以在運行時生成對應的SQL
語句。MyBatis
會根據接口方法的註解來生成SQL
,並將它們與數據庫進行交互。它可以在實體類或映射文件中使用註解來配置映射關係。常用的註解包括 @Select、@Update、@Insert、@Delete
等,它們分別用於配置查詢、更新、插入和刪除操作。通過這些註解,我們可以直接在實體類或映射文件中定義 SQL 語句,而不需要像傳統的 MyBatis 配置方式那樣在映射文件中使用 <select>、<update>、<insert> 和 <delete>
標籤來定義 SQL 語句
1.4.1 @Select
1.4.1.1 基本用法
@Select
:該註解的目的是爲了取代mapper.xml
中的select
標籤,只作用於方法上面。此時就不要在寫mapper.xml
文件了。
@Select
註解的源碼
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Select
{
String[] value();
}
從上述可以看到兩點信息:@Select
註解只能修飾方法。@Select
註解的值是字符數組。
所以,@Select
註解的用法是這樣的:
@Select({ "select * from xxx", "select * from yyy" })
Person selectPersonById(Integer id);
雖然@Select
註解的值是字符數組,但是真正生效的應該是最後那條SQL語句
1.4.1.2 @Select註解動態SQL拼寫
普通的字符串值,只能實現變量的替換功能,實現簡單的SQL
語句,如下所示
@Select("select * from t_person where id = #{id}")
Person selectPersonById(Integer id);
如果要想實現複雜的邏輯判斷,則需要使用標籤 ,如下所示:
@Select("<script> select * from t_person where id = #{id}
<when test='address !=null'> and address = #{address}
</when> </script>")
Person selectPersonById(Integer id);
其實,標籤 註解專用的,其他的註解,例如@Insert、@Update、@Delete等等,都可以使用的。
1.4.2 與@Select相關注解
import java.util.List;
import me.gacl.domain.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
/**
* @author gacl
* 定義sql映射的接口,使用註解指明方法要執行的SQL
*/
public interface UserMapperI {
使用@Insert註解指明add方法要執行的SQL
@Insert("insert into users(name, age) values(#{name}, #{age})")
public int add(User user);
使用@Delete註解指明deleteById方法要執行的SQL
@Delete("delete from users where id=#{id}")
public int deleteById(int id);
使用@Update註解指明update方法要執行的SQL
@Update("update users set name=#{name},age=#{age} where id=#{id}")
public int update(User user);
使用@Select註解指明getById方法要執行的SQL
@Select("select * from users where id=#{id}")
public User getById(int id);
使用@Select註解指明getAll方法要執行的SQL
@Select("select * from users")
public List<User> getAll();
}
1.4.3 動態SQL查詢
動態SQL查詢
通常用於根據不同條件構建SQL
語句。
在這個示例中,我們將演示如何構建一個動態查詢,根據傳遞的參數來動態生成查詢條件。首先,創建一個 UserProvider
類,用於提供動態SQL
查詢的邏輯:
import org.apache.ibatis.jdbc.SQL;
import java.util.Map;
public class UserProvider {
public String dynamicSQL(Map<String, Object> params) {
return new SQL() {
{
SELECT("*");
FROM("users");
if (params.get("username") != null) {
WHERE("username = #{username}");
}
if (params.get("email") != null) {
WHERE("email = #{email}");
}
}
}.toString();
}
}
在Mapper
接口中,使用 @SelectProvider
註解來指定動態SQL
的提供者類和方法。
@SelectProvider(type = UserProvider.class, method = "dynamicSQL")
List<User> searchUsers(UserCriteria criteria);
在這裏,UserProvider
類的 dynamicSQL
方法會根據傳遞的 criteria
參數動態生成SQL
查詢語句,實現了根據用戶名和電子郵件地址查詢用戶的功能。MyBatis
動態註解開發是一種強大的方式,能夠根據不同條件動態生成SQL
語句,無需編寫繁瑣的XML
映射文件,可以在接口方法上直接使用註解,減少了冗餘的代碼。它提供了靈活性和簡潔性,適用於各種不同的數據庫操作需求。
1.5 @Param
接口綁定解決多參數的傳遞,一般使用@Param
@Param
: 動態代理接口向映射文件中傳遞參數的時候,會使用@Param
註解,並且如果動態代理接口使用了@Param
這個註解,那麼映射文件中的標籤中可以不用寫parameterType
屬性,可以直接接收@Param
中傳遞來的參數值
1.5.1 @Param註解基本類型的參數
mapper中的方法:
public User selectUser(@Param("userName") String name,@Param("password") String pwd);
映射到xml
中的標籤
<select id="selectUser" resultMap="User">
select * from user where user_name = #{userName} and user_password=#{password}
</select>
其中where user_name = #{userName} and user_password = #{password}
中的userName
和password
都是從註解@Param()
裏面取出來的,取出來的值就是方法中形式參數 String name
和 String pwd
的值。
重點:當只存在一個參數的時候,此時可以省略這個@Param
註解,但是兩個參數必須使用這個註解。
1.5.2 @Param註解JavaBean對象
SQL
語句通過@Param
註解中的別名把對象中的屬性取出來然後複製 mapper
中的方法:
public List<User> getAllUser(@Param("user") User u);
映射到xml
中的標籤
<select id="getAllUser" parameterType="com.vo.User" resultMap="userMapper">
select
from user t where 1=1
and t.user_name = #{user.userName}
and t.user_age = #{user.userAge}
</select>
注意:
當使用了@Param
註解來聲明參數的時候,SQL
語句取值使用#{}
,${}
取值都可以。
當不使用@Param
註解聲明參數的時候,必須使用的是#{}
來取參數。使用${}
方式取值會報錯。
不使用@Param
註解時,參數只能有一個,可以是一個基本的數據也可以是一個JavaBean
1.5.3 不使用@Param
接口綁定解決多參數的傳遞,如果不使用@Param
,則使用數字的方式取出,從0
開始
接口中定義方法
User selByUP(String username, String password
映射文件中提供對應的標籤
此時, SQL
語句中獲取方式有兩種, 通過#{index}
或#{param+數字}
的方式
<select id="selByUP" resultType="user">
select * from t_user where username=#{0} and password=#{1}
</select>
或者
<select id="selByUP" resultType="user">
select * from t_user where username=#{param1} and password=#{param2}
</select>