手撸MyBatis(二)模拟实现,最新Java笔试题分享

测试:

@Test

public void testParse(){

ConfigParser parser = new ConfigParser();

try {

parser.parseConfig(Test2.class.getClassLoader().getResourceAsStream(“mock-config.xml”));

System.out.println(parser.getDataSource());

System.out.println(parser.getClassMappers());

System.out.println(parser.getResourceMappers());

} catch (DocumentException e) {

e.printStackTrace();

}

}

编写一个类,保存Mapper方法相关的信息

/**

  • SQL映射类

*/

public class Mapper {

//sql类型 insert update delete select

private String sqlType;

//Mapper方法名

private String methodName;

//sql语句

private String sql;

//参数类型

private String paramType;

//返回类型

private String returnType;

}

定义一个解析类,完成对映射文件的解析工作:

/**

映射文件的解析类

*/

public class MapperParser {

private Map<String,Mapper> mappers = new HashMap<>();

public void parseMappers(InputStream inputStream) throws DocumentException {

SAXReader reader = new SAXReader();

reader.setEntityResolver(new EntityResolver() {

@Override

public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {

return new InputSource(new ByteArrayInputStream(“”.getBytes()));

}

});

Document doc = reader.read(inputStream);

Element root = doc.getRootElement();

List elements = root.elements();

String namespace = root.attributeValue(“namespace”);

for(Element e : elements){

Mapper mapper = new Mapper();

mapper.setSqlType(e.getName());

mapper.setMethodName(e.attributeValue(“id”));

mapper.setParamType(e.attributeValue(“parameterType”));

mapper.setReturnType(e.attributeValue(“resultType”));

mapper.setSql(e.getText());

mappers.put(namespace+“.”+e.attributeValue(“id”),mapper);

}

}

public Map<String, Mapper> getMappers() {

return mappers;

}

}

测试:

@Test

public void testParse(){

ConfigParser parser = new ConfigParser();

MapperParser mParser = new MapperParser();

try {

parser.parseConfig(Test2.class.getClassLoader().getResourceAsStream(“mock-config.xml”));

System.out.println(parser.getDataSource());

System.out.println(parser.getClassMappers());

System.out.println(parser.getResourceMappers());

for(String resource : parser.getResourceMappers()){

System.out.println(“resourc:”+resource);

mParser.parseMappers(Test2.class.getClassLoader().getResourceAsStream(resource));

System.out.println(mParser.getMappers());

}

} catch (DocumentException e) {

e.printStackTrace();

}

}

编写模拟SQLSession的类,通过动态代理获得Mapper对象

/**

  • 模拟SqlSession

*/

public interface MySqlSession {

/**

  • 返回Mapper对象

  • @param clazz

  • @param

  • @return

*/

T getMapper(Class clazz);

}

public class MySqlSessionImpl implements MySqlSession {

private Map<String,String> dataSource;

private Map<String,Mapper> mappers;

public MySqlSessionImpl(Map<String, String> dataSource, Map<String, Mapper> mappers) {

this.dataSource = dataSource;

this.mappers = mappers;

}

@Override

public T getMapper(Class clazz) {

XMLMapperProxy xmlMapperProxy = new XMLMapperProxy(dataSource,mappers,clazz);

return (T) xmlMapperProxy.getProxy();

}

}

动态代理的实现类

/**

  • XML映射文件的代理

*/

public class XMLMapperProxy implements InvocationHandler{

private Map<String,String> dataSource;

private Map<String,Mapper> mappers;

private Class<?> clazz;

private Connection connection;

public XMLMapperProxy(Map<String, String> dataSource, Map<String,Mapper> mappers,Class clazz) {

this.dataSource = dataSource;

this.mappers = mappers;

this.clazz = clazz;

initDatasource(dataSource);

}

/**

  • 获得代理对象

  • @return

*/

public Object getProxy(){

return Proxy.newProxyInstance(this.getClass().getClassLoader(),new Class[]{clazz},this);

}

/**

  • 执行代理方法

  • @return

*/

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

String key = clazz.getName() + “.” + method.getName();

//通过类名取到Mapper对象

Mapper mapper = mappers.get(key);

System.out.println(“mapper—>”+mapper);

if(mapper == null){

System.out.println(key+“,has no mapper.”);

return null;

}

//获得PreparedStatement 对象执行sql

PreparedStatement psmt = connection.prepareStatement(mapper.getSql());

Object result = null;

//判断是否查询命令

if(“select”.equals(mapper.getSqlType())){

//获得查询结果

ResultSet rs = psmt.executeQuery();

List columns = new ArrayList<>();

int count = rs.getMetaData().getColumnCount();

for(int i = 1;i <= count;i++){

columns.add(rs.getMetaData().getColumnName(i));

}

List selectRs = new ArrayList();

//通过反射读取属性名,通过set方法给每个属性赋值

while(rs.next()){

Class<?> poClazz = Class.forName(mapper.getReturnType());

Object po = poClazz.newInstance();

for(String colName : columns){

for(Method med : poClazz.getMethods()){

if(med.getName().equalsIgnoreCase(“set”+colName)){

try{

med.invoke(po,rs.getString(colName));

}catch (IllegalArgumentException ex) {

med.invoke(po, rs.getInt(colName));

}

}

}

}

selectRs.add(po);

}

result = selectRs;

}else{

result = psmt.executeUpdate();

}

connection.close();

return result;

}

/**

  • 初始化数据源

  • @return

*/

private void initDatasource(Map<String,String> dataSource){

try {

Class.forName(dataSource.get(“driver”));

connection = DriverManager.getConnection(dataSource.get(“url”),dataSource.get(“username”),dataSource.get(“password”));

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后

总而言之,面试官问来问去,问的那些Redis知识点也就这么多吧,复习的不够到位,知识点掌握不够熟练,所以面试才会卡壳。将这些Redis面试知识解析以及我整理的一些学习笔记分享出来给大家参考学习

还有更多学习笔记面试资料也分享如下:

都是“Redis惹的祸”,害我差点挂在美团三面,真是“虚惊一场”

助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-cD2ozhTP-1710757884147)]
[外链图片转存中…(img-3wfjJ5gh-1710757884148)]
[外链图片转存中…(img-HJGkFIov-1710757884149)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-Qwh1aqtE-1710757884149)]

最后

总而言之,面试官问来问去,问的那些Redis知识点也就这么多吧,复习的不够到位,知识点掌握不够熟练,所以面试才会卡壳。将这些Redis面试知识解析以及我整理的一些学习笔记分享出来给大家参考学习

还有更多学习笔记面试资料也分享如下:

[外链图片转存中…(img-HZALOGua-1710757884150)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值