接上一篇:https://blog.csdn.net/liuyuan5363/article/details/106994916
Resources读取文件流的工具类:
import java.io.InputStream;
public class Resources {
public static InputStream getResource(String resource){
return Resources.class.getResourceAsStream(resource) ;
}
}
SqlSession定义操作数据库的方法:
import java.util.List;
public interface SqlSession {
<E> List <E> getAll(String statementId,Object param)throws Exception;
<T> T getOne(String statementId,Object param)throws Exception;
void close()throws Exception;
}
DefaultSqlSession是SqlSession的实现类:
import java.util.List;
import com.config.Configuration;
import com.config.MappedStatement;
import com.executor.Executor;
import com.executor.SimpleExecutor;
public class DefaultSqlSession implements SqlSession {
private Configuration configuration ;
public DefaultSqlSession(Configuration configuration) {
super();
this.configuration = configuration;
}
Executor executor = new SimpleExecutor();
public <E> List<E> getAll(String statementId, Object param) throws Exception {
MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId) ;
return executor.query(configuration, mappedStatement, param) ;
}
public <T> T getOne(String statementId, Object param) throws Exception {
List <T>list = getAll(statementId,param);
if(null!=list && list.size()==1){
return list.get(0) ;
}
if(null!=list && list.size()>1){
throw new Exception("查询结果记录多余一条") ;
}
return null;
}
public void close() throws Exception {
executor.close();
}
}
定义抽象工厂接口 SqlSessionFactory:
public interface SqlSessionFactory {
SqlSession openSession();
}
抽象工厂实现类 DefaultSqlSessionFactory:
import com.config.Configuration;
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private Configuration configuration ;
public DefaultSqlSessionFactory(Configuration configuration) {
super();
this.configuration = configuration;
}
public SqlSession openSession() {
return new DefaultSqlSession(configuration);
}
}
SqlSessionFactoryBuild工厂的创建类:
import java.io.InputStream;
import com.config.Configuration;
import com.config.XmlSqlConfigBuild;
public class SqlSessionFactoryBuild {
Configuration configuration ;
public SqlSessionFactoryBuild(){
configuration = new Configuration();
}
public SqlSessionFactory bulid(InputStream inputStream)throws Exception{
XmlSqlConfigBuild xmlSqlConfigBuild = new XmlSqlConfigBuild(configuration);
configuration = xmlSqlConfigBuild.parseSqlConfig(inputStream);
SqlSessionFactory sqlSessionFactory = new DefaultSqlSessionFactory(configuration);
return sqlSessionFactory ;
}
}
sql执行接口 Executor
import java.util.List;
import com.config.Configuration;
import com.config.MappedStatement;
public interface Executor {
<E> List <E> query(Configuration configuration,MappedStatement mappedStatement,Object param)throws Exception;
void close ()throws Exception ;
}
Executor实现类:
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import com.config.Configuration;
import com.config.MappedStatement;
import com.util.BoundSql;
import com.util.GenericTokenParser;
import com.util.ParameterMapping;
import com.util.ParameterMappingTokenHandler;
public class SimpleExecutor implements Executor {
Connection connection ;
public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object param)
throws Exception {
connection = configuration.getDataSource().getConnection() ;
//select a.id as id a.user_name as userName from t_user a
//where a.id=#{id} and a.user_name=#{userName}
//=>where a.id=? and a.user_name=?
String sql = mappedStatement.getSql() ;
//boundSql中sqlText是解析后的sql,List<ParameterMapping> parameterMappings 存的是传入的参数的属性值(id,userName)
BoundSql boundSql = getBoundSql(sql);
PreparedStatement ps = connection.prepareStatement(boundSql.getSqlText()) ;
//ps.setObject(i+1, x);
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings() ;
//id,userName
Class <?> parameterClass = mappedStatement.getParameterClass() ;
if(null!=parameterMappings && null!=parameterClass){
for(int i=0;i<parameterMappings.size();i++){
ParameterMapping parameterMapping = parameterMappings.get(i) ;
String content = parameterMapping.getContent() ;
Field field = parameterClass.getDeclaredField(content) ;
field.setAccessible(true);
//通过反射取参数的属性值,比如id,取的就是user参数的id值
Object v = field.get(param) ;
ps.setObject(i+1, v);
}
}
ResultSet resultSet = ps.executeQuery() ;
Class<?> resultClass = mappedStatement.getResultClass() ;
List results = new ArrayList();
while(resultSet.next()){
Object object = resultClass.newInstance() ;//Users u = new Users()
ResultSetMetaData resultSetMetaData = resultSet.getMetaData() ;
//select a.id as id a.user_name as userName
int cloumnCount = resultSetMetaData.getColumnCount() ;
for(int i=0;i<cloumnCount;i++){
/*Users u = new Users();
String userName = resultSet.getString("username") ;
u.setUserName(userName);*/
//id,userName
String columnName = resultSetMetaData.getColumnName(i+1) ;
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName,resultClass);
Method method = propertyDescriptor.getWriteMethod() ;
method.invoke(object, resultSet.getObject(i+1)) ;//u.setUserName(userName);
}
results.add(object) ;
}
return results;
}
public void close() throws Exception {
if(null!=connection){
connection.close();
}
}
public BoundSql getBoundSql(String sql){
ParameterMappingTokenHandler parameterMappingTokenHandler = new ParameterMappingTokenHandler();
GenericTokenParser genericTokenParser = new GenericTokenParser("#{","}",parameterMappingTokenHandler);
String sqlText = genericTokenParser.parse(sql) ;
BoundSql boundSql = new BoundSql(sqlText,parameterMappingTokenHandler.getParameterMappings());
return boundSql ;
}
}
以下这几个类都是ibatis中的:
最后junit测试:
@Test
public void test(){
try{
InputStream inputStream = Resources.getResource("/sqlConfig.xml") ;
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuild().bulid(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession() ;
/*List <Users> list = sqlSession.getAll("user.getAll", null) ;
for(Users u:list){
System.out.println(u.getId()+","+u.getUserName());
}*/
Users param = new Users();
param.setId(1);
param.setUserName("aa");
Users result = sqlSession.getOne("user.getOne", param) ;
System.out.println(result.getId()+","+result.getUserName());
sqlSession.close();
}catch(Exception ex){
ex.printStackTrace();
}
}