SSM整合(2): spring 与 mybatis 整合

来源:互联网 发布:vue.js修改data 编辑:程序博客网 时间:2024/05/17 09:42

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

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

一. db.properties

jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8jdbc.username=rootjdbc.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  #Consolelog4j.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 Appenderlog4j.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来存储. 这样能保证数据的精确性. 而对于时间类型, 使用字符串类型去处理, 其实完全是可以的, 并且在实际使用中, 我觉得更方便. 

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

 

原创粉丝点击