本文主要介绍Spring中,

1 Spring JDBC

2 使用注解方式管理事务的传播行为

3 采用XML 方式配置事务

4 SH 整合

5 SSH 整合

一、Spring JDBC

1) 导包 , 使用myeclipse2014, 添加与持久化相关的包

2) 引入名称空间等

3) 配置数据源

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><!-- 单实例bean -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/shop?useUnicode=true&amp;characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>
<property name="initialSize" value="10"/> <!-- 连接池启动时的初始值 -->
<property name="maxActive" valu3) e="300"/> <!-- 连接池的最大值 -->
<property name="maxIdle" value="5"/> <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
<property name="minIdle" value="3"/> <!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
</bean>

4) dao层

@Repository("userDaoImpl")
public class UserDaoImpl {
private JdbcTemplate jdbcTemplate; //用于进行数据库操作的模板,线程安全的 @Resource
public void setDataSource(DataSource dataSource){
this.jdbcTemplate=new JdbcTemplate(dataSource);
} //添加
public int addUser(UserInfo user){
String sql="insert into userInfo (userName,password,note) values(?,?,?)" ;
Object[] paramList={user.getUserName(),user.getPassword(),user.getNote()}; //也可以不用定义数组,直接这样写 :return jdbcTemplate.update(sql, user.getUserId(),user.getUserName(),user.getPassword(),user.getNote());
return jdbcTemplate.update(sql, paramList);
} //删除
public int delUser(int id){
String sql="delete from userInfo where id=?";
Object[] paramList={id};
return jdbcTemplate.update(sql, paramList);
} //修改
public int update(UserInfo user){
String sql="update userInfo set userName=?,password=?, note=? where id=?";
Object[] paramList={user.getUserName(),user.getPassword(),user.getNote(),user.getId()};
return jdbcTemplate.update(sql, paramList);
} //查询
public UserInfo getUserById(int id){
String sql="select * from userInfo where id=?"; //注意:如果查询结果多于一条,将报异常
Object[] paramList={id};
Object user=jdbcTemplate.queryForObject(sql, paramList, new BeanPropertyRowMapper(UserInfo.class));
return (UserInfo)user;
} //查询出列表
public List<UserInfo>getUserList(){
String sql="select * from userInfo";
return (List<UserInfo>)jdbcTemplate.query(sql,new BeanPropertyRowMapper(UserInfo.class));
} //查询出单个Int值
public int getUserCount(){
String sql="select count(*) from userInfo";
return jdbcTemplate.queryForInt(sql);
} //只查询一个字段
public String getUserName(int id){
String sql="select userName from userInfo where id= "+id;
return (String)jdbcTemplate.queryForObject(sql, String.class); //因为要查询的字段是String型的,所以在这里用 String.class
} //返回map
public Map getUserMapData(int id){
String sql="select * from userInfo where id="+id;
return jdbcTemplate.queryForMap(sql);
} //添加一个用户,返回其ID
public void addUser2(final UserInfo user){ //注意,这里必须用 final
jdbcTemplate.execute(new ConnectionCallback<Object>() { //org.springframework.jdbc.core.包下的 ConnectionCallback
@Override
public Object doInConnection(Connection conn) throws SQLException,DataAccessException { String sql="insert into userInfo (userName,password,note) values(?,?,?)" ;
PreparedStatement stm=conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
stm.setString(2, user.getUserName());
stm.setString(3, user.getPassword());
stm.setString(4, user.getNote()); stm.executeUpdate();
ResultSet rs=stm.getGeneratedKeys(); if(rs.next()){
System.out.println("新添加的用户的主键是:"+rs.getInt(1));
}
return null;
}
});
} //拿到自增主键的另一个方法,来自帮助文档
public void ttt(){
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement("insert into my_test (name) values(?)", new String[] {"id"});
ps.setString(1, "张三");
return ps;
}
},
keyHolder);
keyHolder.getKey(); //这就是拿到的自增主键
} }

5) 测试用例

