public class SqlSessionFactoryBuild {
/**
* 解析配置文件,创建 SqlSession
*/
public SqlSessionFactory build(InputStream in) throws DocumentException, PropertyVetoException {
// 1、使用dom4j解析配置文件,将解析出来的内容封装到 Configuration 中
XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder();
Configuration configuration = xmlConfigBuilder.parseConfig(in);
// 2、创建SqlFactory对象
DefaultSqlSessionFactory defaultSqlSessionFactory = new DefaultSqlSessionFactory(configuration);
return defaultSqlSessionFactory;
}
}
定义对数据库的CRUD操作
public class DefaultSqlSession implements SqlSession {
private Configuration configuration;
public DefaultSqlSession(Configuration configuration) {
this.configuration = configuration;
}
@Override
public List selectList(String statementId, Object... params) throws Exception {
SimpleExecutor simpleExecutor = new SimpleExecutor(configuration);
MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
List
在SimpleExecutor 中编写JDBC代码
public class SimpleExecutor implements Executor {
private Configuration configuration;
public SimpleExecutor(Configuration configuration) {
this.configuration = configuration;
}
@Override
public List query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {
// 1、注册驱动,获取数据库连接
Connection connection = configuration.getDataSource().getConnection();
/*
* 2、获取sql语句 : select * from user where id = #{id} and username = #{username}
* 转换sql语句: select * from user where id = ? and username = ? ,转换的过程中,还需要对#{}里面的值进行解析存储
*/
String sql = mappedStatement.getSql();
BoundSql boundSql = getBoundSql(sql);
// 3、获取预处理对象 preparedStatement
PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSql());
// 4、设置参数
String parameterType = mappedStatement.getParameterType();
Class> parameterTypeClass = getClassType(parameterType);
List parameterMappingList = boundSql.getParameterMappingList();
for (int i = 0; i < parameterMappingList.size(); i++) {
ParameterMapping parameterMapping = parameterMappingList.get(i);
String content = parameterMapping.getContent();
Field declaredField = parameterTypeClass.getDeclaredField(content);
declaredField.setAccessible(true);
Object o = declaredField.get(params[0]);
preparedStatement.setObject(i + 1, o);
}
// 5. 执行sql
ResultSet resultSet = preparedStatement.executeQuery();
String resultType = mappedStatement.getResultType();
Class> resultTypeClass = getClassType(resultType);
ArrayList objects = new ArrayList<>();
// 6. 封装返回结果集
while (resultSet.next()) {
Object o = resultTypeClass.getDeclaredConstructor().newInstance();
ResultSetMetaData metaData = resultSet.getMetaData();
for (int i = 1; i <= metaData.getColumnCount(); i++) {
String columnName = metaData.getColumnName(i);
Object value = resultSet.getObject(columnName);
//使用内省,根据数据库表和实体的对应关系,完成封装
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
Method writeMethod = propertyDescriptor.getWriteMethod();
writeMethod.invoke(o, value);
}
objects.add(o);
}
return (List) objects;
}
/**
* 完成对#{}的解析工作:1.将#{}使用?进行代替,2.解析出#{}里面的值进行存储
* 具体工具类都是从 Mybatis 中直接拿来使用的
*/
private BoundSql getBoundSql(String sql) {
// 标记处理类:配置标记解析器来完成对占位符的解析处理工作
ParameterMappingTokenHandler parameterMappingTokenHandler = new ParameterMappingTokenHandler();
GenericTokenParser genericTokenParser = new GenericTokenParser("#{", "}", parameterMappingTokenHandler);
// 解析出来的sql
String parseSql = genericTokenParser.parse(sql);
// #{}里面解析出来的参数名称
List parameterMappings = parameterMappingTokenHandler.getParameterMappings();
BoundSql boundSql = new BoundSql(parseSql, parameterMappings);
return boundSql;
}
private Class> getClassType(String type) throws ClassNotFoundException {
if (type != null) {
Class> aClass = Class.forName(type);
return aClass;
}
return null;
}
}
使用端编写测试类
package com.wujun.test;
import com.alibaba.fastjson.JSON;
import com.wujun.io.Resources;
import com.wujun.pojo.User;
import com.wujun.sqlSession.SqlSession;
import com.wujun.sqlSession.SqlSessionFactory;
import com.wujun.sqlSession.SqlSessionFactoryBuild;
import org.junit.Test;
import java.io.InputStream;
public class IPersistenceTest {
@Test
public void test() throws Exception {
InputStream resourceAsSteam = Resources.getResourceAsSteam("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuild().build(resourceAsSteam);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(1L);
user.setUsername("吴俊1");
User sqlResult = sqlSession.selectOne("com.wujun.dao.IUserDao.findByCondition", user);
System.out.println(JSON.toJSONString(sqlResult));
}
}
测试返回结果
Connected to the target VM, address: '127.0.0.1:60755', transport: 'socket'
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.dom4j.io.SAXContentHandler (file:/D:/repository/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar) to method com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$LocatorProxy.getEncoding()
WARNING: Please consider reporting this to the maintainers of org.dom4j.io.SAXContentHandler
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
log4j:WARN No appenders could be found for logger (com.mchange.v2.log.MLog).
log4j:WARN Please initialize the log4j system properly.
{"id":1,"username":"吴俊1"}
Disconnected from the target VM, address: '127.0.0.1:60755', transport: 'socket'
Process finished with exit code 0
原题链接:#136 Single Number
要求:
给定一个整型数组,其中除了一个元素之外,每个元素都出现两次。找出这个元素
注意:算法的时间复杂度应为O(n),最好不使用额外的内存空间
难度:中等
分析:
题目限定了线性的时间复杂度,同时不使用额外的空间,即要求只遍历数组一遍得出结果。由于异或运算 n XOR n = 0, n XOR 0 = n,故将数组中的每个元素进
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2281)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:
Velocity出现的目的用于简化基于MVC的web应用开发,用于替代JSP标签技术,那么Velocity如何访问Java代码.本篇继续以Velocity三http://bit1129.iteye.com/blog/2106142中的例子为基础,
POJO
package com.tom.servlets;
public
今天看org.jboss.netty.example.http.file.HttpStaticFileServerHandler.java
可以直接往channel里面写入一个FileRegion对象,而不需要相应的encoder:
//pipeline(没有诸如“FileRegionEncoder”的handler):
public ChannelPipeline ge
Zero Clipboard的实现原理
Zero Clipboard 利用透明的Flash让其漂浮在复制按钮之上,这样其实点击的不是按钮而是 Flash ,这样将需要的内容传入Flash,再通过Flash的复制功能把传入的内容复制到剪贴板。
Zero Clipboard的安装方法
首先需要下载 Zero Clipboard的压缩包,解压后把文件夹中两个文件:ZeroClipboard.js
4.1 @Order
Spring 4.2 利用@Order控制配置类的加载顺序
4.2 演示
两个演示bean
package com.wisely.spring4_2.order;
public class Demo1Service {
}
package com.wisely.spring4_2.order;
public class