第一次接触spring,之前从来没有学过spring,所以算是赶鸭子上架,花了差不多一个星期来搭建,中间遇到各种各样的问题,一度觉得这个框架搭建非常麻烦,没有一点技术含量,纯粹就是配置,很低级!但随着搭建的完成,有一点点体会:框架可以让我们的代码更加像一个项目,而不是一个普普通通的作业,这在之前我们学生时代往往不会注意到这一点。我觉得这就是专业和业余的区别。当然,目前,我连spring入门可能都算不上,只是为了完成任务来搭建这套框架,但还是很有收获的,所以记录下这篇博客,给过来人参考。

另外还有一个重要原因是,网上的框架搭建如spring+mybatis的博客,老实说,有很多明显有错误!最终竟然还能正确运行出结果,简直匪夷所思,还有的,缺少文件或者说明,会让刚学习spring的人摸不着头脑,尤其是你兴致勃勃地参考一篇博客,辛苦地搭建了一大半,结果到最后发现,有一个文件没有提供,有一个函数没有提供,有一个类没有提供。。。总之你无法继续下去,内心一定会非常奔溃!所以,我决定写这篇博客!

关于spring的介绍,我就不多说了,我也是门外汉~我就说一下,我为什么要使用这几个框架,spring自然不必多说,mybatis是对数据库的封装,用来操作数据库,mina是对网络通信(如socket)的封装,logback是关于日志的框架。我要实现的是一个短信平台的验证系统,需要操作数据库,需要通过向第三方服务器发送短信,这几个功能可以由这些框架一一实现。

参考博客:

http://chenjc-it.iteye.com/blog/1402939

http://www.cnblogs.com/nick-huang/p/3838326.html

mybatis

mybatis和spring整合需要的包有mybatis、mybatis-spring、数据库驱动包(oracle是ojdbcXXX.jar或者mysql,根据用到的数据库配置)和数据库连接池dbcp包。如果对数据库连接池不太清楚的,可以上网搜索。关于包的版本,我用的跟网上的一些也都不一样,所以大家也没必要纠结一定要用哪个版本的包,不过确实会存在版本过高或过低导致的问题,到时候注意一下就行了。包的下载,我强烈推荐一个网址:https://mvnrepository.com/,只要输入相关关键字就可以找到相应不同版本的包,非常方便!好了,现在开始搭建。假设,我已经用oracle创建了一个表-wkzf,表的字段有(telephone,starttime...),为了方便,我只列出这两个字段,这两个字段的类型都是NUMBER。telephone表示手机号,是11位,starttime表示发送短信的时间,它是毫秒,用来表示现在与 1970 年1月1日00:00:00.000的偏移量,这个可以很方便地计算一个验证码是否超过60秒,如果是日期如yy-mm-dd-hh这样的格式就不太好计算了。

接下来,我们创建一个包,包名可以叫作com.xysj.mybatis.entity,包名的规则可以参考:http://www.runoob.com/java/java-package.html。这些小细节可以让你看起来更加专业。在这个包下面,我们可以创建一个实体类,用来与上面我们设计的表中的字段对应起来,代码如下:

 package com.xysj.mybatis.entity

 public class User {
private long telephone;
private long starttime; public long getTelephone()
public void setTelephone(long telephone)
...
}

可以看到,我们实体类User当中,有两个私有变量,很显然分别对应表中的两个字段,然后还有get和set函数,分别用来对这些变量进行操作。

接下来,我们定义一个接口类UserMapper,用来对数据库进行操作。同样,我们创建一个包:com.xysj.mybatis.mapper,在该包下面,创建一个java文件,代码如下:

 package com.xysj.mybatis.mapper

 import com.xysj.mybatis.User

 public interface UserMapper {
public User selectUser(long telephone)
public void insertUser(User user)
...
}

UserMapper只是一个接口类,那它的具体实现,即操作数据库的SQL语句在哪里呢?我们可以通过xml文件来进行配置,即具体的实现都写在xml文件当中。所以我们可以在整个工程的src目录下,创建一个UserMapper.xml的文件,文件的具体内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xysj.mybatis.mapper.UserMapper"> <select id="selectUser" resultType="user">
select * from wkzf where telephone = #{telephone}
</select> <insert id="insertUser" parameterType="user">
insert into wkzf values(#{telephone},#{starttime})
</insert> </mapper>

需要注意的有几点:1)namespace后面填写的是包名+接口类名,一定不能错,错了,不像java有异常机制,可以捕捉异常,xml配置错了,很难发现,所以一定要小心!2)id后面的名字对应UserMapper.java中函数名,不能错!3)可能有人会疑问,为什么这里是“user”而不是“User”,我们定义的类是User啊,稍安勿躁,后面还有一个mybatis-configure.xml文件配置时,会对user进行说明,简单来说就是把User用了一个别名user。4)其他就是注意一些格式要求,#{}代表参数,对应着user中定义的变量。

