Block
1)、Blocks封装了一段代码,可以在任何时候执行
2)、Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline(内联函数的),并且默认情况下它对局部是只读的
3)、苹果官方建议尽量多用blocks。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多
Blocks的定义
例一
Main.m
//
// main.m
// OC10-内存管理2-set方法的内存管理
//
// Created by qwz on 13-12-9.
// Copyright (c) 2013年 renhe. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Button.h"
typedef int (^mySum) (int, int) ;
void test(){
//定义了一个block,这个block返回值是int类型,接受两个int类型的参数
int (^Sum) (int, int) = ^(int a, int b){
return a + b;
};
int a = Sum(10, 11);
NSLog(@"%i", a);
}
void test2(){
//__block有2个下划线
__block int c = 15;
//声明了一个block变量
mySum sum = ^(int a, int b){
//如果外部的变量用了__block关键字,就可以在block内部修改这个变量
c = 19;
//block可以访问外面定义的变量
NSLog(@"c is %i", c);
return a + b;
};
NSLog(@"%i", sum(10, 10));
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
// test2();
Button *btn = [[[Button alloc] init] autorelease];
btn.block = ^(Button *btn){
NSLog(@"按钮-%@被点击了", btn);
};
//模拟按钮点击
[btn click];
}
return 0;
}
Button.h
//
// Button.h
// OC10-内存管理2-set方法的内存管理
//
// Created by qwz on 13-12-10.
// Copyright (c) 2013年 renhe. All rights reserved.
//
#import <Foundation/Foundation.h>
@classButton;
typedef void (^ButtonBlock) (Button *);
@interface Button : NSObject
@property (nonatomic, assign) ButtonBlock block;
//模拟按钮点击
- (void)click;
@end
Button.m
//
// Button.m
// OC10-内存管理2-set方法的内存管理
//
// Created by qwz on 13-12-10.
// Copyright (c) 2013年 renhe. All rights reserved.
//
#import "Button.h"
@implementation Button
- (void)click{
_block(self);
}
@end
最近写一个web服务接口,用到了MyBatis3.2,把我配置的过程及自己的一些做法供大家参考,希望能帮助到刚入手MyBatis的人;(如果您阅读文章时发现问题的,希望能留言指出)
首先导入mybatis-3.2.3.jar包 还有连接数据库的驱动包,我用的是Sqls2005 所以导入sqljdbc.jar
工程中必须导入的三个包(对应的包附件中可以下载):
- mybatis-3.2.3.jar
- sqljdbc.jar
- log4j-1.2.14.jar
- 第一部分 配置MyBatis及经验之谈(我把类所在包的路径删了,如果要引用我代码的话自己新建一个合适的包路径)
- 配置过程如下六个步骤缺一不可
- 第一步:编写数据库连接文件sqlserver-jdbc-connection.properties,我的文件路径在com.mybatis.config包下
#sqlserver connection driver=com.microsoft.sqlserver.jdbc.SQLServerDriver url=jdbc:sqlserver://192.168.1.31:1433; DatabaseName=dataBaseName username=sa password=sa
- 第二步:编写MyBatis配置文件Configuration.xml,我的文件路径在com.mybatis.config包下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 注意:每个标签必须按顺序写,不然蛋疼的DTD会提示错误:The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,plugins?,environments?,mappers?)". -->
<configuration>
<!-- 属性配置 -->
<properties resource="com/mybatis/config/sqlserver-jdbc-connection.properties">
<!-- 相同属性:最高优先级的属性是那些作为方法参数的,然后是资源/url 属性,最后是 properties元素中指定的属性 -->
<!-- <property name="username" value="sa"/> -->
<!-- <property name="password" value="phoenix"/> -->
</properties>
<!-- 设置缓存和延迟加载等等重要的运行时的行为方式 -->
<settings>
<!-- 设置超时时间,它决定驱动等待一个数据库响应的时间 -->
<setting name="defaultStatementTimeout" value="25000"/>
<!-- 这个配置使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 -->
<!-- <setting name="lazyLoadingEnabled" value="true"/> -->
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载 -->
<setting name="aggressiveLazyLoading" value="true"/>
<!-- 允许或不允许多种结果集从一个单独的语句中返回(需要适合的驱动) -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 使用列标签代替列名。不同的驱动在这方便表现不同。参考驱动文档或充分测试两种方法来决定所使用的驱动 -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许JDBC支持生成的键。需要适合的驱动。如果设置为true则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如Derby) -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单,没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其他情况) -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE"/>
</settings>
<!-- 别名 -->
<typeAliases>
<!-- 用户bean-用户登录时映射使用 -->
<typeAlias alias="UserBean" type="com.restservice.bean.UserBean"/>
<environments default="development">
<!-- environment 元素体中包含对事务管理和连接池的环境配置 -->
<environment id="development">
<transactionManager type="JDBC" />
<!-- type分三种:
UNPOOLED是每次被请求时简单打开和关闭连接
UNPOOLED的数据源仅仅用来配置以下 4 种属性driver,url,username,password
POOLED :JDBC连接对象的数据源连接池的实现,不直接支持第三方数据库连接池
-->
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- ORM映射文件 -->
<mappers>
<!-- 用户测试XML -->
<mapper resource="com/restservice/bean/UserBean.xml" />
</mappers>
</configuration>
- 第三步:编写对应的用户bean及xml
贴一下xml代码,需要自己写一下bean哦,(不会可以留言。)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<!-- namespace用于java代码调用时识别指定xml的mapper文件 -->
<mapper namespace="userinfo">
<!-- 开启Mabatis二级缓存 -->
<cache/>
<!-- 配置ORM映射 -->
<resultMap type="UserInfo" id="user_orm">
<id property="id" column="id"/>
<result property="code" column="code"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="phone" column="phone"/>
<result property="money" column="money"/>
</resultMap>
<!-- 用来定义可重用的SQL代码段 -->
<sql id="demo_sql">
code,name,sex,phone,money
</sql>
<insert id="inser_userInfo" parameterType="UserInfo">
<!-- include 引用可重用的SQL代码段 -->
INSERT INTO USERINFO(<include refid="demo_sql"/>) VALUES(#{code},#{name},#{sex},#{phone},#{money})
</insert>
<update id="update_userInfo" parameterType="UserInfo">
UPDATE USERINFO SET code=#{code} ,name=#{name} ,sex=#{sex} ,phone=#{phone} ,money=#{money} WHERE id=#{id}
</update>
<select id="selectAll_userInfo" resultMap="user_orm">
SELECT * FROM USERINFO
</select>
<select id="selectById_userInfo" parameterType="int" resultType="UserInfo">
SELECT * FROM USERINFO WHERE id= #{id}
</select>
</mapper>
sql语句中常用的特殊处理 如:需要in查询
<select id="findWellsInfo" useCache="false" flushCache="true" resultType="hashmap">
SELECT ID AS FIELDCODE,NAME AS DATACATEGORYNAME,'' COLOR FROM IMS_WELL WHERE ID IN
<foreach item="wellIds" index="index" collection="wellIds"
open="(" separator="," close=")">
#{wellIds}
</foreach>
</select>
我这里传入的参数是一个map ,map中有一个参数是数组wellIds,所以我写成collection="wellIds";
可以直接传入数组,写法:只需要把collection="wellIds"改成collection="array";
也可以传入List ,写法:只需要把collection="wellIds"改成collection="list";
还有很多特殊情况就不一一举例了,具体请详细阅读附件MyBatis3.2中文API
- 第四步:创建SessionFactoryUtil.java工具类
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
/**
*
* MyBatis会话工厂类.
*
* @version 1.0 2013-12-1
* @author xqwu
*/
public class SessionFactoryUtil {
protected static final Logger log = Logger.getLogger(SessionFactoryUtil.class);
//MyBatis配置路径
private static final String RESOURCE = "com/mybatis/config/Configuration.xml";
//sql会话工厂
private static SqlSessionFactory sqlSessionFactory = null;
//所有sqlSession
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
/**
* 静态代码块 用于获得sqlSessionFactory
* 不执行 由SessionFactoryListener调用初始化方法
*/
/*static {
Reader reader = null;
try {
reader = Resources.getResourceAsReader(RESOURCE);
} catch (IOException ioex) {
throw new RuntimeException("Get resource error:"+RESOURCE, ioex);
}
//获得sqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}*/
/**
*
* 获得SqlSessionFactory
* @author xqwu
* @date 2013-12-1 下午2:08:59
*
* @return
*/
public static SqlSessionFactory getSqlSessionFactory(){
return sqlSessionFactory;
}
/**
*
* 初始化SqlSessionFactory.
* @author xqwu
* @date 2013-12-1 下午2:08:39
*
*/
public static void initSqlSessionFactory() throws RuntimeException,Exception{
try {
if(sqlSessionFactory == null){
Reader reader = Resources.getResourceAsReader(RESOURCE);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
log.debug("init sqlSessionFactory success");
}
} catch (IOException ioex) {
throw new RuntimeException("Get resource error:"+RESOURCE, ioex);
}
}
/**
*
* 获取sqlSession.
* @author xqwu
* @date 2013-12-1 上午11:27:38
*
* @return
*/
public static SqlSession getSession(){
SqlSession sqlsession = threadLocal.get();
if(sqlsession!=null){
if(sqlSessionFactory == null){
getSqlSessionFactory();
}
//如果sqlSessionFactory不为空则获取sqlSession,否则返回null
sqlsession = (sqlSessionFactory!=null) ? sqlSessionFactory.openSession(): null;
}
return sqlsession;
}
/**
*
* 关闭sqlSession
* @author xqwu
* @date 2013-12-1 上午11:26:23
*
*/
public static void closeSqlSession() throws Exception{
//获得sqlsession
SqlSession sqlsession = threadLocal.get();
threadLocal.set(null);
if(sqlsession!=null){//验证关闭sqlsession
sqlsession.close();
log.debug("close sqlsession success");
}
log.debug("sqlsession is null");
}
}
- 第五步:创建tomcat启动监听器类SessionFactoryListener,用于管理sqlSessionFactory生命周期(我用的是tomcat6.0)
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.Logger;
import com.opro.ims.i.restservice.utils.SessionFactoryUtil;
/**
* Class description goes here.
*
* @version 1.0 2013-12-6
* @author xqwu
*/
public class SessionFactoryListener implements ServletContextListener {
protected static final Logger log = Logger.getLogger(SessionFactoryListener.class);
/* (non-Javadoc)
* <p>Title: contextDestroyed</p>
* <p>Description: </p>
* @param arg0
* 当Servlet 容器终止Web 应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet 和Filter 过滤器。
* @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
*/
@Override
public void contextDestroyed(ServletContextEvent arg0) {
try {
SessionFactoryUtil.closeSqlSession();
} catch (Exception ex) {
log.error(ex.getMessage());
}
}
/* (non-Javadoc)
* <p>Title: contextInitialized</p>
* 当Servlet 容器启动Web 应用时调用该方法。在调用完该方法之后,容器再对Filter 初始化,
* 并且对那些在Web 应用启动时就需要被初始化的Servlet 进行初始化。
* @param arg0
* @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
*/
@Override
public void contextInitialized(ServletContextEvent arg0) {
try {
SessionFactoryUtil.initSqlSessionFactory();
} catch (RuntimeException rex) {
log.error(rex.getMessage());
} catch (Exception ex) {
log.error(ex.getMessage());
}
}
}
- 第六步:web.xml 配置文件中加入如下内容
<!-- 初始化SessionFactory监听器 --> <listener> <listener-class>com.opro.ims.i.restservice.listener.SessionFactoryListener</listener-class> </listener>
- 第二部分,自己写的扩展接口,项目中所有的dao都继承该接口,个人觉得是可以方便许多。(我把类所在包的路径删了,如果要引用我代码的话自己新建一个合适的包路径)放在自定义包下,如:package com.gool.core
编写接口BaseDao
import java.sql.SQLException;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.type.TypeException;
/**
* Class description goes here.
*
* @version 1.0 2013-11-29
* @author xqwu
*/
public interface BaseDao {
/**
*
* 获得sqlSession对象.
* @author xqwu
* @date 2013-11-29 下午4:17:11
*
* @return
*/
public SqlSession getSqlSession() throws TypeException,SQLException,Exception;
/**
*
* 插入数据.
* @author xqwu
* @date 2013-12-6 上午09:56:00
*
* @param s
* @param obj
* @throws TypeException
* @throws SQLException
* @throws Exception
*/
public void insert(String s, Object obj) throws TypeException,SQLException,Exception;
/**
*
* 查询所有数据.
* @author xqwu
* @date 2013-11-29 下午3:52:21
*
* @return
*/
public List<?> findAll(String s, Object obj) throws TypeException,SQLException,Exception;
/**
*
* 查询指定页数大小.
* @author xqwu
* @date 2013-11-29 下午3:54:06
*
* @param s namespace用于java代码调用时识别指定xml的mapper文件
* @param pageNo 页码
* @param pageSize 大小
* @return
*/
public List<?> findList(String s, Object obj, int pageNo, int pageSize) throws TypeException,SQLException,Exception;
/**
*
* 查询返回对象.
* @author xqwu
* @date 2013-12-2 下午02:58:41
*
* @param s
* @param param
* @return
*/
public Object selectOne(String s, Object param) throws TypeException,SQLException,Exception;
/**
*
* 更新数据方法.
* @author xqwu
* @date 2013-12-4 下午05:59:16
*
* @param s
* @param param
* @throws TypeException
* @throws SQLException
* @throws Exception
*/
public void update(String s, Object param) throws TypeException,SQLException,Exception;
}
编写接口实现BaseDaoImpl
import java.sql.SQLException;
import java.util.List;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.type.TypeException;
import com.opro.ims.i.restservice.core.BaseDao;
import com.opro.ims.i.restservice.utils.SessionFactoryUtil;
/**
* Dao基类,所有Dao都继承该类.
*
* @version 1.0 2013-11-29
* @author xqwu
*/
public class BaseDaoImpl implements BaseDao{
@Override
public SqlSession getSqlSession() throws TypeException,SQLException,Exception {
// TODO Auto-generated method stub
return SessionFactoryUtil.getSqlSessionFactory().openSession();
}
@Override
public List<?> findAll(String s, Object obj) throws TypeException,SQLException,Exception {
// TODO Auto-generated method stub
SqlSession session = getSqlSession();
try{
List list = session.selectList(s, obj);
return list;
} finally{
session.close();
}
}
@Override
public List<?> findList(String s, Object obj, int pageNo, int pageSize) throws TypeException,SQLException,Exception {
// TODO Auto-generated method stub
SqlSession session = getSqlSession();
try{
List list = session.selectList(s, obj, new RowBounds((pageNo-1)*pageSize, pageSize));
return list;
} finally{
session.close();
}
}
@Override
public Object selectOne(String s, Object param) throws TypeException,SQLException,Exception {
// TODO Auto-generated method stub
SqlSession session = getSqlSession();
try{
Object object = session.selectOne(s, param);
return object;
} finally{
session.close();
}
}
@Override
public void update(String s, Object param) throws TypeException,SQLException, Exception {
// TODO Auto-generated method stub
SqlSession session = getSqlSession();
try{
session.update(s, param);
session.commit();
} finally{
session.close();
}
}
/* (non-Javadoc)
* <p>Title: insert</p>
* <p>Description: </p>
* @param s
* @param obj
* @throws TypeException
* @throws SQLException
* @throws Exception
* @see com.opro.ims.i.restservice.core.BaseDao#insert(java.lang.String, java.lang.Object)
*/
@Override
public void insert(String s, Object param) throws TypeException, SQLException, Exception {
// TODO Auto-generated method stub
SqlSession session = getSqlSession();
try{
session.insert(s, param);
session.commit();
} finally{
session.close();
}
}
}
在Dao层中调用示例
继承BaseDaoImpl后,写法就如此简单了
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.type.TypeException;
import com.opro.ims.i.restservice.core.impl.BaseDaoImpl;
/**
* 检索报警数据Dao.
*
* @version 1.0 2013-12-5
* @author xqwu
*/
public class RetrieveWarningsDao extends BaseDaoImpl{
@SuppressWarnings("unchecked")
public List retrieveWarnings(Map param, int pageNo, int pageSize) throws TypeException,SQLException,Exception{
return findList("retrievewarnings.retrieveWarnings", param, pageNo, pageSize);
}
}
最后我把对应的MyBatis中文API分享给大家。
查看、添加、提交、删除、找回,重置修改文件
查看提交记录
tig
Mac上可以使用tig代替diff和log,brew install tig
取得Git仓库
提交你的修改
基本的分支管理
参考资料
远程仓库的使用
何谓分支
基本的分支与合并
分支的管理
分支式工作流程
远程分支
衍合
参考1: http://www.xbc.me/git-commands/
参考2: http://neverno.me/hello-world/git-commands-github.html
在线中文图书: 1. Git Magic 2. Pro Git