在进行完spring与springmvc整合之后, 继续 spring与mybatis的整合.

既然是操作数据库, 那必然不能缺少了连接属性

一. db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

二. application.xml

将前一篇注释的部分, 再注释回来就行了, 是一个import操作

三. spring和mybatis的整合xml文件: spring-mybatis.xml

<?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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 自动搜索bean -->
<!-- <context:annotation-config/>--> <!-- 自动扫描 -->
<!--<context:component-scan base-package="org.elvin.ssm" />--> <!-- 引入配置文件 -->
<context:property-placeholder location="classpath:conf/db.properties" /> <!--配置数据库连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!--driverClassName会自动识别, 可以不配置-->
<property name="driverClassName" value="${jdbc.driver}" /> <!-- 配置初始化大小、最小、最大 -->
<!--
initialSize:初始化时建立物理连接的个数, 默认为0
minIdle:最小连接池数量
maxActive:最大连接池数量, 默认为8
-->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" /> <!--获取连接时最大等待时间,单位ms-->
<property name="maxWait" value="60000" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" /> <!--
validationQuery:用来检测连接是否有效的sql
testWhileIdle:建议配置为true,默认false, 不影响性能,并且保证安全性,申请连接的时候检测,如果空闲时间大于
timeBetweenEvictionRunsMillis, 执行validationQuery检测连接是否有效。
testOnBorrow:申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。默认true
testOnReturn:归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
-->
<property name="validationQuery" value="SELECT 1 " />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" /> <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<!--<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />--> <!-- 监控统计用的filter:stat
日志用的filter:log4j
防御sql注入的filter:wall -->
<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
<property name="filters" value="stat" />
</bean> <!-- mybatis 的工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:conf/mybatis.xml"/>
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mapper/**/*.xml" />
</bean> <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.elvin.ssm.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean> <!-- 配置事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 注解方式配置事物 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager" /> --> <!-- 拦截器方式配置事物 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" isolation="REPEATABLE_READ" read-only="true" />
<tx:method name="find*" isolation="REPEATABLE_READ" read-only="true" />
<tx:method name="search*" isolation="REPEATABLE_READ" read-only="true" />
<tx:method name="load*" isolation="REPEATABLE_READ" read-only="true" /> <tx:method name="*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
</tx:attributes>
</tx:advice> <aop:config>
<aop:pointcut id="pointCut" expression="execution(* org.elvin.ssm.service..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut" />
</aop:config>
</beans>

四. mybatis本身也可以有一个对自己的配置文件. mybatis.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>
<typeAliases>
<package name="org.elvin.ssm.pojo" />
</typeAliases>
</configuration>

如果没有什么特别的配置, 这里也可以不写, 这个文件也可以不要, 但是要在spring-mybatis.xml文件中删除  configLocation 的配置

五. 加入日志文件 log4j.properties

log4j.rootLogger=DEBUG,Console,FILE
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
#File Appender
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.File=C:/soft/logs/SSM.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[%d{HH:mm:ss,SSS}] [%l] [%t] [%-5p] : %m%n log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=INFO
log4j.logger.java.sql.Statement=INFO
log4j.logger.java.sql.PreparedStatement=INFO

然后需要在web.xml文件中加入配置

    <!-- 加载log4j的配置文件log4j.properties -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>
classpath:conf/log4j.properties
</param-value>
</context-param>
<!-- 设定刷新日志配置文件的时间间隔,这里设置为10s -->
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>10000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

六. 后台代码

在mapper文件夹下, 加入一个mapper文件. BookMapper.java

package org.elvin.ssm.mapper;

import org.elvin.ssm.pojo.Book;

import java.util.List;

