2012-11-14 37 views
7

Tôi là một ứng dụng sử dụng mybatis cho sự kiên trì đối tượng. Nhưng có những cơ hội tôi cần để chạy sql tùy ý (từ người dùng). Tôi có thể làm điều đó với mybatis không?Làm thế nào để chạy sql tùy ý với mybatis?

Cập nhật:

tôi chọn để sử dụng dbutils (JDBC) để chạy người dùng định nghĩa sql, nhưng tôi cần một thể hiện của DataSource để tạo QueryRunner. Có cách nào tôi có thể nhận nguồn dữ liệu từ mybatis không?

Trả lời

7

tôi sử dụng lớp utilitary này:

import java.util.List; 
import org.apache.ibatis.annotations.SelectProvider; 

public interface SqlMapper { 
    static class PureSqlProvider { 
     public String sql(String sql) { 
      return sql; 
     } 

     public String count(String from) { 
      return "SELECT count(*) FROM " + from; 
     } 
    } 

    @SelectProvider(type = PureSqlProvider.class, method = "sql") 
    public List<?> select(String sql); 

    @SelectProvider(type = PureSqlProvider.class, method = "count") 
    public Integer count(String from); 

    @SelectProvider(type = PureSqlProvider.class, method = "sql") 
    public Integer execute(String query); 
} 
+0

tôi nhận được một UnsupportedOperationException khi tôi thử điều này .. –

+0

@OrGal Tôi đang sử dụng lớp này trong một thời gian trong các ứng dụng của mình. Bạn đang chạy mã gì để nhận ngoại lệ này? –

+0

@italo, cảm ơn bạn đã trả lời, nhưng nó không hoạt động đối với tệp sql có nhiều hơn một câu? – Suge

2

câu hỏi của bạn cũng tương tự như câu hỏi của How to exequte query directly from java code using mybatis?

tôi đã đưa ra câu trả lời cho câu hỏi đó. Nhưng tôi hy vọng giải pháp này sẽ giúp bạn.

Mybatis đã có chức năng này, nhưng bạn phải sử dụng bộ điều hợp như sau.

  1. tạo lớp bộ điều hợp;

    public class SQLAdapter { 
    String sql; 
    
    public SQLAdapter(String sql) { 
        this.sql = sql; 
    } 
    
    public String getSql() { 
        return sql; 
    } 
    
    public void setSql(String sql) { 
        this.sql = sql; 
    } } 
    
  2. tạo typeAlias ​​của lớp SQLAdapter

<typeAlias alias="sqladapter" type="com.zj.xxx.xxx.SQLAdapter" />

  1. đặt chọn thẻ trong mỗi xml đối tượng mà bạn cần thực thi sql trực tiếp.

    <select id="findRecords" parameterType="SQLAdapter" resultMap="xxxxxResultMap"> 
        ${sql} 
    </select> 
    
  2. phương thức gọi chọn này như

String _sql = "select * from table where... order by... limit..."; 
xxxxx.findRecords(new SQLAdapter(_sql)); 
  1. Mọi thứ đã được tất cả được thực hiện. bạn không còn có thể viết ngôn ngữ sql phức tạp trong tệp xml nữa. Chúc may mắn.
1

Dựa trên các câu trả lời được cung cấp, cả hai đều tốt. Nhưng cả hai đều yêu cầu một lớp Adapter để sử dụng.

Sử dụng Mybatis phiên bản 3, tôi đã thành công sử dụng một HashMap<String, String> để giữ và vượt qua SQL.

Xem các mã bên dưới.

trong Mapper lớp

final String sql = "${sql}"; 

@Select(sql) 
void execute(HashMap<String, String> m); 

khi invoke phương pháp:

String sql = "SELECT * FROM record limit 1"; 
HashMap<String, String> map = new HashMap<String, String>(); 
map.put("sql", sql); 
mapper.execute(map); 

HashMap cung cấp một cách mà bạn không cần phải xác định các tính chất Class, hoặc các lĩnh vực trong mã, bạn có thể sử dụng một Bản đồ để xác định nó một cách hơi đỏ.

Cảm ơn.

+0

Tôi nhận được lỗi sau trong lớp bản đồ của tôi khi tôi thực hiện xây dựng maven. bất kỳ lời khuyên nào? các loại không tương thích: java.util.Map không thể chuyển đổi thành java.lang.String – Razvi

+0

Bạn có biết cách chuyển các tham số vào truy vấn động không? – Razvi

0

Đoạn tái sử dụng của SQL có thể được sử dụng để tạo phần chọn truy vấn động. Trong bạn Mapper truy vấn vượt qua như thông số bình thường:

@Param("sql")String sql

trong truy vấn của bạn chỉ cần truy cập vào các thông số sử dụng $ {} sql thay vì # {} sql. Giá trị trong tham số sql có thể là truy vấn sql hoàn toàn hợp lệ hoặc một đoạn truy vấn sql.

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