mybatis如何实现注解sql的简单例子 博客分类: java mybatissql注解
程序员文章站
2024-03-21 08:15:10
...
最近马上要开动项目了,后台是用mybatis,开始研究mybatis,发现
public interface SqlInterface { @MySelect("select * from t_user where id = 1") public UserPO select(); }
这种实现,感觉蛮有意思的。于是自己模拟写了一个,这里要求读者要有java注解,java反射,代理,java对数据库的操作等要求。如果看不懂代码的话,可以先了解下上面提到的java基础。
首先在mysql的test建个表t_user,字段id,username,password,插入一条数据1,123,123。
一个PO对象UserPO
public class UserPO { public long id; public String userName; public String password;
一个select的注解接口
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MySelect { public String value(); }
一个sql的接口
public interface SqlInterface { @MySelect("select * from t_user where id = 1") public UserPO select(); }
由于比较懒,就直接把代理和test类写在一起
public class TestMain { public static void main(String[] args) { try { //代理 SqlInterface sqlInterface = (SqlInterface) Proxy.newProxyInstance(SqlInterface.class.getClassLoader(), new Class[] { SqlInterface.class }, new InvocationHandler() { public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable { // TODO Auto-generated method stub //获取注解的sql语句 String sqlString = null; if (method.getAnnotation(MySelect.class) != null) { sqlString = method.getAnnotation(MySelect.class).value(); System.out.println(sqlString); } String databaseDriver = "com.mysql.jdbc.Driver"; Connection conn = null; ResultSet rs = null; try { Class.forName(databaseDriver); conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8", "root", "root"); PreparedStatement stmt = conn.prepareStatement(sqlString); rs = stmt.executeQuery(); } catch (Exception e) { e.printStackTrace(); } // 获取数据库字段名称 ResultSetMetaData rsmd = rs.getMetaData(); String[] dataMetas = new String[rsmd.getColumnCount()]; int colcount = rsmd.getColumnCount(); for (int i = 1; i <= colcount; i++) { //dataMetas没有index为0的,从1开始 System.out.println(rsmd.getColumnClassName(i)); dataMetas[i-1] = rsmd.getColumnName(i); } // 获取返回值类型,就是userPO Object o = method.getReturnType().newInstance(); while (rs.next()) { Field[] fields = o.getClass().getDeclaredFields(); for (Field field : fields) { String fieldname = field.getName(); for (String dateMeta : dataMetas) { if (fieldname.toLowerCase().equals(dateMeta)) { field.set(o, rs.getObject(dateMeta)); break; } } } } try { rs.close(); conn.close(); } catch (Exception e) { } return o; } }); UserPO po = sqlInterface.select(); System.out.println(po.getUserName()); } catch (Exception e) { e.printStackTrace(); } } }
这里还是有很多问题的,比如查询带参数,如果返回对象是null或者List,如何处理。
由于只是自己写的一个demo,比较烂,特别是命名和结构,大家了解下原理就好了。
注意run的时候需要mysql-connector-java-5.1.25.jar