public class UserDaoImplTest {
private static ClassPathXmlApplicationContext ctx;
private static UserDaoImpl dao; @BeforeClass
public static void setUpBeforeClass() throws Exception {
ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
dao=(UserDaoImpl)ctx.getBean("userDaoImpl");
} @Before
public void setUp() throws Exception {
} @Test
public void testAddUser() {
UserInfo user=new UserInfo();
user.setUserName("赵明明");
user.setPassword("忘了");
user.setNote("又想起来了"); dao.addUser(user); System.out.println("-----------嘻嘻---------------"); } @Test
public void testDelUser() {
int result=dao.delUser(196611);
System.out.println(result);
} @Test
public void testUpdate() {
UserInfo user=new UserInfo();
user.setId(196610);
user.setUserName("费无极");
user.setPassword("大费费");
user.setNote("中小型费费"); int result=dao.update(user);
System.out.println(result);
} @Test
public void testGetUserById() {
UserInfo user=dao.getUserById(196609);
System.out.println(user.getNote());
} @Test
public void testGetUserList() {
List<UserInfo>userList=dao.getUserList();
for(UserInfo u:userList){
System.out.println(u.getUserName());
}
} @Test
public void testGetUserCount() {
int result=dao.getUserCount();
System.out.println(result);
} @Test
public void testGetUserName() {
String userName=dao.getUserName(491553);
System.out.println(userName);
} @Test
public void testGetUserMapData() {
Map userMap=dao.getUserMapData(2); Set<Map.Entry>entrySet=userMap.entrySet();
Iterator <Map.Entry>it=entrySet.iterator();
while(it.hasNext()){
Map.Entry item=it.next();
System.out.println(item.getKey()+"---"+item.getValue());
}
} @Test
public void testAddUser2() {
UserInfo user=new UserInfo();
user.setUserName("奥八马");
user.setPassword("小狒狒");
user.setNote("超级小狒狒");
dao.addUser2(user);
} @Test
public void testTtt() { }

二、使用注解方式管理事务的传播行为

//删除
public int delUser(int id){
String sql="delete from userInfo where id=?";
Object[] paramList={id};
int result= jdbcTemplate.update(sql, paramList); int a=90/0; //如果程序在这里出现异常,会不会回滚,默认情况下,不回滚
return result;
}

在spring中开启事务管理

1)要加入相应的名称空间

xmlns:tx="http://www.springframework.org/schema/tx"
...
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd

2) 配置事务管理器

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 使用注解的方式管理事务(不使用注解,不用加这句) -->
<tx:annotation-driven transaction-manager="txManager"/>

3) 在要进行事务管理的类上,用注解声明

@Transactional @Repository("userDaoImpl")
public class UserDaoImpl {
public int delUser(int id){
String sql="delete from userInfo where id=?";
Object[] paramList={id};
int result= jdbcTemplate.update(sql, paramList); int a=90/0; //如果程序在这里出现异常,会不会回滚,由于声明了事务,所以会回滚
return result;
} ...
} //对这个方法进行细粒度的控制
@Transactional(noRollbackFor=RuntimeException.class)
public void delAllUser(){
String sql="delete from userInfo ";
jdbcTemplate.execute(sql);
throw new RuntimeException(发生了运行时异常); }

这段代码要删除所有用户,但运行时抛出了异常,所以事务会回滚,数据不会被删除,可以更改这种行为,在方法前加上注解。

@Transactional(noRollbackFor=RuntimeException.class)  表示出了异常也不回滚。

有的方法比如查询方法,不需要事务,可以在该方法上指定。

@Transactional(propagation=Propagation.NOT_SUPPORTED)  //加上以后,这个方法就不再支持事务了
public List<UserInfo>getUserList(){
String sql="select * from userInfo";
return (List<UserInfo>)jdbcTemplate.query(sql,new BeanPropertyRowMapper(UserInfo.class));
}

事务的传播行为

----REQUIRED:业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务。

----NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行。

