mybatis主体流程

1.实例化sqlSessionFactory ,加载数据库配置文件以及mapper.xml 文件到configuration对象中
2.获取sqlSession对象
3.通过动态代理获取接口
4.遵循jdbc规范,通过底层的四大对象的合作完成数据查询和数据转化

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.38</version>
</dependency>

<dependency>
  <groupId>dom4j</groupId>
  <artifactId>dom4j</artifactId>
  <version>1.6</version>
</dependency>

1.完成SqlSessionFactory的创建 
	1.1.生成sqlSession对象
				加载数据库配置文件
	1.2.实例化configuration对象
				加载mapper文件
 public class SqlSessionFactory {

private  final Configuration conf=new Configuration();

private static final String DB_CONFIG_FILE="db.properties";

private static final String MAPPER_CONFIG_LOCATION="mappers";

/**
 * 通过构造方法加载
 * 1.数据库配置文件
 * 2.加载配置文件
 */
public SqlSessionFactory() {
    //1.加载数据库配置文件
    loadDbInfo();

    //2.加载mapper文件
    loadMappersInfo();

}


/**
 * 加载数据库配置文件
 */
private void loadDbInfo() {
    InputStream dbIs = SqlSessionFactory.class.getClassLoader().getResourceAsStream(DB_CONFIG_FILE);
    Properties p = new Properties();
    try {
        p.load(dbIs);
    } catch (IOException e) {
        e.printStackTrace();
    }
    conf.setJdbcDriver(String.valueOf(p.get("db.driver")));
    conf.setJdbcUrl(String.valueOf(p.get("jdbc.url")));
    conf.setJdbcUsername(String.valueOf(p.get("jdbc.username")));
    conf.setJdbcPassword(String.valueOf(p.get("jdbc.password")));
}


/**
 * 加载所有的mapper.xml文件
 */
private void loadMappersInfo() {
    URL resources = SqlSessionFactory.class.getClassLoader().getResource(MAPPER_CONFIG_LOCATION);
    File mappers = new File(resources.getFile());
    if (mappers.isDirectory()){
        File[] listFiles = mappers.listFiles();
        for (File file : listFiles) {
            //加载文件
            loadMapperInfo(file);
        }
    }
}


/**
 * 加载配置文件
 */
private void loadMapperInfo(File file) {
    // 创建reader对象
    SAXReader reader = new SAXReader();

    Document document=null;
    try {
        document = reader.read(file);
    } catch (DocumentException e) {
        e.printStackTrace();
    }
    //获取根节点元素
    Element rootElement = document.getRootElement();
    //获取命名空间
    String namespace = rootElement.attribute("namespace").getData().toString();
    //获取select子列表
    List<Element> selects = rootElement.elements("select");
    for (Element element : selects) {
        //实例化mappedStatement
        MappedStatement mappedStatement = new MappedStatement();
        //读取id
        String id = element.attribute("id").getData().toString();
        //读取返回类型
        String resultType = element.attribute("resultType").getData().toString();
        //读取sql
        String sql = element.getData().toString();

        String sourceId=namespace+"."+id;
        //赋值
        mappedStatement.setNamespace(namespace);
        mappedStatement.setResultType(resultType);
        mappedStatement.setSourceId(sourceId);
        mappedStatement.setSql(sql);
        //注册到conf中
        conf.getMappedStatementMap().put(sourceId,mappedStatement);
    }

}

/**
 * 获取sqlSession
 * @return
 */
public SqlSession openSession(){
    return new DefaultSqlSession(conf);
}
}

public interface SqlSession {

/**
 * 查询单个对象
 * @param statement 方法对应的sql 语句
 * @param parameter sql 参数
 * @param <T>
 * @return
 */
<T> T selectOne(String statement,Object parameter);

/**
 * 查询全部
 * @param statement 方法对应的sql 语句
 * @param parameter sql 参数
 * @param <E>
 * @return
 */
<E> List<E> selectList(String statement,Object parameter);

/**
 * 反射获取mapper对象
 * @param type
 * @param <T>
 * @return
 */
<T> T getMapper(Class<T> type);
}



public class DefaultSqlSession implements SqlSession {

private Configuration conf;
private Executor executor;

public DefaultSqlSession(Configuration conf) {
    this.conf = conf;
    executor=new DefaultExecutor(conf);
}

@Override
public <T> T selectOne(String statement, Object parameter) {
    List<Object> objects = selectList(statement, parameter);
    if (objects==null || objects.size()==0){
        return null;
    }
    if (objects.size()==1){
        return (T) objects.get(0);
    }else {
        throw new RuntimeException("Too Many Result.....");
    }
}

@Override
public <E> List<E> selectList(String statement, Object parameter) {
    MappedStatement mappedStatement = conf.getMappedStatementMap().get(statement);
    return executor.query(mappedStatement,parameter);
}

@Override
public <T> T getMapper(Class<T> type) {
    MapperProxy mapperProxy = new MapperProxy(this);
    return (T) Proxy.newProxyInstance(type.getClassLoader(),new Class[]{type},mapperProxy);
}
}


public class MappedStatement {

private String namespace; // 命名空间

private String sourceId;//方法名

private String resultType;//返回类型

private String sql;//sql 语句


public String getNamespace() {
    return namespace;
}

public void setNamespace(String namespace) {
    this.namespace = namespace;
}

public String getSourceId() {
    return sourceId;
}

public void setSourceId(String sourceId) {
    this.sourceId = sourceId;
}

public String getResultType() {
    return resultType;
}

public void setResultType(String resultType) {
    this.resultType = resultType;
}

public String getSql() {
    return sql;
}

public void setSql(String sql) {
    this.sql = sql;
}
}



