public class User {
private Integer id;
private String username;
private String password;
private String birthday;
...get/set
}
1.4.4 读取解析封装
Resource
读取:Resource获取配置文件流
package com.topxin.io;
import java.io.InputStream;
public class Resource {
//根据配置文件的路径,将配置文件加载成字节输入流,存储在内存中
public static InputStream getResourceAsSteam(String path){
InputStream resourceAsStream = Resource.class.getClassLoader().getResourceAsStream(path);
return resourceAsStream;
}
}
XMlConfigBuilder
解析:将SqlMapperConfig.xml配置文件通过dom4j解析
封装:Configuration对象
注意:Configuration对象同时封装MapperStatement
package com.topxin.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.topxin.io.Resource;
import com.topxin.pojo.Configuration;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.beans.PropertyVetoException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;
public class XMlConfigBuilder {
private Configuration configuration;
public XMlConfigBuilder() {
this.configuration = new Configuration();
}
/**
* 该方法即使将配置文件进行解析,封装Configuration
* @return
*/
public Configuration parseConfig(InputStream inputStream) throws PropertyVetoException, DocumentException {
Document document = new SAXReader().read(inputStream);
//configuration
Element rootElement = document.getRootElement();
Properties properties = new Properties();
List list = rootElement.selectNodes("//property");
for (Element element : list) {
String name = element.attributeValue("name");
String value = element.attributeValue("value");
properties.setProperty(name,value);
}
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setDriverClass(properties.getProperty("driverClass"));
comboPooledDataSource.setJdbcUrl(properties.getProperty("jdbcUrl"));
comboPooledDataSource.setUser(properties.getProperty("username"));
comboPooledDataSource.setPassword(properties.getProperty("password"));
configuration.setDataSource(comboPooledDataSource);
//mapper.xml解析,拿到路径,根据路径---字节输入六---dom4j解析
List mapperList = rootElement.selectNodes("//mapper");
for (Element element : mapperList) {
String mapperPath = element.attributeValue("resource");
InputStream resourceAsSteam = Resource.getResourceAsSteam(mapperPath);
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);
xmlMapperBuilder.parse(resourceAsSteam);
}
return configuration;
}
}
XMLMapperBuilder
解析:将UserMapper.xml配置文件通过dom4j解析
封装:MapperStatement对象
注意:根据 statementId的key = namespace +"."+ id
package com.topxin.config;
import com.topxin.pojo.Configuration;
import com.topxin.pojo.MapperStatement;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.List;
public class XMLMapperBuilder {
private Configuration configuration;
public XMLMapperBuilder(Configuration configuration) {
this.configuration = configuration;
}
public void parse(InputStream inputStream) throws DocumentException {
Document document = new SAXReader().read(inputStream);
Element rootElement = document.getRootElement();
String namespace = rootElement.attributeValue("namespace");
List list = rootElement.selectNodes("//select");
for (Element element : list) {
String id = element.attributeValue("id");
String resultType = element.attributeValue("resultType");
String paramterType = element.attributeValue("parameterType");
String sqlText = element.getTextTrim();
MapperStatement mapperStatement = new MapperStatement();
mapperStatement.setId(id);
mapperStatement.setResultType(resultType);
mapperStatement.setParameterType(paramterType);
mapperStatement.setSql(sqlText);
String key = namespace +"."+ id;
configuration.getMapperStatementMap().put(key,mapperStatement);
}
}
}
1.4.5 SqlSessionFactory
核心方法openSession()
SqlSessionFactoryBuilder
package com.topxin.sqlSession;
import com.topxin.config.XMlConfigBuilder;
import com.topxin.pojo.Configuration;
import org.dom4j.DocumentException;
import java.beans.PropertyVetoException;
import java.io.InputStream;
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(InputStream in) throws PropertyVetoException, DocumentException {
//第一:使用dom4j解析配置文件,将解析出来的内容防撞到Configuration中
XMlConfigBuilder xMlConfigBuilder = new XMlConfigBuilder();
Configuration configuration = xMlConfigBuilder.parseConfig(in);
//第二:创建sqlSessionFactory对象,工厂类,生产sqlSession会话对象
DefaultSqlSessionFactory defaultSqlSessionFactory = new DefaultSqlSessionFactory(configuration);
return defaultSqlSessionFactory;
}
}
SqlSessionFactory接口
package com.topxin.sqlSession;
public interface SqlSessionFactory {
public SqlSession openSession();
}
SqlSessionFactory接口的实现类DefaultSqlSessionFactory
package com.topxin.sqlSession;
import com.topxin.pojo.Configuration;
public class DefaultSqlSessionFactory implements SqlSessionFactory{
private Configuration configuration;
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
@Override
public DefaultSqlSession openSession() {
return new DefaultSqlSession(configuration);
}
}
1.4.6 SqlSession
invoke()方法
SqlSession接口
package com.topxin.sqlSession;
import java.util.List;
public interface SqlSession {
//查询所有
public List selectList(String statementId,Object... params) throws Exception;
//根据条件查询单个
public T selectOne(String statementId,Object... params) throws Exception;
//为Dao接口生产代理实现类
public T getMapper(Class> mapperClass);
}
SqlSession接口的实现类
package com.topxin.sqlSession;
import com.topxin.pojo.Configuration;
import com.topxin.pojo.MapperStatement;
import java.lang.reflect.*;
import java.util.List;
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里的query方法调用
SimpleExecutor simpleExecutor = new SimpleExecutor();
MapperStatement mapperStatement = configuration.getMapperStatementMap().get(statementId);
List
1.4.7 Executor
Executor接口
package com.topxin.sqlSession;
import com.topxin.pojo.Configuration;
import com.topxin.pojo.MapperStatement;
import java.sql.SQLException;
import java.util.List;
public interface Executor {
public List query(Configuration configuration, MapperStatement mapperStatement, Object... params) throws SQLException, Exception;
}
BoundSql封装解析后的Sql语句
package com.topxin.sqlSession;
import com.topxin.utils.ParameterMapping;
import java.util.ArrayList;
import java.util.List;
public class BoundSql {
private String sqlText; //解析过后的sql
private List parameterMappings = new ArrayList<>();
public BoundSql(String sqlText, List parameterMappings) {
this.sqlText = sqlText;
this.parameterMappings = parameterMappings;
}
public String getSqlText() {
return sqlText;
}
public void setSqlText(String sqlText) {
this.sqlText = sqlText;
}
public List getParameterMappings() {
return parameterMappings;
}
public void setParameterMappings(List parameterMappings) {
this.parameterMappings = parameterMappings;
}
}
/**
* Copyright 2009-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.topxin.utils;
/**
* @author Clinton Begin
*/
public class GenericTokenParser {
private final String openToken; //开始标记
private final String closeToken; //结束标记
private final TokenHandler handler; //标记处理器
public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
this.openToken = openToken;
this.closeToken = closeToken;
this.handler = handler;
}
/**
* 解析${}和#{}
* @param text
* @return
* 该方法主要实现了配置文件、脚本等片段中占位符的解析、处理工作,并返回最终需要的数据。
* 其中,解析工作由该方法完成,处理工作是由处理器handler的handleToken()方法来实现
*/
public String parse(String text) {
// 验证参数问题,如果是null,就返回空字符串。
if (text == null || text.isEmpty()) {
return "";
}
// 下面继续验证是否包含开始标签,如果不包含,默认不是占位符,直接原样返回即可,否则继续执行。
int start = text.indexOf(openToken, 0);
if (start == -1) {
return text;
}
// 把text转成字符数组src,并且定义默认偏移量offset=0、存储最终需要返回字符串的变量builder,
// text变量中占位符对应的变量名expression。判断start是否大于-1(即text中是否存在openToken),如果存在就执行下面代码
char[] src = text.toCharArray();
int offset = 0;
final StringBuilder builder = new StringBuilder();
StringBuilder expression = null;
while (start > -1) {
// 判断如果开始标记前如果有转义字符,就不作为openToken进行处理,否则继续处理
if (start > 0 && src[start - 1] == '\\') {
builder.append(src, offset, start - offset - 1).append(openToken);
offset = start + openToken.length();
} else {
//重置expression变量,避免空指针或者老数据干扰。
if (expression == null) {
expression = new StringBuilder();
} else {
expression.setLength(0);
}
builder.append(src, offset, start - offset);
offset = start + openToken.length();
int end = text.indexOf(closeToken, offset);
while (end > -1) {存在结束标记时
if (end > offset && src[end - 1] == '\\') {//如果结束标记前面有转义字符时
// this close token is escaped. remove the backslash and continue.
expression.append(src, offset, end - offset - 1).append(closeToken);
offset = end + closeToken.length();
end = text.indexOf(closeToken, offset);
} else {//不存在转义字符,即需要作为参数进行处理
expression.append(src, offset, end - offset);
offset = end + closeToken.length();
break;
}
}
if (end == -1) {
// close token was not found.
builder.append(src, start, src.length - start);
offset = src.length;
} else {
//首先根据参数的key(即expression)进行参数处理,返回?作为占位符
builder.append(handler.handleToken(expression.toString()));
offset = end + closeToken.length();
}
}
start = text.indexOf(openToken, offset);
}
if (offset < src.length) {
builder.append(src, offset, src.length - offset);
}
return builder.toString();
}
}
ParameterMapping分装Mybaitis中Sql语句的${}和#{}的内容
package com.topxin.utils;
public class ParameterMapping {
private String content;
public ParameterMapping(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
TokenHandler接口
/**
* Copyright 2009-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.topxin.utils;
/**
* @author Clinton Begin
*/
public interface TokenHandler {
String handleToken(String content);
}
ParameterMappingTokenHandler类
package com.topxin.utils;
import java.util.ArrayList;
import java.util.List;
public class ParameterMappingTokenHandler implements TokenHandler {
private List parameterMappings = new ArrayList();
// context是参数名称 #{id} #{username}
public String handleToken(String content) {
parameterMappings.add(buildParameterMapping(content));
return "?";
}
private ParameterMapping buildParameterMapping(String content) {
ParameterMapping parameterMapping = new ParameterMapping(content);
return parameterMapping;
}
public List getParameterMappings() {
return parameterMappings;
}
public void setParameterMappings(List parameterMappings) {
this.parameterMappings = parameterMappings;
}
}
1.4.9 Test测试
package com.topxin.test;
import com.topxin.dao.IUserDao;
import com.topxin.io.Resource;
import com.topxin.pojo.User;
import com.topxin.sqlSession.SqlSession;
import com.topxin.sqlSession.SqlSessionFactory;
import com.topxin.sqlSession.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class IPersistenceTest {
@Test
public void test() throws Exception {
InputStream resourceAsSteam = Resource.getResourceAsSteam("sqlMapperConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam);
SqlSession sqlSession = sqlSessionFactory.openSession();
//调用
User user = new User();
user.setId(1);
user.setUsername("lucy");
/* User u = sqlSession.selectOne("user.selectOne", user);
System.out.println(u);*/
/*List users = sqlSession.selectList("user.selectList");
for (User u : users) {
System.out.println(u);
}*/
//返回的userDao是代理对象proxy
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
/*User byCondition = userDao.findByCondition(user);
System.out.println(byCondition);*/
List all = userDao.findAll();
for (User user1 : all) {
System.out.println(user1);
}
}
}
T selectOne(String statement, Object parameter)
List selectList(String statement, Object parameter)
int insert(String statement, Object parameter)
int update(String statement, Object parameter)
int delete(String statement, Object parameter)
public class PerpetualCache implements Cache {
private final String id;
private MapcObject, Object> cache = new HashMapC);
public PerpetualCache(St ring id) {this.id = id;}
}
我们可以看到二级缓存底层还是HashMap结构
public class User implements Serializable(
//用户ID private int id;
//用户姓名 private String username;
//用户性别 private String sex;
}
package com.topxin.constructor;
public class ComputerBuilder {
private Computer computer = new Computer();
public void installDisPlayer(String disPlayer){
computer.setDisPlayer(disPlayer);
}
public void installMainUnit(String mainUnit){
computer.setMainUnit(mainUnit);
}
public void installKeyboard(String keyboard){
computer.setKeyboard(keyboard);
}
public void installMouse(String mouse){
computer.setMouse(mouse);
}
public Computer getComputer(){
return computer;
}
}
测试
package com.topxin.constructor;
public class ConstructorTest {
public static void main(String[]args){
ComputerBuilder computerBuilder = new ComputerBuilder();
computerBuilder.installDisPlayer("显万器");
computerBuilder.installMainUnit("主机");
computerBuilder.installKeyboard("键盘");
computerBuilder.installMouse("鼠标");
Computer computer = computerBuilder.getComputer();
System.out.println(computer);
}
}
10.5.2 工厂模式
简单工厂类:可以根据参数的不同返回不同类的实例
构架抽象类
package com.topxin.simpleFactory;
public abstract class Computer {
public abstract void start();
}
新建惠普类
package com.topxin.simpleFactory;
public class HpComputer extends Computer {
@Override
public void start() {
System.out.println("hp");
}
}
理想类
package com.topxin.simpleFactory;
public class LenovoComputer extends Computer {
@Override
public void start() {
System.out.println("lenovo");
}
}
工厂类
package com.topxin.simpleFactory;
public class ComputerFactory {
public static Computer createComputer(String type){
Computer computer = null;
switch (type){
case "lenovo":
computer = new LenovoComputer();
case "hp":
computer = new HpComputer();
}
return computer;
}
}
测试
通过工厂类createComputer可以创建不同类型的类
package com.topxin.simpleFactory;
public class SimpleFactoryTest {
public static void main(String[] args) {
Computer hp = ComputerFactory.createComputer("hp");
hp.start();
}
}
10.5.3 代理模式
Mybatis核心使用
接口
package com.topxin.dynamicprocy;
public interface Person {
void doSomething();
}
具体实现类
package com.topxin.dynamicprocy;
public class Bob implements Person{
@Override
public void doSomething() {
System.out.println("Bob doSomeThing");
}
}
package com.topxin.dynamicprocy;
public class ProxyTest {
public static void main(String[] args) {
Person person = new Bob();
person.doSomething();
Person proxy = (Person) new JDKDynamicProxy(new Bob()).getTarget();
proxy.doSomething();
}
}
public class Server
{
//用来存储所有连接上来的客户
private List<ServerThread> clients;
public static void main(String[] args)
{
Server s = new Server();
s.startServer(9988);
}
publi
I got serveral questions about auto.offset.reset. This configuration parameter governs how consumer read the message from Kafka when there is no initial offset in ZooKeeper or
two cursors.
Make the first cursor go K steps first.
/*
* 第 13 题:题目:输入一个单向链表,输出该链表中倒数第 k 个节点
*/
public void displayKthItemsBackWard(ListNode head,int k){
ListNode p1=head,p2=head;
一、sh 脚本不执行的原因
sh脚本不执行的原因 只有2个
1.权限不够
2.sh脚本里路径没写完整。
二、解决You have new mail in /var/spool/mail/root
修改/usr/share/logwatch/default.conf/logwatch.conf配置文件
MailTo =
MailFrom
三、查询连接数
$ git push joe prod-2295-1
To [email protected]:joe.le/dr-frontend.git
! [rejected] prod-2295-1 -> prod-2295-1 (non-fast-forward)
error: failed to push some refs to '[email protected]