ok,现在对mybatis-configure.xml文件进行说明,代码如下:

 <?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"> <configuration> <!-- Register Alias -->
<typeAliases>
<typeAlias alias="user" type="com.xysj.mybatis.entity.User" />
</typeAliases> <!-- Register Mapper -->
<mappers>
<!-- SQL Mapper -->
<mapper resource="UserMapper.xml" />
</mappers> </configuration>

可以看到,我们对User取了一个别名user,这样就不需要把User的包名全部都写上了。同时,我们还关联了上面刚刚定义的UserMapper.xml文件。如果是单独的使用mybatis,用不到spring框架,这个xml文件中还应该声明DataSource的相关信息,好让mybatis知道与那个数据库连接。不过有了spring之后,这部分可以在spring-configure.xml文件中声明。

接下来我们先创建一个包com.xysj.service,然后在包下创建一个UserService的类,代码如下:

 package com.xysj.service;

 import com.xysj.mybatis.entity.User;
import org.mybatis.spring.SqlSessionTemplate; public class UserService {
private SqlSessionTemplate sqlSession; public SqlSessionTemplate getSqlSession() {
return sqlSession;
} public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
} public UserInfo selectUser(long telephone) {
User user = null;
try {
user = (User) sqlSession.selectOne("com.xysj.mybatis.mapper.UserMapper.selectUser", telephone);
} catch (Exception e) {
e.printStackTrace();
} return user;
}
}

注意selectOne中的函数第一个参数,一定要写完整!包名+接口名+函数名。之前,我这边没怎么搞懂,代码老是出错,我调试了很久才搞定!当然,这里只写了一个函数,你可以自己写insertUser、updateUser等函数,都是类似的。

spring

好了,现在我们开始配置spring-configure.xml文件,这个非常关键,一点也不能错,代码如下:

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
default-autowire="byName"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:SID" />
<property name="username" value="xxxx" />
<property name="password" value="xxxx" />
<property name="maxActive" value="100"></property>
<property name="maxIdle" value="30"></property>
<property name="maxWait" value="500"></property>
<property name="defaultAutoCommit" value="true"></property>
</bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="mybatis-configure.xml"></property>
<property name="dataSource" ref="dataSource" />
</bean> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean> <bean id="userService" class="com.xysj.service.UserService">
<property name="sqlSession" ref="sqlSessionTemplate" />
</bean> </beans>

需要注意的有几点:1)关于数据源的配置,因为用到了dbcp数据库连接池,所以需要相应的库(commons-dbcp-1.2.jar和commons-pool-1.4.jar ),localhost代表本机,如果你是远程连接到某一个数据库服务器上,则写服务器的IP地址,1521是端口号,SID是数据库名,记住是数据库名,不是表名!2)configLocation后面的value值填写正确,是mybatis的xml配置文件。3)最后一个bean,即“userService”后面的class处写正确,包名+类名。差不多要注意就是这几点,可能还有遗漏的,等到发现了再说。

mina

因为我们只是调用第三方的短信发送平台,所以我们只需要写一个客户端就行,不需要写服务端。总共有4个文件,我们可以先创建一个包:com.xysj.mina。第一个文件ClientHandle.java:

 package com.xysj.mina;

 import ...

 public class ClientHandle extends IoHandlerAdapter {
private final static Log log = LogFactory.getLog(ClientHandle.class); @Override
public void messageReceived(IoSession session, Object message) throws Exception {
log.debug("客户端收到消息" + message.toString());
super.messageReceived(session, message);
} @Override
public void messageSent(IoSession session, Object message) throws Exception {
log.debug("客户端发送消息" + message.toString());
super.messageSent(session, message);
} @Override
exceptionCaught
sessiogCreated
sessionOpened
sessionClosed
sessionIdle
}

