2012-08-28 23 views
9

Gần đây tôi đã sử dụng Mybatis3 và thấy rằng khi câu lệnh SQL của bạn nhận được một tập kết quả trống từ cơ sở dữ liệu, Mybatis tạo một List mới và trả về chương trình của bạn.Làm thế nào là MyBatis xử lý một tập kết quả trống?

Với một số mã như:

List<User> resultList = (List<User>)sqlSession.select("statementId"); 

<select id="statementId" resultType="User"> 
    select * from user where id > 100 
</select> 

giả định rằng SQL trên trở lại không có hàng (ví dụ: không có id lớn hơn 100).

Biến resultList sau đó sẽ trống List, nhưng tôi muốn nó là null thay thế. Tôi có thể làm như thế nào?

Trả lời

15

Tốt hơn nên có một bộ sưu tập trống thay vì null do truy vấn của bạn. Khi làm việc với một bộ sưu tập, bạn thường lặp qua từng mục và làm điều gì đó với nó, như sau:

List<User> resultList = (List<User>) sqlSession.select("statementId"); 
for (User u : resultList) { 
    //... 
} 

không làm gì nếu danh sách trống.

Nhưng nếu bạn quay lại null, bạn có để bảo vệ mã của bạn chống lại NullPointerExceptions và viết mã như thế này thay vì:

List<User> resultList = (List<User>) sqlSession.select("statementId"); 
if (resultList != null) { 
    for (User u : resultList) { 
    //... 
    } 
} 

Phương pháp đầu tiên là thường tốt hơn và MyBatis làm nó như thế, nhưng bạn có thể buộc nó để trả về null, nếu đó thực sự là những gì bạn muốn.

Để làm điều đó bạn có thể viết MyBatis plugin và chặn các cuộc gọi đến bất kỳ truy vấn nào và sau đó trả về null nếu kết quả truy vấn trống.

Dưới đây là một số mã:

Trong cấu hình add bạn:

<plugins> 
    <plugin interceptor="pack.test.MyInterceptor" /> 
</plugins> 

Mã đánh chặn:

package pack.test; 

import java.util.List; 
import java.util.Properties; 

import org.apache.ibatis.executor.Executor; 
import org.apache.ibatis.mapping.MappedStatement; 
import org.apache.ibatis.plugin.Interceptor; 
import org.apache.ibatis.plugin.Intercepts; 
import org.apache.ibatis.plugin.Invocation; 
import org.apache.ibatis.plugin.Plugin; 
import org.apache.ibatis.plugin.Signature; 
import org.apache.ibatis.session.ResultHandler; 
import org.apache.ibatis.session.RowBounds; 

@Intercepts({ @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}) }) 
public class MyInterceptor implements Interceptor { 
    public Object intercept(Invocation invocation) throws Throwable { 
     Object result = invocation.proceed(); 
     List<?> list = (List<?>) result; 
     return (list.size() == 0 ? null : result); 
    } 

    public Object plugin(Object target) { 
     return Plugin.wrap(target, this); 
    } 

    public void setProperties(Properties properties) { 
    } 
} 

Sau đó, bạn có thể tiếp tục giới hạn phạm vi đánh chặn nếu bạn chặn cuộc gọi đến ResultSetHandler thay vì Executor.

1

Bạn nên sử dụng danh sách trống thay vì null vì những lý do sau.

Sử dụng vô giá trị null có thể gây ra nhiều lỗi đáng kinh ngạc.

Ngoài ra, null không rõ ràng là không rõ ràng. Nó hiếm khi rõ ràng những gì một giá trị trả về null có nghĩa là - ví dụ, Map.get (key) có thể trả về null vì giá trị trong bản đồ là null, hoặc giá trị không có trong bản đồ. Null có thể có nghĩa là thất bại, có thể có nghĩa là thành công, có thể có nghĩa là hầu hết mọi thứ. Sử dụng một cái gì đó khác null làm cho ý nghĩa của bạn rõ ràng.

good discussion about null usage

Các vấn đề liên quan