SSH多个数据源动态数据切换

[TOC]

SSH多个数据源动态数据切换

一般情况下我们在spring配置中只配置一个dataSource来连接数据库,然后在SessionFactory中绑定dataSource。如果有需要连接多个数据库时的正确做法是:

enter description here

SSH框架的项目中我需要连接两个PostgreSQL数据库既可以手动切换,也可以使用aop来动态切换。

1. 配置文件

<!-- 自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<!--第一个数据源-->
<bean id="dataSourceJDJ" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close">
    <!-- oracle连接 <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/> 
        <property name="jdbcUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/> -->
    <property name="driverClass" value="org.postgresql.Driver" />
    <property name="jdbcUrl" value="jdbc:postgresql://127.0.0.1:5432/jdj" />
    <property name="user" value="postgres" />
    <property name="password" value="123456" />
    <property name="minPoolSize" value="5" />
    <property name="maxPoolSize" value="20" />
    <property name="initialPoolSize" value="10" />
    <property name="maxIdleTime" value="60" />
    <property name="acquireIncrement" value="5" />
    <property name="maxStatements" value="20" />
    <property name="idleConnectionTestPeriod" value="30" />
    <property name="acquireRetryAttempts" value="10" />
    <property name="breakAfterAcquireFailure" value="true" />
    <property name="testConnectionOnCheckout" value="true" />
</bean>

<!--第二个数据源-->
    <bean id="dataSourceSDE" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
    destroy-method="close">  
 <property name="driverClass" value="org.postgresql.Driver" />
    <property name="jdbcUrl" value="jdbc:postgresql://192.168.1.139:5432/sde" />
    <property name="user" value="postgres" />
    <property name="password" value="123456" />
    <property name="minPoolSize" value="5" />
    <property name="maxPoolSize" value="20" />
    <property name="initialPoolSize" value="10" />
    <property name="maxIdleTime" value="60" />
    <property name="acquireIncrement" value="5" />
    <property name="maxStatements" value="20" />
    <property name="idleConnectionTestPeriod" value="30" />
    <property name="acquireRetryAttempts" value="10" />
    <property name="breakAfterAcquireFailure" value="true" /> 
    <property name="testConnectionOnCheckout" value="true" />
</bean> 

<!--动态切换配置-->
<bean id="dynamicDataSource" class="com.lbs.core.DynamicDataSource">  
    <property name="targetDataSources">  
        <map key-type="java.lang.String">  
            <entry value-ref="dataSourceJDJ" key="dataSourceJDJ"></entry>  
            <entry value-ref="dataSourceSDE" key="dataSourceSDE"></entry>  
        </map>  
    </property>  
    <property name="defaultTargetDataSource" ref="dataSourceJDJ"></property>  
</bean> 

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dynamicDataSource" />
    </property>
    <property name="packagesToScan">
        <list>
            <value>com.lbs.model</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
</bean>

<!-- 注解的事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>  
    <aop:pointcut id="transactionPointCut" expression="execution(* com.lbs.service..*.*(..))" />  
    <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointCut" />  
</aop:config>  

<tx:advice id="txAdvice" transaction-manager="transactionManager">  
    <tx:attributes>  
        <tx:method name="add*" propagation="REQUIRED" />  
        <tx:method name="save*" propagation="REQUIRED" />  
        <tx:method name="update*" propagation="REQUIRED" />  
        <tx:method name="delete*" propagation="REQUIRED" />  
        <tx:method name="*" read-only="true" />  
    </tx:attributes>  
</tx:advice>  

<aop:config>  
    <aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor">  
        <aop:pointcut id="daoOne" expression="execution(* com.dao.one.*.*(..))" />  
        <aop:pointcut id="daoTwo" expression="execution(* com.dao.two.*.*(..))" />  
        <aop:before pointcut-ref="daoOne" method="setdataSourceOne" />  
        <aop:before pointcut-ref="daoTwo" method="setdataSourceTwo" />  
    </aop:aspect>  
</aop:config>  
  1. 注意事务拦截器的配置
    Spring的事务管理是与数据源绑定的,一旦程序执行到事务管理的那一层(如service)的话,由于在进入该层之前事务已经通过拦截器开启,因此在该层切换数据源是不行的,明白事务的原理是尤为重要的,我之前的文章中,将切换数据源的拦截器配置在了Dao层是有问题的。改为在service层进行配置拦截
  2. 注意数据库表的创建
    一些人喜欢用Hibernate的自动创建表的功能,但需要注意,在多数据源中,尤其是不同数据库的多数据源,想都自动建表是不行的。因为Hibernate自动建表是在项目启动时触发的,因此只会建立项目配置的默认数据源的表,而其他数据源的表则不会自动创建。大家要注意着点。
  3. Hibernate的数据库方言(dialect)可以忽略
    在多数据源时,方言的设置可以忽略,Hibernate在使用时会自动识别不同的数据库,因此不必纠结这个配置,甚至不配置也可以。