因为我们公司是在云桌面开发的,所有的代码和开发环境都在思杰的云桌面上,没有办法拷贝下来,所以只能手打,错误在所难免啊~我也没有办法,import后面的内容省略了,一般你敲完代码,eclipse会提示需要import哪些类,一些重载的函数我也省略了,函数里的内容基本上都差不多,除了一些参数不一样。还有网上搜一下,也能找到这些函数的实现,这里我就不一一敲了。都是手工敲的,难免会有一些代码会敲错,如果出错,请大家指出来哈!第二个文件CodeFactory.java:

 package com.xysj.mina;

 import ...

 public class CodeFactory implements ProtocolCodecFactory {
private XmlDecoder xmldecoder = null;
private XmlEncoder xmlencoder = null; public CodeFactory() {
this(Charset.defaultCharset());
} public codeFactory(Charset charset) {
this.xmldecoder = new XmlDecoder(charset);
this.xmlencoder = new XmlEncoder(charset);
} @Override
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return xmldecoder
} @Override
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return xmlencoder
}
}

从字面意思不难发现,一个是编码,一个是解码,当你把消息发送出去前(即调用messageSent函数前),需要先编码。当你收到消息及messageReceived响应时,会先进行解码。所以接下来就是对这两部分分别进行实现,网上也有响应的代码,也可以参考,老实说mian这部分我也不是很清楚,正如我前面所说的,我只是先搭建了这么一个框架,然后把代码调通,以后有时间,再慢慢深入了解这些框架。好了,首先是XmlDecoder.java:

 package com.xysj.mina;

 import ...

 public class XmlDecoder extends CumulativeProtocolDecoder {
private final static Log log = LogFactory.getLog(XmlDecoder.class);
private final Charset charset; public XmlDecoder(Charset charset) {
this.charset = charset;
} @Override
protected boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
CharsetDecoder decoder = charset.newDecoder();
IoBuffer ioBuffer = IoBuffer.allocate(3072).setAutoExpand(true);
log.info(“开始解码”); byte[] b = new byte[in.limit()];
in.get(b); Charset charset = Charset.forName("GBK");
ByteBuffer buf = ByteBuffer.wrap(b);
CharBuffer cbuf = charset.decoder(buf);
log.debug("客户端收到消息" + cbuf.toString()); while(in.hasRemaining()) {
byte bte = in.get();
ioBuffer.put(bte);
if(bte == '\n') {
ioBuffer.flip();
byte[] bt = new byte[ioBuffer.limit()];
ioBuffer.get(bt);
String message = new String(bt, decoder.charset());
ioBuffer = IoBuffer.allocate(100).setAutoExpand(true)limit
out.write(message);
}
}
return true;
}
}

有了解码的,还有编码的XmlEncode.java:

 package com.xysj.mina;

 import ...

 public class XmlEncoder extends ProtocolEncoderAdapter {

     private final Charset charset;

     public XmlEncoder(Charset charset) {
this.charset = charset;
} @Override
protected void encode(IoSession session, Object obj,
ProtocolEncoderOutput out) throws Exception {
CharsetEncoder encoder = charset.newEncoder();
IoBuffer io = IoBuffer.allocate(100).setAutoExpand(true); io.putString(obj.toString(), encoder);
io.put((byte)'\r');
io.put((byte)'\n');
io.flip();
out.write(io);
}
}

好了,关于mina的四个文件都已经写好了,关键是编码和解码的实现,感觉这是要按照相同的格式才行。如果要配置mina的服务器的话,还需要创建响应的xml配置文件,大家自己上网搜找。我们这里只涉及客户端的代码。

logback

日志框架,这个一句话说明就行了,相信大家看上面的代码看到这一行代码:private final static Log log = LogFactory.getLog(类名.class)。然后,在函数中,只要加上log.info()或者log.debug()就可以生成相应的日志。当然,生成的日志放在哪里,日志是什么样的格式,日志的名字等等信息都需要在logback的xml配置文件中声明,logback.xml文件如下:

 <?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="/log" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender> <!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

logback的配置文件,我直接从网上拷贝下来的,参考的网址是:http://www.cnblogs.com/warking/p/5710303.html。我的云桌面上的配置文件跟这个差不多,一行一行敲下来肯定不现实,所以直接从网上找了一个类似的。有些地方可以自己改一改,比如日志生成的路径啊,日志名字啊等等,还是很容易理解的。

OK,终于到最后了!是不是感觉这些框架配置起来挺麻烦的,一点错误都不能有,一旦xml中出错,查找起来还比较麻烦,因为没有报错机制啊,也不能设置断点一行一行查看,所有细心非常重要!接下来我们需要写一个测试类,用来测试上面所有的框架。简单点,就test.java:

test的目的是调用上面框架,代码也不少,一个一个敲实在是太麻烦,所以就贴图片了,格式会比较乱,但也没有办法。OK,到此,关于这个框架的搭建就差不多了。最后想说的是,后面的路还很长,我还是一个java初学者,需要努力加油!

日志

1.2017.9.11正式发布第一版本

spring+mybatis+mina+logback框架搭建的更多相关文章

  1. Spring+Mybatis+SpringMVC+Maven+MySql搭建实例

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了如何使用Maven来搭建Spring+Mybatis+SpringMVC+M ...

  2. 【转】Spring+Mybatis+SpringMVC+Maven+MySql搭建实例

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了如何使用Maven来搭建Spring+Mybatis+SpringMVC+M ...

  3. freemarker + spring mvc + spring + mybatis + mysql + maven项目搭建

    今天说说搭建项目,使用freemarker + spring mvc + spring + mybatis + mysql + maven搭建web项目. 先假设您已经配置好eclipse的maven ...

  4. [Java] Spring boot 的 SrpingSecurity 框架搭建

    参考: SrpingSecurity]之一:框架搭建https://blog.csdn.net/qq_28296925/article/details/82021092 [SpringSecurity ...

  5. Spring mybatis 之-ssm框架环境搭建(方案一)

    SSM框架- S-Spring  S-Spring mvc M-mybatis  就需要以下几个配置文件,放在resources文件夹下面: db.properties 放的是数据库连接池的配置文件, ...

  6. JAVA之Mybatis基础入门--框架搭建与简单查询

    JAVA中,操作数据库有JDBC.hibernate.Mybatis等技术,今天整理了下,来讲一讲下Mybatis.也为自己整理下文档: hibernate是一个完全的ORM框架,是完全面向对象的.但 ...

  7. springmvc+mybatis+maven项目框架搭建

    项目的目录

  8. springboot+mybatis+druid+atomikos框架搭建及测试

    前言 因为最近公司项目升级,需要将外网数据库的信息导入到内网数据库内.于是找了一些springboot多数据源的文章来看,同时也亲自动手实践.可是过程中也踩了不少的坑,主要原因是我看的文章大部分都是s ...

  9. 160719、Spring + Dubbo + zookeeper (linux) 框架搭建

    转载一篇博客,写得不错(至少我参考一下搭建成功了) 转载地址:http://my.oschina.net/wangt10/blog/522799 dubbo简介 节点角色说明: Provider: 暴 ...

随机推荐

  1. 头像修改功能 包含ios旋转图片 但是旋转后没遮罩, 正常图片可以显示遮罩 宽高不规则图片没做控制 遮罩框可以拖动

    https://blog.csdn.net/wk767113154/article/details/77989544  参考资料 <template> <div id="p ...

  2. 详解MySQL数据表类型

    学习Mysql数据库,Mysql表类型都有哪些是一定需要知道的,下面就为您介绍七种Mysql表类型,希望能对您学习Mysql表类型有所帮助. MySQL作为当前最为流行的免费数据库服务引擎,已经风靡了 ...

  3. js 生成随机颜色

    var getRandomColor = function(){ return '#'+(Math.random()*0xffffff<<0).toString(16); } <&l ...

  4. Linux下SVN server 的使用及权限配置

    [Linux下SVN server 的使用及权限配置] 参考:http://www.cnblogs.com/heinoc/p/3805779.html

  5. Android无法访问本地服务器(localhost/127.0.0.1)的解决方案

    [Android无法访问本地服务器(localhost/127.0.0.1)的解决方案] 在Android开发中通过localhost或127.0.0.1访问本地服务器时,会报Java.NET.Con ...

  6. app.use

    [app.use] app.use([path,] function [, function...]) Mounting a middleware at a path will cause the m ...

  7. unity中Android环境变量配置

    http://www.cnblogs.com/windytrees/p/7533477.html

  8. Redis 总结

    Redis官网下载地址: https://redis.io/ Redis 客户端可视化:https://redisdesktop.com/download 一.Redis 是什么? 1.key-val ...

  9. dedecms迁站

    1  后台>系统>备份数据库 2  下载“所有(强调一下是所有:包括整站程序与备份的数据)”原站的数据,整个站点 3  将下载下来的所有数据上传到新空间 4  删除install目录下的i ...

  10. centos 7.3+nginx+jira(.bin)+mysql

    JIRA 安装参考资料 http://www.cnblogs.com/ilanni/p/6200875.html 注意服务启动与关闭 service jira stop service jira st ...