XMLの最も基本的な構成
xml情報を読み取るコード
はSqlMapConfig.xmlのマッパー//マッパーに記述されているため、リソースマッピング
AccountByIdDao.xml のみが戻り値型の完全修飾クラス名を持つ必要があります
基本的なテスト手順:
public class Self_defindedTest {
public static void main(String[] args) throws Exception{
InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);//多态,继承接口SqlSessionFactory
SqlSession session = factory.openSession();//多态,继承接口SqlSession
//注意,增删改方法需要提交事务,openSession()可添加true实现提交事务,此自定义并未实现
AccountByIdDao byIdDao = session.getMapper(AccountByIdDao.class);
List<Account> all = byIdDao.findAll();
for (Account account : all){
System.out.println(account);
}
session.close();
is.close();
}
}
入力パラメーターに基づいてバイト入力ストリームを取得する
InputStream is = Resources.getResourceAsStream(“ sqlMapConfig.xml”);
public class Resources {
public static InputStream getResourceAsStream(String filePath){
return Resources.class.getClassLoader().getResourceAsStream(filePath);
}
}
バイト入力ストリームに基づいてファクトリを構築する**
ここではXMLConfigBuilderコードは省略されています
SqlSessionFactoryファクトリ=新しいSqlSessionFactoryBuilder()。build(is);
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(InputStream is){
Configuration cfg = XMLConfigBuilder.loadConfiguration(is);
return new DefaultSqlSessionFactory(cfg);//到下一步环节
}
}
**読み取ったファイルの情報を表す構成**
構成cfg = XMLConfigBuilder.loadConfiguration(is);
public class Configuration {
private String driver;
private String url;
private String username;
private String password;
private Map<String,Mapper> mappers = new HashMap<String, Mapper>();
//此处省略get和set方法的构建
}
Mapperによってカプセル化されたSQLステートメントと結果タイプの完全修飾クラス名
Map <String、Mapper> mappers = new HashMap <String、Mapper>();
public class Mapper {
private String queryString;
private String resultType;
//略set,get
}
ファイル情報をプロキシクラスに渡して、新しいデータベースオブジェクトを作成します。
SqlSession session = factory.openSession(); //基本的な手順
新しいDefaultSqlSessionFactory(cfg);
public class DefaultSqlSessionFactory implements SqlSessionFactory{
private Configuration cfg;
public DefaultSqlSessionFactory(Configuration cfg) {
this.cfg = cfg;
}
@Override
public SqlSession openSession() {
return new DefaultSqlSession(cfg);//转到下一步环节
}
}
プロキシオブジェクトクラスを入力して拡張してください
AccountByIdDao byIdDao = session.getMapper(AccountByIdDao.class);
session.close(); //基础步骤新しいDefaultSqlSession(cfg);
public class DefaultSqlSession implements SqlSession{
private Configuration cfg;
private Connection connection;
public DefaultSqlSession(Configuration cfg) {
this.cfg = cfg;
connection = DataSourceUtil.getConnection(cfg);
}
@Override
public <T> T getMapper(Class<T> daoInterfaceClass) {
return (T)Proxy.newProxyInstance(daoInterfaceClass.getClassLoader(), new Class[]{daoInterfaceClass}, new MapperProxy(cfg.getMappers(),connection));
// **动态代理异常com.sun.proxy.$Proxy0 cannot be cast to**
/**
1.第二个参数Class.getInterfaces() 主要作用是获取某类所实现的接口所有接口,返回值Class<?>[] ,这里使用就是获取接口的接口,所以出错
2.代理类没有实现接口,而是实现了某一基类。
3.当你获得代理类对象的时候,就是强制转换的哪里,如果用子类强转,也会报错,只能用接口转换
*/
}
@Override
public void close() {
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
DataSourceUtil、データソースを作成するためのツールクラス
connection = DataSourceUtil.getConnection(cfg);
public class DataSourceUtil {
/**
* 用于获取一个连接
* @param cfg
* @return
*/
public static Connection getConnection(Configuration cfg){
try {
Class.forName(cfg.getDriver());
return DriverManager.getConnection(cfg.getUrl(), cfg.getUsername(), cfg.getPassword());
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
invocationHandlerインターフェースの実装メソッドを継承する
新しいMapperProxy(cfg.getMappers()、connection)
public class MapperProxy implements InvocationHandler {
private Map<String,Mapper> mappers;
private Connection conn;
public MapperProxy(Map<String, Mapper> mappers,Connection conn) {
this.conn = conn;
this.mappers=mappers;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取方法名
String methodName = method.getName();
//获取类名
String name = method.getDeclaringClass().getName();
//组合key
String key = name + "." +methodName;
//获取Mapper对象
Mapper mapper = mappers.get(key);
//判断是否有mapper
if(mapper == null){
throw new IllegalArgumentException("传入的参数有误");
}
//调用工具查询所有
return new Executor().selectList(mapper,conn);//已略工具类
}
}