----REQUIRESNEW:(requiresnew) 属性表明不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行。

----MANDATORY (mandatory,强制的,命令的,受委托的):该属性指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。 如果业务方法在没有事务的环境下调用,容器就会抛出例外。

----SUPPORTS:这一事务属性表明,如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。

----Never:指定业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出例外,只有业务方法没有关联到任何事务,才能正常执行。

----NESTED:nested (窝,嵌套)如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务, 则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保存点。

内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

REQUIRED 是默认的 ,比如

//这里什么都不写,相当于写上 @Transactional(propagation=Propagation.REQUIRED)
public int delUser(int id){
String sql="delete from userInfo where id=?";
Object[] paramList={id};
int result= jdbcTemplate.update(sql, paramList); int a=90/0; //如果程序在这里出现异常,会不会回滚
return result; public void testTx(UserInfo user){
jdbcTemplate.update("delete from userInfo where id=1");
addUser(user);
jdbcTemplate.update("delete from userInfo where id=2");
//int x=0/0;
}

说明:

对于这个例子来说,没有指明事务的传播行为,所以这是默认的 @Transactional(propagation=Propagation.REQUIRED)。

对于 addUser 来说,如果如果方法运行时,已经处在一个事务中,则它将加入这个事务。所以,上面的操作,将会成为一个整体。

三、采用XML 方式配置事务

<aop:config>
<aop:pointcut id="myTxPointCut" expression="execution(* cat.dao.UserDaoImpl_other.*(..))" />
<aop:advisor advice-ref="txAdvisor" pointcut-ref="myTxPointCut" />
</aop:config> <tx:advice id="txAdvisor" transaction-manager="txManager" >
<tx:attributes>
<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>

用XML配置的方式,就不用再写

<tx:annotation-driven transaction-manager="txManager"/>
                 @Repository("userDaoImpl_other")
public class UserDaoImpl_other {
....
public void testTx(UserInfo user){
jdbcTemplate.update("delete from userInfo where id=5");
addUser(user);
jdbcTemplate.update("delete from userInfo where id=6"); int x=0/0;
} public static void main(String[] args) {
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDaoImpl_other dao=(UserDaoImpl_other)ctx.getBean("userDaoImpl_other"); UserInfo user=new UserInfo();
user.setUserName("9999999999999");
user.setPassword("小狒狒");
user.setNote("超级小狒狒"); dao.testTx(user); } }

四、SH 整合

1) 导入名称空间

<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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

2) 打开扫描

<context:component-scan base-package="cat" />

3) 配置 DataSource  //hibernate用的

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/production?useUnicode=true&amp;characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="initialSize" value="10"/> 连接池启动时的初始值
<property name="maxActive" value="500"/> 连接池的最大值
<property name="maxIdle" value="2"/> 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止
<property name="minIdle" value="3"/> 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请
</bean>

4) 配置SessionFactory //hibernate用的

/*
sessionFactory 建议做成单例
LocalSessionFactoryBean 除了可建一个 sessionFactory 对象出来,把它做成单例,还专门用于集成
Hibernate ,用于做一些额外的工作,比如接管hibernate的事务
*/
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
<property name="dataSource">
<ref bean="dataSource" />
</property> <property name="mappingResources">
<list>
<value>cat/beans/UserInfo.hbm.xml</value>
</list>
</property> <property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.format_sql=true //配置二级缓存用的
// hibernate.cache.use_second_level_cache=true
// hibernate.cache.use_query_cache=false //是否使用查询缓存 因为它的效率比较差,所以不用
// hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider //指定的缓存产品 要导入 lib\optional\ejcacje -1-1-3/jar
</value>
</property>
</bean>

5) 配置事务管理器 txManager

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean> <tx:annotation-driven transaction-manager="txManager"/> 如果要用注解方式管理事务,要加这个配置

五、SSH 整合

再和 struts2 进行整合

1) 在web.xml 中 对Spring容器进行初始化

