注解|注解,反射的简单应用
java的注解和反射学了一直没有用到,主要是框架帮我们封装好了,那就好了,仿写框架就可以开拓新思路
仿mybatis写一个简易的orm框架
注解 (sql注解)
/**
* @author
* sql操作
*运行时检查
*注解标记的位置,在方法上
* */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Select {String value();
}
mapper接口
/**
* @author cainiao
* */
public interface UserMapper {@Select(value = "https://www.it610.com/article/select * from user where id = #{id}")
User select(int id);
@Insert(value = "https://www.it610.com/article/insert into user () values ()")
void insert(User user);
void update(User user);
void delete(int id);
}
jdbc的工具类,为了简单,就不用数据库连接池
/**
* @author 连接数据库
*/
public class JDBCConfig {private static String url = null;
private static String driver = null;
private static String username = null;
private static String password = null;
private static final String file = "db.properties";
static {
try {
InputStream input = JDBCConfig.class.getClassLoader().getResourceAsStream(file);
Properties properties = new Properties();
properties.load(input);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
} catch (Exception e) {
e.printStackTrace();
}
}public static Connection getConnection() throws Exception{
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
}
public static void getClose(Connection conn, PreparedStatement ps, ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
rs=null;
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ps = null;
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
包装数据的工具类
/**
* @author cainiao
* 封装返回数据
*/
public class MapperUtil {//增 删 改
public static int update(String sql,Object...values) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
int rows = -1 ;
try {
conn = JDBCConfig.getConnection();
ps = conn.prepareStatement(sql);
int len = values.length;
for(int i = 0;
i List query(Class clazz, String sql, Object[] values) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List beans = new ArrayList<>();
try {
conn = JDBCConfig.getConnection();
ps = conn.prepareStatement(sql);
int valueCount = values.length;
for (int i = 0;
i < valueCount;
i++) {
ps.setObject(i + 1, values[i]);
}
rs = ps.executeQuery();
ResultSetMetaData meta = rs.getMetaData();
int colum = meta.getColumnCount();
while (rs.next()) {
T bean = clazz.newInstance();
for (int i = 0;
i < colum;
i++) {
String label = meta.getColumnName(i + 1);
Field field = bean.getClass().getDeclaredField(label);
field.setAccessible(true);
Object value = https://www.it610.com/article/rs.getObject(label);
field.set(bean, value);
}
beans.add(bean);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCConfig.getClose(conn, ps, rs);
}
return beans;
}
public static void main(String[] args) {
ArrayList list = (ArrayList) MapperUtil.query(User.class,"select * from user where id = ?",new Object[]{19});
for (Object object:list){
System.out.println((User)object);
}
}
}
简单的java对象
@Table(value = "https://www.it610.com/article/user")
public class User {@Property(value = "https://www.it610.com/article/id")
private int id;
private String username;
private String password;
private String salt;
private int state;
private String email;
private String phone;
private Date created;
private Date modified;
}
mapper接口没有实现类,要实现其功能需要用到jdk动态代理,这里代理不是做切面用,而是拿到接口的方法的各种参数
jdk动态代理
/**
* @author jdk动态代理
*/
public class MapperProxy implements InvocationHandler {private Class target;
/**
*存放截取过程中的sql片段
*/
static List list = new ArrayList<>();
public MapperProxy(Class target) {
this.target = target;
}/**
* 拿到接口类
* 代理类
* 调用的方法
* 方法的参数值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取返回值类型
Type type = method.getGenericReturnType();
//获取参数类型
Type[] types = method.getGenericParameterTypes();
//变量名
Parameter[] parameters = method.getParameters();
//返回信息
Object object = null;
Annotation[] annotations = method.getDeclaredAnnotations();
for (Annotation annotation : annotations) {
String name = annotation.annotationType().getSimpleName();
String sql = null;
switch (name) {
case "Select":
sql = method.getDeclaredAnnotation(Select.class).value();
object = select(sql, type, args, parameters);
break;
case "Insert":
sql = method.getDeclaredAnnotation(Insert.class).value();
break;
case "Update":
sql = method.getDeclaredAnnotation(Select.class).value();
break;
case "Delete":
sql = method.getDeclaredAnnotation(Select.class).value();
break;
default:
}
}
return object;
}/**
* 查询方法
*/
private Object select(String sql, Type type, Object[] args, Parameter[] parameters) throws ClassNotFoundException {
Class> clazz = Class.forName("com.orm.pojo.User");
StringBuilder sb = new StringBuilder();
jiequ(sql);
for (int i = 0;
i < args.length;
i++) {
sb.append(list.get(i));
}
System.out.println(sb);
//转为string ,不转会越界报错
sql = sb + "";
//执行sql
List objects = MapperUtil.query(clazz, sql, args);
if (objects.size() == 1) {
try {
return objects.get(0);
} catch (Exception e) {
e.printStackTrace();
}
}
return objects;
}private void insert(Type type, Type[] types, Object[] args) {}private void update(Type type, Type[] types, Object[] args) {}private void delete(Type type, Type[] types, Object[] args) {}/**
* sql截取
*/
public void jiequ(String sql) {
if (sql.contains("#")) {
String[] sqls = sql.split("and", 2);
for (int i = 0;
i < sqls.length;
i++) {
if (i == 0) {
String[] temps = sqls[i].split("\\#");
for (int j = 0;
j < sqls.length;
j++) {
if (j == 0) {
list.add(temps[j] + "?");
}
}
} else {
jiequ(sqls[i]);
}
}
}
}public static void main(String[] args) {}}
这里stringbuilder必须先转为String,不然prepareStatement会报越界错误
创建代理的类
/**
* @author
* */
public class MapperFactory {public static T newInstance(Class target){
MapperProxy mapperProxy = new MapperProxy(target);
return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class[]{target},mapperProxy);
}
}
测试类
/**
* @author
* */
public class UserService {
/**
* 注入mapper
* */
private UserMapper userMapper = MapperFactory.newInstance(UserMapper.class);
public void get(int id){
User user = userMapper.select(id);
System.out.println(user);
}public static void main(String[] args) {
UserService userService = new UserService();
userService.get(19);
}
}
测试
![注解|注解,反射的简单应用](https://img.it610.com/image/info10/0aaa8db9a55248438e8e60b78c6a70f7.jpg)
文章图片
aaaa.png 还有不足,引用pojo类没有动态的获取
【注解|注解,反射的简单应用】github:https://github.com/cailonghao/Imitation-writing
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量