Mybatis大家都是所知道的是对应的是dao层接口,那么我们都知道接口是不能实例化对象的,那么是如何进行数据库操作的呢?
Mybatis底层是通过生成dao层接口的代理类从而操作数据库的
package com.ssm.proxy;
import com.ssm.dao.UserMapper;
public class ProxyMain {
public static void main(String[] args) {
UserMapper mapper = (UserMapper) SZSession.getMapper(UserMapper.class);
System.out.println("mian============"+mapper.getClass().getName());
mapper.selectAllUser();
}
}
package com.ssm.proxy;
import java.lang.reflect.Proxy;
public class SZSession {
public static Object getMapper(Class clazz){
Class[] classz=new Class[]{clazz};
Object object=Proxy.newProxyInstance(clazz.getClassLoader(),classz,new SZInvocationHandler());
return object;
}
}
package com.ssm.dao;
import com.ssm.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
List<User> selectAllUser();
}
package com.ssm.proxy;
import com.ssm.pojo.User;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.jdbc.Null;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class SZInvocationHandler implements InvocationHandler
{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("proxy============="+proxy.getClass().getName());
Select annotation = method.getAnnotation(Select.class);
String sql = annotation.value()[0];
System.out.println(sql);
Class.forName("com.mysql.jdbc.Driver");
Connection root = DriverManager.getConnection("jdbc:mysql://localhost:3306/stu", "root", "123");
PreparedStatement preparedStatement = root.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
List<User> list=new ArrayList<>();
while (resultSet.next()){
User user=new User();
user.setId(resultSet.getString("id"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
list.add(user);
}
System.out.println(list);
return null;
}
}
执行结果
mian============com.sun.proxy.$Proxy0
proxy=============com.sun.proxy.$Proxy0
select * from user
[User(id=1, username=sz, password=123), User(id=2, username=sun, password=123),]
从上面可以可能出来执行成功,而在我main方法的mapper对象就是生成的代理对象,在InvocationHandler中的invoke中三个参数的作用分别是 。
proxy :可以用proxy通过反射获取到生成的代理对象
method:这个就是目前正在执行的方法
args:是正在执行方法的参数
下面加入Spring IOC容器中
//在这里我用一个配置类代表Spring 的主配置文件
package com.ssm.proxy;
import com.ssm.dao.UserMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration
public class SZConfiguration {
@Bean
public UserMapper userMapper(){
return (UserMapper) SZSession.getMapper(UserMapper.class);
}
}
package com.ssm.ssm;
import com.ssm.dao.UserMapper;
import com.ssm.pojo.User;
import com.ssm.proxy.SZConfiguration;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.security.auth.login.Configuration;
import java.lang.reflect.Proxy;
public class SpringDome {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(SZConfiguration.class);
UserMapper bean = applicationContext.getBean(UserMapper.class);
System.out.println(bean.selectAllUser());
}
}
执行结果
proxy=============com.sun.proxy.$Proxy9
select * from user
[User(id=1, username=sz, password=123), User(id=2, username=sun, password=123)]
可以看到在这个spring使用的是我自己手写的mybatis底层