//指定spring 的配置文件,默认从web根目录寻找配置文件,可以通过string 提供的classpath:前缀指定从类路径下寻找
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value> 如果配置多个配置文件,可以用逗号隔开
</context-param>
// 对spring 容器进行实例化 ,实例化后,这个实例会放在applicateion 范围-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

2) 在web.xml中添加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>杠*</url-pattern>
</filter-mapping>

3) 在类路径下添加 sruts.xml 文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.objectFactory" value="spring" /> //声明要用spring来创建 action 类 <package name="p_user" namespace="" extends="struts-default">
<action name="userAction_name" class="userAction">
<result name="success">/main.jsp</result>
</action>
</package>
</struts>

4) Action 类

@Controller
public class UserAction {
@Resource(name="userDaoImpl")
private IUserDao dao;
public String execute(){
UserInfo user=new UserInfo();
user.setUserName("SSH整合成功");
dao.addUser(user);
return "success";
}
}

5)接口

public interface IUserDao {
void addUser(UserInfo user) ; void delUser(int id) ; UserInfo getUserById(int id); List<UserInfo>getUserList(); void updateUser(UserInfo user); void deleteUser(UserInfo user);
}

6)实现类

@Transactional @Repository
public class UserDaoImpl implements IUserDao{
@Resource //这个注解默认是按名称注入
private SessionFactory sessionFactory; public void addUser(UserInfo user) {
//Session s=sessionFactory.openSession();
//它得到的是spring容器管理的session
Session s=sessionFactory.getCurrentSession();
s.save(user);
} public void delUser(int id) {
Session s=sessionFactory.getCurrentSession();
UserInfo user=(UserInfo)s.get(UserInfo.class, id);
s.delete(user); //先查一下,再删除
} @Transactional(propagation=Propagation.NOT_SUPPORTED)
public UserInfo getUserById(int id) {
Session s=sessionFactory.getCurrentSession();
return (UserInfo)s.get(UserInfo.class, id);
} @Transactional(propagation=Propagation.NOT_SUPPORTED)
public List<UserInfo> getUserList() {
Session s=sessionFactory.getCurrentSession();
return s.createQuery("from UserInfo").list();
} public void updateUser(UserInfo user) {
Session s=sessionFactory.getCurrentSession();
s.saveOrUpdate(user);
} public void deleteUser(UserInfo user) {
Session s=sessionFactory.getCurrentSession();
s.delete(user);
} }

附 如何知道一个类在哪个jar包中

ctl + shift + t

附 关于被Spring 管理的 dao 使用接口访问的问题

Spring的文档中这么写的:Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理,如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。使用beanNameAutoProxyCreator来进行事务代理的话,他的proxyTargetClass这个属性设置为false(默认是false),即使用JDK动态代理,如果你的service类没有实现接口的话,就会报类型转换错误。

解决办法有:

1、给service类添加一个接口iService,让service类实现它,则创建代理类时使用JDK动态代理就不会出现问题

2、设置beanNameAutoProxyCreator的proxyTargetClass属性为true,意思是强制使用CGLIB代理,前提是你已经将CGLIB包加入到项目中。

其实,就是 在配置文件中配置:

<aop:aspectj-autoproxy proxy-target-class="true"/>

但要注意:

需要导入 cglib-nodep-2.2.jar (它可以从myeclipse 自动生成的 Spring 项目中获得),还要导入 aspectj 相关的几个jar包。