public class Configuration {

private String jdbcDriver;

private String jdbcUrl;

private String jdbcUsername;

private String jdbcPassword;

//存放sql 类型
private Map<String,MappedStatement> mappedStatementMap=new HashMap<>();

public String getJdbcDriver() {
    return jdbcDriver;
}

public void setJdbcDriver(String jdbcDriver) {
    this.jdbcDriver = jdbcDriver;
}

public String getJdbcUrl() {
    return jdbcUrl;
}

public void setJdbcUrl(String jdbcUrl) {
    this.jdbcUrl = jdbcUrl;
}

public String getJdbcUsername() {
    return jdbcUsername;
}

public void setJdbcUsername(String jdbcUsername) {
    this.jdbcUsername = jdbcUsername;
}

public String getJdbcPassword() {
    return jdbcPassword;
}

public void setJdbcPassword(String jdbcPassword) {
    this.jdbcPassword = jdbcPassword;
}

public Map<String, MappedStatement> getMappedStatementMap() {
    return mappedStatementMap;
}

public void setMappedStatementMap(Map<String, MappedStatement> mappedStatementMap) {
    this.mappedStatementMap = mappedStatementMap;
}
}

动态代理mapper
	
	public class MapperProxy implements InvocationHandler {

private SqlSession sqlSession;

public MapperProxy(SqlSession sqlSession) {
    this.sqlSession = sqlSession;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Class<?> returnType = method.getReturnType();
    if (Collection.class.isAssignableFrom(returnType)){
        return sqlSession.selectList(method.getDeclaringClass().getName()+"."+method.getName(),args==null?null:args[0]);
    }else {
        return sqlSession.selectOne(method.getDeclaringClass().getName()+"."+method.getName(),args==null?null:args[0]);
    }
}
}




定时操作数据库的主体类
public interface Executor {

/**
 *查询
 * @param ms 封装sql语句的mappedStatement
 * @param parameter 查询参数
 * @param <E>
 * @return
 */
<E> List<E> query(MappedStatement ms,Object parameter);
}

public class DefaultExecutor implements Executor {

private final Configuration conf;

public DefaultExecutor(Configuration conf) {
    this.conf = conf;
}

/**
 *
 * @param ms 封装sql语句的mappedStatement
 * @param parameter 查询参数
 * @param <E>
 * @return
 */
@Override
public <E> List<E> query(MappedStatement ms, Object parameter) {
    System.out.println("执行sql"+ms.getSql());
    ArrayList<E> ret = new ArrayList<>();
    try {
        //1.加载驱动
        Class.forName(conf.getJdbcDriver());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;
    try {
        //2.连接数据库
        connection = DriverManager.getConnection(conf.getJdbcUrl(), conf.getJdbcUsername(), conf.getJdbcPassword());
        //3.预加载sql
        preparedStatement=connection.prepareStatement(ms.getSql());
        parameterize(preparedStatement,parameter);
        //4.执行sql
        resultSet = preparedStatement.executeQuery();
        //5.映射结果集
        handlerResultSet(resultSet,ret,ms.getResultType());
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            resultSet.close();
            preparedStatement.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    return ret;
}

/**
 * 映射结果集
 * @param resultSet
 * @param ret
 * @param resultType
 * @param <E>
 */
private <E> void handlerResultSet(ResultSet resultSet, ArrayList<E> ret, String resultType) {
    Class<E> eClass=null;
    try {
        eClass= (Class<E>) Class.forName(resultType);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    try {
        while (resultSet.next()){
            Object entity = eClass.newInstance();
            ReflectionUtil.setPropToBeanFromResultSet(entity,resultSet);
            ret.add((E) entity);
        }
    }catch (Exception e){
        e.printStackTrace();
    }

}

/**
 * 处理sql
 * @param preparedStatement
 * @param parameter
 */
private void parameterize(PreparedStatement preparedStatement, Object parameter) throws SQLException {
    if (parameter instanceof Integer){
        preparedStatement.setInt(1, (Integer) parameter);
    }else if (parameter instanceof Long){
        preparedStatement.setLong(1, (Long) parameter);
    }else if (parameter instanceof String){
        preparedStatement.setString(1, (String) parameter);
    }
}
}
	
	反射解析查询结果
		
		public class ReflectionUtil {

/**
 * 为指定bean 的propName属性赋值为value
 * @param bean 目标对象
 * @param propName 对象属性名
 * @param value 值
 */
public static void setPropToBean(Object bean,String propName,Object value){
    Field f;
    try {
       f= bean.getClass().getDeclaredField(propName); //获取对象指定属性
       f.setAccessible(true); //将对象设置为可通过反射进行访问
       f.set(bean,value);//为属性赋值
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

/**
 * 从result 中读取一行数据 并填充的实体bean
 * @param entity
 * @param resultSet
 */
public static void setPropToBeanFromResultSet(Object entity, ResultSet resultSet) throws SQLException {
    Field[] declaredFields = entity.getClass().getDeclaredFields();//通过反射获取对象的所有字段
    for (int i = 0; i < declaredFields.length; i++) {
        if (declaredFields[i].getType().getSimpleName().equals("String")){
            setPropToBean(entity,declaredFields[i].getName(),resultSet.getString(declaredFields[i].getName()));
        }else if (declaredFields[i].getType().getSimpleName().equals("Integer")){
            setPropToBean(entity,declaredFields[i].getName(),resultSet.getInt(declaredFields[i].getName()));
        }else if (declaredFields[i].getType().getSimpleName().equals("Long")){
            setPropToBean(entity,declaredFields[i].getName(),resultSet.getLong(declaredFields[i].getName()));
        }
    }
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值