2. java文件

需要写以下三个.java文件来实现切换

enter description here

DatabaseContextHolder, 用来保存当前应该使用的数据源名称

package com.lbs.core;

public class DatabaseContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  
    public static void setCustomerType(String customerType) {  
        contextHolder.set(customerType);  
    }  
    public static String getCustomerType() {  
        return contextHolder.get();  
    }  
    public static void clearCustomerType() {  
        contextHolder.remove();  
    }  
}

AbstractRoutingDataSource实现类,实现数据源路由选择

package com.lbs.core;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource{

    @Override
    protected Object determineCurrentLookupKey() {
        // TODO 自动生成的方法存根
        return DatabaseContextHolder.getCustomerType(); 
    }
}

DataSourceInterceptor来进行切换

package com.lbs.core;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
//@Order(value=1)
//使用aop来自动切换数据源
public class DataSourceInterceptor {

     @Before("execution(* com.lbs.JDJDao.impl.*.*(..))")
    public void setdataSourceJDJ(JoinPoint jp) {
        DatabaseContextHolder.setCustomerType("dataSourceJDJ");
    }
     @Before("execution(* com.lbs.SDEDao.impl.*.*(..))")
    public void setdataSourceSDE(JoinPoint jp) {
        DatabaseContextHolder.setCustomerType("dataSourceSDE");
    }
}

或者不用aop @before来拦截,手动调用以下语句

DatabaseContextHolder.setCustomerType("dataSourceSDE");

hibernate

[TOC]

更新

hibernate使用update更新时一般情况下是对所有字段进行更新,如果只更新个别字段,则需要用id或者其他字段将对象先取出来再进行个别字段的更新。
对应字段加上如下注释时,则不进行更新

@Column(updatable=false)

若使用XML配置文件,可以配置dynamic-update,就可以动态更新,但在Annotation中没有此类方法

<class name=”com.sccin.entity.Student” table=”student” dynamic-update=”true”>

字段大小写问题

由于column中name若有大写(如goodNum),到数据库中都会被译成>
good_num,而相对数据库中来说字段不分大小写的,所以若数据库创建表
时,若字段名中有大写,些时在column的name属性中应全部改为小写.

反向工程创建问题

参考http://blog.knowsky.com/250382.htm

在使用myeclipse的hibernate的反向工程创建时出现点击没有反应的情况,解决方法是是找到工程目录下的.myhibernatedata文件,然后找到reSettingsFile=…那行,删除这一行即可,或者换一个工作空间建立web工程,加入hibernate,即可。
反向工程后若出现XXXId的类,则说明数据表没有主键

hibernate update

hibernate的主键也需要自己管理。特别是当用update的时候,主键为自增,若不进行管理,不对其赋所修改的值时会报如下错误。

1
org.hibernate.TransientObjectException: The given object has a null identifier:

出现如下错误,设置主键自动生成

1
org.hibernate.id.IdentifierGenerationException:ids for this class must be manually assigned before calling save():
1
2
3
4
5
6
@Id
@Column(name = "Id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getId() {
return this.id;
}

配置文件