Java框架之Spring(五)的更多相关文章

  1. java框架篇---spring AOP 实现原理

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  2. java框架之Spring(2)-注解配置IOC&AOP配置

    注解配置IoC 准备 1.要使用注解方式配置 IoC,除了之前引入的基础 jar 包,还需要引入 spring-aop 支持包,如下: 2.在 applicationContext.xml 中引入 c ...

  3. Java框架之Spring(四)

    本文主要讲述在Spring中 1 注解方式装配 2 以自动扫描把组件纳入spring容器中管理 3 面象切面编程-代理的jdk 版实现 4 使用 Cglib 生成代理 5 aop编程的一些概念 6 使 ...

  4. Java - 框架之 Spring

    一. IOC 和 DI IOC : 控制反转,将对象的创建权反转给了 Spring.DI  : 依赖注入,前提是必须要有 IOC 的环境,Spring 管理这个类的时候将类的依赖的属性注入(设置)进来 ...

  5. java框架篇---spring IOC 实现原理

    IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用 ...

  6. Java框架之Spring MVC(二)

    一.Spring MVC 验证 JSR 303 是ajvaEE6 中的一项子规范 ,叫 Bean Validation 用于对javaBean中的字段进行校验. 官方的参考实现是: Hibernate ...

  7. Java框架之Spring MVC(一)

    一.Spring简介 Spring MVC是当前最优秀的 MVC 框架,自从Spring 2.5 版本发布后,由于支持注解配置,易用性有了大幅度的提高.Spring 3.0 更加完善,实现了对 Str ...

  8. java框架之spring

    一.HelloWorld程序 导入四个核心包(core.beans.expression.context)和一个logging的包: 写一个类并在 xml 中配置相应的bean(两个重要属性 id 和 ...

  9. java框架之Spring(1)-入门

    介绍 概述 Spring 是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring 是于 2003 年兴起的一个轻量级的 J ...

随机推荐

  1. javascript 正則表達式补充

    定义 JavaScript种正則表達式有两种定义方式,定义一个匹配类似 <%XXX%> 的字符串 1. 构造函数 var reg=new RegExp('<%[^%>]+%&g ...

  2. ASP.NET Core 使用 Hangfire 定时任务

    定时任务组件,除了 Hangfire 外,还有一个 Quarz.NET,不过 Hangfire .NET Core 支持的会更好些. ASP.NET Core 使用 Hangfire 很简单,首先,N ...

  3. IEEE Trans 2007 Signal Recovery From Random Measurements via OMP

    看了一篇IEEE Trans上的关于CS图像重构的OMP算法的文章,大部分..看不懂,之前在看博客的时候对流程中的一些标号看不太懂,看完论文之后对流程有了一定的了解,所以在这里解释一下流程,其余的如果 ...

  4. 自学WPF之Binding(二)

    没有Source的Binding,使用ContentText作为Binding源: 上一篇是把CLR类型对象当作指定为Binding的Source,两种方法:一是把对象赋值给Binding.Sourc ...

  5. Unable to resolve persistence unit root URL

    异常信息 时间:2017-03-07 11:46:05,516 - 级别:[ WARN] - 消息: [other] The web application [ROOT] appears to hav ...

  6. mongodb副本集配置

    需要用到mongodb的时候单个实例肯定是不行的,挂了怎么办,那然后呢,跟mysql一样搞主从备份吗,是可以的mongodb这么弄,不过官网已经不推荐了这么干了,推荐使用副本集的模式,然后数据再大一点 ...

  7. MySQL数据库常见操作

    数据库连接与关闭:mysql -h 服务器主机地址 -u 用户名 -p 用户密码 创建新用户并授权:grant 权限 on 数据库.数据表 to 用户名@登录主机 identified by &quo ...

  8. Python3 学习Python流程--试水中

    二.基础语法之后可以搭载服务器练习: 教程 一.1.Python 搭建环境. 初学基本语法 :Python基本语法 2.推荐 IDE :  PyCharm CE 下载 菜鸟教程都是基础语法,可以对py ...

  9. iOS ShareSDK 三方分享/登录使用

    原文 http://www.cnblogs.com/CoderAlex/p/4860352.html 一: 快速集成 1.前言 作为现在App里必不可少的用户分享需要,社交化分享显然是我们开发app里 ...

  10. Keras的安装与配置

    Keras是由Python编写的基于Tensorflow或Theano的一个高层神经网络API.具有高度模块化,极简,可扩充等特性.能够实现简易和快速的原型设计,支持CNN和RNN或者两者的结合,可以 ...