/**
* author: Elvin
* datetime: 2017/12/2 8:21
* description:
*/
public interface BookMapper { /**
* 根据id查询实体数据
* @param id
* @return
*/
public Book find(Integer id); /**
* 获取数据库中所有的数据
* @return
*/
public List<Book> getAll(); /**
* 新增
* @param book
* @return
*/
public Integer insert(Book book); /**
* 修改
* @param book
*/
public void update(Book book); /**
* 删除
* @param id
*/
public void remove(Integer id);
}

这个文件是一个接口文件, 这里不需要我们手动去实现这个接口, 只需要在resources/mapper文件夹下, 加入对应的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="org.elvin.ssm.mapper.BookMapper"> <select id="find" parameterType="java.lang.Integer" resultType="org.elvin.ssm.pojo.Book">
select * from book where id=#{id}
</select> <select id="getAll" resultType="org.elvin.ssm.pojo.Book">
select * from book
</select> <insert id="insert" parameterType="org.elvin.ssm.pojo.Book" >
insert into book(name, price, publishTime) values(#{name}, #{price}, #{publishTime})
</insert> <update id="update" parameterType="org.elvin.ssm.pojo.Book">
update book set name=#{name}, price=#{price}, publishTime=#{publishTime} where id=#{id]}
</update> <delete id="remove" parameterType="java.lang.Integer">
delete from book where id=#{id}
</delete> </mapper>

这样, dao中的部分, 就完成了. 接下来, 完成service中的部分

package org.elvin.ssm.service;

import org.elvin.ssm.pojo.Book;

import java.util.List;

public interface BookService {
/**
* 根据id查询实体数据
* @param id
* @return
*/
public Book find(Integer id); /**
* 获取数据库中所有的数据
* @return
*/
public List<Book> getAll(); /**
* 新增
* @param book
* @return
*/
public Integer insert(Book book); /**
* 修改
* @param book
*/
public void update(Book book); /**
* 删除
* @param id
*/
public void remove(Integer id);
}

其实现类:

package org.elvin.ssm.serviceimpl;

import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.fastjson.JSON;
import org.elvin.ssm.mapper.BookMapper;
import org.elvin.ssm.pojo.Book;
import org.elvin.ssm.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.List; /**
* author: Elvin
* datetime: 2017/12/2 8:26
* description:
*/
@Service("bookService")
public class BookServiceImpl implements BookService { Log logger = LogFactory.getLog(BookServiceImpl.class); @Autowired
private BookMapper bookMapper; /**
* 根据id查询实体数据
* @param id
* @return
*/
public Book find(Integer id){
logger.info("find book : " + id);
return bookMapper.find(id);
} /**
* 获取数据库中所有的数据
* @return
*/
public List<Book> getAll(){
logger.info("getAll book");
return bookMapper.getAll();
} /**
* 新增
* @param book
* @return
*/
public Integer insert(Book book){
logger.info("insert book : " + JSON.toJSONString(book));
return bookMapper.insert(book);
} /**
* 修改
* @param book
*/
public void update(Book book){
logger.info("update book : " + JSON.toJSONString(book));
bookMapper.update(book);
} /**
* 删除
* @param id
*/
public void remove(Integer id){
logger.info("remove book : " + id);
bookMapper.remove(id);
}
}

controller中, 新建一个控制器, 来验证一下程序是否能正常运行

package org.elvin.ssm.controller;

import org.elvin.ssm.pojo.Book;
import org.elvin.ssm.pojo.ResModel;
import org.elvin.ssm.service.BookService;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*; import java.util.*; /**
* author: Elvin
* datetime: 2017/11/29 20:06
* description:
*/
@Controller
@RequestMapping("hello")
public class HelloController { @Autowired
private BookService bookService; @RequestMapping("index")
public String index(ModelMap model){ List<Book> bookList = bookService.getAll(); model.put("bookList", bookList); return "index";
} @RequestMapping(value = "book/{id}", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public Book book(@PathVariable("id") Integer id){
Book b = bookService.find(id);
return b;
} @RequestMapping(value = "get", method = RequestMethod.POST)
public @ResponseBody Map<String, Object> getData(@RequestParam("id") Integer id){
Map<String, Object> map = new HashMap<>();
map.put("name", "hahhha");
map.put("age", 20);
return map;
} @GetMapping("addData")
@ResponseBody
public ResModel addData(){
ResModel resObj = new ResModel("新增数据失败", 0, null);
try{
List<Book> list = getBookList();
list.forEach(n->{
bookService.insert(n);
});
resObj.setMsg("新增成功");
resObj.setCode(1);
}
catch (Exception e){
System.out.println(e.getMessage()); }
return resObj;
} //region private method
private List<Book> getBookList(){
List<Book> bookList = new ArrayList<>();
String[] nameStrs = {"吴", "一", "雪", "动", "额", "阿", "前", "里", "排"};
Random r = new Random();
String timeStr = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
for (int i = 0; i < 10 ; i++){
Book b = new Book();
b.setId(i+1);
b.setName(nameStrs[r.nextInt(5)] + nameStrs[r.nextInt(9)]);
b.setPublishTime(timeStr);
b.setPrice(r.nextInt(100));
bookList.add(b);
}
return bookList;
}
//endregion
}

这里我做了一个Json数据返回的规范实体

package org.elvin.ssm.pojo;

/**
* author: Elvin
* datetime: 2017/12/2 13:19
* description:
*/
public class ResModel {
private String msg; private Integer code; private Object resObj; public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} public Integer getCode() {
return code;
} public void setCode(Integer code) {
this.code = code;
} public Object getResObj() {
return resObj;
} public void setResObj(Object resObj) {
this.resObj = resObj;
} public ResModel(String msg, Integer code, Object resObj) {
this.msg = msg;
this.code = code;
this.resObj = resObj;
}
}

七. 验证

1. 加数据到数据库中

这里的价格和时间, 我在数据库中用的是 int 和 varchar 类型的.  在实际使用中, 价格不要使用decimal去存储, 看需求, 如果money不是很大, 可以用int, 如果大, 则使用long来存储. 这样能保证数据的精确性. 而对于时间类型, 使用字符串类型去处理, 其实完全是可以的, 并且在实际使用中, 我觉得更方便.

有了数据之后, 可以来查询一下

最新文章

  1. 5.2视图中的Order by
  2. ProgressBar.js – 漂亮的响应式 SVG 进度条
  3. C#分布式缓存Couchbase使用
  4. 关于mysql备份说明
  5. c#中获取服务器IP,客户端IP以及其它
  6. hadoop浅尝 hadoop与hbase交互
  7. QTP安装和破解
  8. ubuntu mint 15 编译安装PHP开发环境
  9. WAMP集成环境
  10. Qt中如何 编写插件 加载插件 卸载插件
  11. flex中在basewidget中不能使用图表组件问题
  12. PS中模式算法
  13. 是男人就下100层【第四层】——Crazy贪吃蛇(1)
  14. 使用assets目录来实现插件机制
  15. ng-show,ng-if区别
  16. Oracle数据库常用SQL函数
  17. 关于Android studio的安装和配置问题
  18. 安装LIBXML2
  19. Node入门教程(9)第七章:NodeJs的文件处理
  20. [机器学习&amp;数据挖掘]机器学习实战决策树plotTree函数完全解析

热门文章

  1. POJ2385--Apple Catching(动态规划)
  2. web-day4
  3. 当Windows Phone遇到Windows 8
  4. 第83讲:Scala中List的实现内幕源码揭秘
  5. Pyenv 安装部署
  6. hdu 4975 最大流快版
  7. delphi CopyFileProgressBar 拷贝文件显示进度条
  8. ASP.NET Core 2.1 源码学习之 Options[3]:IOptionsMonitor
  9. .NET 证书加密 存储保存 IIS授权
  10. 【vue】项目编译报错‘npm ERR! **@**dev: `webpack-dev-server --inline --progress --config ’’