注解方式( hibernate.cfg.xml文件中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>

<session-factory>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/lbsimage
</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="myeclipse.connection.profile">cc</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<!--如果使用JUnit进行测试:就要加上下面这句话-->
<property name="javax.persistence.validation.mode">none</property>
<!-- 实体配置类 注解方式-->
<mapping class="com.ssh.model.Student" />
<!--或者配置文件方式 如下 -->
<mapping resource="Teacher.hbm.xml" />
</session-factory>

</hibernate-configuration>

或者使用配置文件方式(Teacher.hbm.xml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="Teacher" table="teacher" catalog="learnssh">
<id name="tid" type="java.lang.Integer">
<column name="tid" />
<generator class="native" />
</id>
<property name="tname" type="java.lang.String">
<column name="tname" />
</property>
<property name="tage" type="java.lang.Integer">
<column name="tage" />
</property>
</class>
</hibernate-mapping>

与Spring结合时,这两种方法的applicationContext.xml文件的为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" xmlns:tx="http://www.springframework.org/schema/tx">

<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation"
value="classpath:hibernate.cfg.xml">
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</bean>
</beans>

Spring+hibernate结合方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!-- 用注解进行依赖注入 -->
<context:annotation-config></context:annotation-config>
<!-- 用注解让spring管理bean -->
<context:component-scan base-package="com.lbs" />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://192.168.1.106:3306/lbsimage" />
<property name="user" value="root" />
<property name="password" value="123456" />
<!--连接池中保留的最小连接数。 -->
<property name="minPoolSize" value="5" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="20" />
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="10" />
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="60" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="5" />
<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。 但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
<property name="maxStatements" value="20" />
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="30" />
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="10" />

<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。 但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
获取连接失败后该数据源将申明已断开并永久关闭。Default: false -->
<property name="breakAfterAcquireFailure" value="true" />

<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都将校验其有效性。 建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。Default: false -->
<property name="testConnectionOnCheckout" value="true" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="packagesToScan">
<list>
<value>com.lbs.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

Angularjs + Express3 + Bootstrap3

[TOC]

环境搭建

Angularjs + Express3 + Bootstrap3
angularjs是由Google团队开发的一款非常优秀web前端框架。Bootstrap让界面美观大方,对于不懂UE的人,也能做出专业级的水准。再结合Nodejs的Express做后端,三剑合并,太无敌了,大有统一前端开发的趋势,前途不可估量!

1. 首先安装node.js

2. webStorm(node.js最好的IDE开发工具)

3. express 安装

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

1
npm install express --save

以上命令会将 Express 框架安装在当前目录的 node_modules 目录中, node_modules 目录下会自动创建 express 目录。以下几个重要的模块是需要与 express 框架一起安装的:

  • body-parser - node.js 中间件,用于处理 JSON, Raw, Text 和 URL 编码的数据。
  • cookie-parser - 这就是一个解析Cookie的工具。通过req.cookies可以取到传过来的cookie,并把它们转成对象。
  • multer - node.js 中间件,用于处理enctype=”multipart/form-data”(设置表单的MIME编码)的表单数据。
$ cnpm install body-parser --save
$ cnpm install cookie-parser --save
$ cnpm install multer --save

安装成功后在node_modules下会找到express目录,同时也会找到.bin目录,它里面有express命令脚本,在终端下执行

1
express project_name

4. Bower安装

bower是一个客户端技术的软件包管理器,它可用于搜索、安装和卸载如JavaScript、HTML、CSS之类的网络资源。安装依赖:NodeJS、NPM、Git

Alt text

安装包是可使用

1
2
bower install <package>
bower install jquery

其中包的形式的可以是GitHub简写、一个git地址、一个url或者其他。

1
2
3
4
5
6
7
8
# registered package
$ bower install jquery
# GitHub shorthand
$ bower install desandro/masonry
# Git endpoint
$ bower install git://github.com/user/package.git
# URL
$ bower install http://example.com/script.js

如果安装成功,则目录中会出现bower_components子目录,其中包括了下载的jQuery源文件。

Alt text

卸载包可以使用uninstall 命令:

1
$ bower uninstall jquery

Q:安装bower时,报Bower : ENOGIT git is not installed or not in the PATH错误?

  1. windows中
    需要配置你的Git到path,假如你的git安装目录是”C:\Program Files (x86)\Git”,在path中加入git的bin和cmd目录,如C:\Program Files (x86)\Git\bin;C:\Program Files (x86)\Git\cmd
  2. Ubuntu 中
    1
    $ apt-get install git

5. angular、bootstrap安装

1
2
3
bower install angular
bower install angular-route
bower install bootstrap

web开发

Express + EJS + Mongoose/MySQL,通常用Nodejs做Web开发,需要这3个框架配合使用,就像Java中的SSH。

  • express 是轻量灵活的Nodejs Web应用框架
  • ejs是一个嵌入的Javascript模板引擎,通过编译生成HTML的代码。
  • mongoose 是MongoDB的对象模型工具,通过Mongoose框架,可以进行访问MongoDB的操作。

应用实例:

Web聊天室(IM):Express + Socket.io
  socket.io一个是基于Nodejs架构体系的,支持websocket的协议用于时时通信的一个软件包。socket.io 给跨浏览器构建实时应用提供了完整的封装,socket.io完全由javascript实现。


 

第一个web工程

  1. 新建工程

Alt text

创建成功后入下图所示:
Alt text
app.js:是项目的入口文件
node_modules/: 项目的依赖库。存放npm安装到本地依赖包,依赖包在package.json文件中声明,使用npm install指令安装。
package.json: npm依赖配置文件, 类似ruby中的Gemfile, java Maven中的pom.xml文件. 一会需要在这里添加 markdown-js 项目依赖。
public/: 存放静态资源文件, jquery/prettify.js等静态库会方这里,当然自己编写的前端代码也可以放这里
view/: 模板文件, express默认采用jade, 当然,你也可以使用自己喜欢的haml,JES, coffeeKup, jQueryTemplate等模板引擎
routes: 路由文件(学习的重要攻克对象。业务好不好,路由是关键)

  1. 目录结构
  • public 公共插件
  • routers 业务逻辑
  • views 页面展示

mongodb

[TOC]

1. mongodb创建

安装好后,新建文件夹和文件如下图所示:

enter description here

enter description here
mongo.log文件为空

enter description here

mongo.config文件内容如下:

enter description here

mongod --dbpath="mongodb安装目录\data" --logpath="mongodb安装目录\log\log.txt" --install --serviceName MongoDB --serviceDisplayName MongoDB

之后就可以在log.txt中看到

1
2
3
4
2015-10-23T14:51:17.374+0800 I CONTROL  [main] Hotfix KB2731284 or later update is not installed, will zero-out data files
2015-10-23T14:51:17.375+0800 I CONTROL [main] Trying to install Windows service 'MongoDB'
2015-10-23T14:51:17.641+0800 I CONTROL [main] Service 'MongoDB' (MongoDB) installed with command line '"C:\Program Files\MongoDB\Server\3.2\bin\mongod.exe" --dbpath=D:\mongodb\data\db --logpath=D:\mongodb\data\log\log.txt --service'
2015-10-23T14:51:17.641+0800 I CONTROL [main] Service can be started from the command line with 'net start MongoDB'

之后就可以在服务管理里面看到

enter description here
可以在此手动启动,也可以在命令行窗口net start MongoDB启动

enter description here
这样服务就启动了。

#关闭服务
net stop mongodb

2. 使用

cmd命令行里:
mongo //进入数据库
use hello-world //创建项目数据库
db.addUser("shuaige", "123456") //给这个数据库创建了一个叫帅哥的账号,密码123456 (但是我觉得可能我理解的不到位,你也可以不做这个操作)
然后,我们就为这个hello-world数据库创建collection(collection就相当于oracle和mysql里的table)
db.createCollection("users") //创建一个集合,也就是表
db.users.insert({userid: "admin", password: "123456"}) //给users里添加一个文档,也就是一条记录账号admin,密码123456
ok,现在检查一下:
db.users.find() //如果看到你刚刚添加的文档记录,就ok咯

在models目录下创建一个user.js,作为实体类映射数据库的users集合

var mongoose = require("mongoose");  //  顶会议用户组件
var Schema = mongoose.Schema;    //  创建模型
var userScheMa = new Schema({
    userid: String,
    password: String
}); //  定义了一个新的模型,但是此模式还未和users集合有关联
exports.user = mongoose.model('users', userScheMa); //  与users集合关联
  • 注意:还要使用npm下载 mongoose模块

重装报错:无法找到系统文件

这几天因为项目的需要,重新安装了一下mongodb数据库,遇到很多新问题,记录一下吧,以方便后来查找。
重新安装mongodb后发现启动服务报错,无法找到系统文件,后来发现是因为重新安装mongodb的目录变化,服务还是老的路径,所以无法打开,直接用一下命令卸载老旧的服务

mongod.exe --remove --serviceName "MongoDB"

如下图所示:

enter description here
然后运行一下命令,重新创建新的服务

mongod --config D:\mongodb\mongo.config --install --serviceName "MongoDB"

查看新服务属性:

enter description here
可以看出可执行文件的路径对了,服务至此可以正常启动了。

修改搜索引擎

在2015/3/17以前,MongoDB只有一个存储引擎,叫做MMAP,MongoDB3.0的推出使得MongoDB有了两个引擎:MMAPv1和WiredTiger。

  • MMAPv1:适应于所有MongoDB版本,MongoDB3.0的默认引擎
  • WiredTiger:仅支持64位MongoDB

    collection无法显示

    使用mongodb VUE 1.6.9.0可视化工具版本太低,对mongodb3.X支持度不好,网上有看到说是因为mongodb搜索引擎的问题,若使用MongoVUE这个工具,需要将存储引擎改成mmavp1,mongoVUE中collections为空,即文件树无法展开问题的解决策略,按照所说的方法没有成功朋友可以亲自尝试一下,下载使用最新的Romongo,mongodb的可视化工具,即可成功显示。

新手常用的git命令及问题分析

[TOC]

专有名词

  • Workspace:工作区
  • Index / Stage:暂存区
  • Repository:仓库区(或本地仓库)
  • Remote:远程仓库,指托管在网络上的项目仓库

.gitignore文件中列出要忽略的文件模式,例如:.class,忽略.class文件

image1

本地项目上传github

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 //设置用户
git config --global user.name
git config --global user.email
cd d:
mkdir bootstrap
cd bootstrap

git init //初始化版本仓库
touch READM //新建readme文件
echo "hello world!" >>README

git add . //将所有文件添加暂存区域
git reset file //取消已暂存文件
git commit -m 'first commit' //提交缓存,并添加描述‘first commit’
// 添加名字为origin的远程库,注意需提前建立好版本仓库,再次修改后提交跳过此命令
git remote add origin https://github.com/chen1218chen/bootstrap.git

git push origin master //提交到github仓库
git push //提交到local
git pull //抓取远程数据并自动合并
git fetch //抓取远程数据,需要手动合并

git clone <url> //自动将远程库归于origin下


git status //查看提交状态
git status -s //更为紧凑的格式输出
git status --short
git log -p -2//-p显示每次提交的内容差异,-2最近两次更新

git tag //列出所有tag
//新建一个tag在当前commit
git tag [tag]
//新建一个tag在指定commit
git tag [tag] [commit]
//查看tag信息
git show [tag]
//提交所有tag
$ git push [remote] --tags

// 新建一个分支,指向某个tag
$ git checkout -b [branch] [tag]

免密码

git 配置SSH即可提交免密码

  1. 生成秘钥
ssh-keygen -t rsa -C "cc.2008.com@163.com"

按3个回车,密码为空。(不要输密码)。然后到.ssh文件夹下面将id_rsa.pub里的内容复制出来粘贴到github个人中心的账户设置的ssh key里面

  1. 设置用户名密码
$ git config --global user.name "chen1218chen"
$ git config --global user.email "cc.2008.com@163.com"

# 查看
git config --list
  1. 测试
ssh -T git@github.com 

成功提示:

Hi chen1218chen! You've successfully authenticated, but GitHub does not provide shell access.  

命令分析

git help

git log

提交记录过长,按q键退出

git mv

修改文件名:

git mv file_from file_to

git rm

删除文件

rm <file>
git rm <file>

git commit

git commit 提交时强制要求输入提交说明,不能省略,使用-m参数输入提交说明,如果没有,git会自动打开一个编辑器,要求在其中输入提交说明。
参数说明:
-m 输入提交说明
–amend 对刚刚的提交进行修补
–allow-empty 空白被允许提交
–reset-author 将author的ID同步修改

最后一次commit信息写错了

如果只是提交信息写错了信息,可以通过以下命令单独修改提交信息

git commit --amend

注意: 通过这样的过程修改提交信息后,相当于删除原来的提交,重新提交了一次。所有如果你在修改前已经将错误的那次提交push到服务端,那在修改后就需要通过 git pull 来合并代码(类似于两个分支了)。
通过 git log –graph –oneline 查看就会发现两个分支合并的痕迹

最后一次commit少添加一个文件

git add file1
git commit --amend

最后一次commit多添加一个文件

git rm --cached file1
git commit --amend

git clone

# 最简单的命令
git clone xxx.git

# clone到指定目录
git clone xxx.git "指定目录"

# clone时创建新的分支替代默认Origin HEAD(master)
git clone -b [new_branch_name]  xxx.git

git checkout

下载历史版本

# 查看历史版本的sha-1(也是commit版本号)
git log
# 获取
git checkout 75adcf5d3a33bb7266adfa7ae3d20ee6e841c68b

单个文件恢复到历史版本

git reset commit_id 文件路径
git checkout 文件路径

git push

推送数据到远程仓库

git push [remote-name] [branch-name]

git remote

git默认使用origin作为远程库名。master为默认主分支名,自动建立的,版本库初始化以后,默认在master主分支进行保存。

git remote //查看远程库名
git remote -v //查看远程库地址
git remte show [remote-name] //查看远程仓库的详细信息
git remote rename aa cc //修改远程仓库aa的名称
git remote rm cc  //删除远程仓库cc

删除远程仓库报错,如下图所示:

enter description here

原因是用法错误,git remote rm <主机名>用来删除添加的remote路径,正确用法如下图所示:

enter description here

常用命令:
enter description here

git config

git config --list //查看配置信息
git config -e  //版本库级配置文件
git config -e --global   //全局配置文件
git config -e --system  //系统级配置文件
git config --global core.editor
git config --global core.ui true //为终端的内容着色

user.name、user.email

删除全局配置中的user.name和user.email

1
2
git config --unset --global user.name
git config --unset --global user.email

这样一来,查看

1
2
git config user.name
git config user.email

将看不到输出。

git branch

enter description here

git tag

# 查看标签
git tag
# 打标签
git tag -a 'V1.1' -m 'first version'
# 轻量级标签
git tag V1.1

-a: 创建标签
-m: 存储标签信息

# 查看标签信息
git show V1.1
# 推送标签到远程服务器
git push origin V1.1
# 把所有不在远程仓库上的标签推送上去
git push origin --tags

# 补打标签
git log --pretty=oneline //查看版本号
git tag -a v1.2 9fceb02...(commit提交版本号)
git push origin v1.2 //提交tag

git reset

enter description here

git reset HEAD <file> //HEAD指针指向当前分支的最新的提交
git reflog  //查看所有日志包括撤销的操作
git reset --hard 2d87c9b  //回复到2d87c9b这个版本
git reset HEAD^ 
git reset HEAD^^
git reset HEAD~1
git reset HEAD~n

git merge

查看支持的工具

git mergetool --tool-help

enter description here
如果工具有效,设置merge.tool

git config --global merge.tool p4merge

设置路径

git config --global mergetool.p4merge.path c:/Users/my-login/AppData/Local/Perforce/p4merge.exe

案例

回退单个文件的历史版本

#查看历史版本
git log 1.txt

#回退该文件到指定版本
git reset [commit_id] 1.txt
git checkout 1.txt

#提交
git commit -m "回退1.txt的历史版本"

移除add过的文件

#方法一
git rm --cache [文件名]

#方法二
git reset head [文件/文件夹]

常见问题

error:failed to push som refs to

1
error:failed to push som refs to ......

解决方法:
1、先输入 git pull origin master ,先把远程服务器github上面的文件拉下来
2、再输入git push origin master

fatal: remote origin already exists.

1
fatal: remote origin already exists.

解决方法:
1、先输入 git remote rm origin
2、再输入git remote add origin https://github.com/chen1218chen/bootstrap.git 就不会报错了!

fatal: The remote end hung up unexpectedly

1
fatal: The remote end hung up unexpectedly

The problem is due to git/https buffer settings.
解决方法:

1
git config http.postBuffer 524288000

获取项目

1
git clone https://github.com/chne1218chen/bootstrap.git

更新时与本地文件冲突

报错:

error: Your local changes to the following files would be overwritten by merge:
        _config.yml
        layout/_partial/footer.ejs
Please, commit your changes or stash them before you can merge.
Aborting

解决方法:

# 暂存
git stash
git pull
# 恢复
git stash pop
# 查看暂存
git stash list
# 清空暂存
git stash clear

常用软件

  1. IDE开发工具
    MyEclipse10、WebStorm10.0.3、eclipse+JRbel
  2. 服务器
    Tomcat7.0.63,jdk1.7
  3. 版本控制
    github客户端
    cc.2008.com@163.com
    cc.2008.com
  4. 编辑器
    NotePad++、马克飞象、markdownPad、印象笔记
  5. 浏览器
    chrome、火狐+firbug

常见问题

[TOC]

  1. html中ID属性值同一页面中不能重复,最好同一系统中也不要存在相同ID,否则JS通过ID属性获取对象的时候会出错,列入遇到的bootstrap dataTimePicker插件中点击日历不显示、bootstrapValidator中重置表单没有反应
  2. 静态数据或者静态表在数据库表设计是可以不用建立数据库表,而是用JSON文件来存储。有时也可选用视图的形式
    #Tomcat
  3. 启动报错
    1
    java.lang.IllegalStateException: Web app root system property already set to different value: 'webapp.root' = [D:\apache-tomcat-7.0.63\webapps\JDJ\] instead of [D:\apache-tomcat-7.0.63\webapps\LBSHMonitor\] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!

错误原因是因为tomcat启动了两个想似的项目,解决方法一是删除一个项目,而是在web.xml里面加如下配置:

1
2
3
4
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>JDJ</param-value>
</context-param>

MySQL

1.mysql查看编码

1
SHOW VARIABLES LIKE 'CHARACTER%' ;

  1. mysql默认情况下是否区分大小写,使用:
    1
    show Variables like '%table_names'

查看lower_case_table_names的值,0代表区分,1代表不区分。

  1. 设置远程登录

    修改数据表

可能是你的帐号不允许从远程登陆,只能在localhost。这个时候只要在 localhost 的那台电脑,登入MySQL后,更改 “MySQL” 数据库里的 “user” 表里的 “Host” 项,从“localhost”改称“%”,%表示所有机器都允许。

1
2
3
mysql> use mysql 

mysql> update user set Host='%' where User='root';

授权权限

允许任何主机使用“myuser”账号和“mypwd”密码连接到 MySQL 服务器。

1
mysql> GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDENTIFIED BY 'mypwd' WITH GRANT OPTION;

即可生效。

1
mysql> FLUSH PRIVILEGES;

通过以上两步走就可以了。

SSH配置集成

[TOC]

工作流程

  • web容器启动
  • 加载spring配置文件,进行初始化,配置中包含hibernate配置信息

Spring整合hibernate

  • dataSource
  • 配置sessionFactory,让spring来创建Session,注入dataSource。一般三个property:dataSource、packagesToScan和hibernateProperties
  • 配置事务管理器 transactionManager,注入sessionFactory
  • 对事务管理器管理事务设置注解方式
    详见6
    配置文件的引入

web.xml配置文件

  • web.xml文件并不是web工程必须的。
  • web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。在tomcat中的加载顺序是Context-Param,listener,filter,servlet
  • 每个xml文件都有定义它书写规则的Schema文件,也就是说javaEE的定义web.xml所对应的xml Schema文件中定义了多少种标签元素,web.xml中就可以出现它所定义的标签元素,也就具备哪些特定的功能。web.xml的模式文件是由Sun 公司定义的,每个web.xml文件的根元素为中,必须标明这个web.xml使用的是哪个模式文件。
  • ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。

    基本配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!--增加struts2的配置-->
    <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
    </filter-mapping>

    <!--自动装配ApplicationContext的配置信息, Spring与Struts的整合 -->
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

ssh中文过滤配置

<!-- ssh 中文过滤 -->
<filter>
    <filter-name>Set Character Encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>Set Character Encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>struts-cleanup</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts-cleanup</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

struts.xml

Struts2原理就是用拦截器,使得你客户端发送的请求都被拦截下来后处理。拦截器用到了反射机制。Struts2主要的功能是控制转发,在于Action的处理,和struts.xml配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<!-- 开启使用开发模式,详细错误提示 -->
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.encoding" value="utf-8"></constant>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

<package name="default" extends="struts-default,json-default">
<action name="getUnreadMessage" class="com.lbs.action.MessageAction"
method="queryUnreadMessage">
<result name="success" type="json">/success.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
</struts>

如果不配置,默认位置在WEB-INF文件夹底下。

JS基础之大杂烩

[TOC]

执行环境和执行环境对象

执行环境由函数在执行过程中发生的所有事物组成,所有函数中定义的变量和函数都是执行环境的一部分。变量在作用域内,即函数运行时变量在当前执行环境中,可访问
属于执行环境的变量和函数,被保存在执行环境对象中。执行环境对象是对执行环境的ECMA标准的实现。

enter description here
执行环境是Javascript引擎的一部分,在Javascript中不能直接访问。

js对象和原型链

javascript的对象是基于原型的,java对象是基于类的。

enter description here

enter description here

enter description here
每个方法中,首先创建了对象的模板。模板在基于类的编程中叫做,在基于原型的编程中叫做原型对象,作用都是为了用来:作为创建对象的结构。

创建构造对象,基于类的编程中构造对象在类的内部定义;在js中对象的构造函数和原型是分开设置的,需要用表2-3中的红框部分Prisoner.prototype = proto;将它们连接在一起。

最后,实例化对象。

函数

一个函数如果没有return语句,那它就只执行函数体中的每条语句,并返回undefined值给调用者。

函数定义

1
2
3
var func = function(name){
console.log("终端输出"+name);
}

嵌套函数

嵌套函数定义,test2只能在test中调用。不能再其他函数中调用

function test(){
    var a=1;
    function test2(){
        a++;
        console.log(a);
    }
    test2();
}
test();//2

console.log(); 终端打印输出,最早是火狐在fiebug中用来调试
作用域规则:嵌套函数可以访问嵌套他们的外部函数的参数和变量。

匿名函数

  1. 用一个局部变量来保存匿名函数
var prison = function(){
    ...
}
  1. 自执行匿名函数
    jquery的实现就是使用了自执行的匿名函数,
(function(){
    ...
})();

enter description here

传参

(function($){
    console.log($); //jQuery
    ...
})(jQuery)

可以将自执行函数保存在一个变量中,如下:

var worker = (function(){
    var person_name = "cc";
    return {
        name: person_name
    }
})();
console.log(worker.name); // cc

自执行匿名函数被用来控制变量的作用域,阻止变量泄露到代码的其他地方去。常用于创建Javascript插件,不会和应用代码起冲突,因为它不会向全局名字空间添加任何变量。

setTimeOut()及js引擎、线程

js引擎是单线程的,基于事件驱动的语言,执行顺序遵循一个事件队列的机制。js引擎处理到与其他线程相关的代码,就会分发给其他线程,他们处理完后需要JS引擎处理是,在事件队列后面添加一个任务。

<script>
    alert("1");
    setTimeOut("alert(2)",0);
    alert(3);
</script>

执行顺序1,3,2

可看出setTimeOut(fn,0);不是立即执行的。原因是:当程序执行到setTimeOut这里,会开启一个定时器线程,然后继续执行新的代码,该线程会在指定的时间后在事件队列里面插入一个新任务,所以setTimeOut中的操作会在所有主任务之后,执行顺序就是1,3,2了。
setTimeOut新解:在指定时间内,将任务放入事件队列,等待js引擎空闲时被执行
js引擎和GUI引擎(渲染引擎)是互斥的。一个挂起一个执行。
浏览器引擎是多线程的,它们在内核的控制下保持同步,一个浏览器至少实现三个常驻线程。:js引擎线程、GUI引擎线程、浏览器时间触发线程。

闭包

js采用词法作用域,即函数的执行依赖于变量的作用域,而变量的作用域是在函数定义是决定的,对应一个作用域链。函数对象可以通过作用域链相互连接起来,函数体的内部变量都保存在函数作用域内,这种特性在计算机中成为闭包。从技术的角度上讲,函数就是一个闭包。

function test() {
    var a = 4;
    return {
        add : function() {
            a++;
            console.log(a);
        },
        plus : function() {
            a--;
            console.log(a);
        }
    };
}
var c1 = new test();
var c2 = new test();
c1.add();//5
c2.plus();//3

两个变量不会相互影响。
初始化私有变量值

function test(n){
    return{
        get count(){
            return n++;
        },
        set count(m){
            if(n>m)
                n=m;
            else throw Error("ddd");
        }
    };
}
var t = test(100);
t.count;
console.log(t.count);//100
t.count=99;
console.log(t.count);//99
  1. 对象的方法调用
var a=1;
function test(){
    var a=3;
    console.log(this.a);
}
var obj={
        a:6,
        fn:test
};
obj.fn();//6
obj.fn.call();//1

this指向当前调用该方法的对象,使用对象的方法调用call,this默认指向的是全局对象,若想改变this指向

var a=1;
function test3(){
    console.log(this.a);
}
test3.call();//1
var obj={
    a:8,
    fn:test3
}
var para={a:9};
obj.fn.call(para);//9

call和apply都是Function对象的方法

  1. 构造函数
function test2(){
    this.a=7;
}
var o = new test2();
console.log(o); //7
  1. 嵌套函数的作用域
var a=1;
function test4(){
    console.log(this.a);//2
    function test5(){
        console.dir(this.a);//1
    }
    test5();
}
var obj = {a:2,fn:test4};
obj.fn();

prompt

1
2
var  username = prompt("what is your name?");
//username则可以获取到输入的参数

js中引用jsp代码

''中直接写JSP代码

1
2
3
4
5
6
7
function getCId(){
return '<%=session.getAttribute("cId")%>';
}
```


## JSON总结

//str->obj
JSON.parse();
//obj->str
JSON.stringify();
```

js字符串长度限制

是使用get传递参数,url无论如何都有2k的长度限制

java

[TOC]

java

集合

  • set
    • HashSet
    • TreeSet
  • list
    • ArrayList
    • LinkedList
  • map
    • HashMap
    • TreeMap

Collection: 集合接口,包含Set,List
java.util.Collections: 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

构造函数

  1. 必须与类名同名
  2. 可以有多个或者0个
  3. 没有返回值
  4. 伴随着new操作一起被调用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class A{
    public A(){
    System.out.println("调用了无参的构造函数");
    }
    public A(String mess){
    System.out.println("调用了有参的构造函数\n"+
    "参数内容为:"+mess);
    }
    }

    public class Test{
    public static void main(String [] args){
    A a_1=new A();//调用无参的构造函数
    A a_2=new A("Hello");//调用有参的构造函数
    }
    }
|