Mybatis运用mapper代码实现和Spring的整合(一)

来源:互联网 发布:mysql数据库视频教程 编辑:程序博客网 时间:2024/05/16 02:24

引言


先前做的java项目中一直使用的EclipseLink和Hibernate,两种ORM框架,现在用Mybatis实现,当然它们之间各有各的优点,同样也有缺点,有时候,一个项目中是可以存在两种框架一起使用的,在项目中,技术选型很重要。Mybatis是一个持久层的框架,是apache下的顶级项目,mybatis让程序将主要的精力放在sql上,通过mybatis提供的映射方式,自由灵活生成。


Mybatis的主要是靠sql语句来进行实现对数据库持久化的,这就是mybatis的硬伤,当然,它也因为是靠sql语句进行实现,很灵活但不好维护。


画了一张简单的思维导图,咱们按照图进行说明:




mybatis的框架:


我们现在说一个Mybatis的框架,当然能用图说明,我们尽量不要使用文字:



对于图的说明:数据库链接的初期,只要使用时就会创建,不适用立刻释放,对数据库进行很频繁链接开启和关闭,造成数据库资源浪费,影响了数据库的性能。因此我们需要使用数据库连接池进行管理数据库的连接。这里我们需要使用sqlSessionFactory会话工厂进行管理。另外我们将sql语句硬编码到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护,这里我们使用了将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行编译了。另外,我们向proparedStatement中设置参数,对战位富豪位置和设置参数,也要放到xml文件中。从另外我们总是从resultSet中便利结果集数据,不利于系统维护,因此,我们将查询的结果集,自动映射成java对象。


简单的流程:


由于篇幅有限,我们直接在Spring整合工程中提到。


与spring的整合:


这里我们使用的是Mapper代理的形式,将我们所有的Mybatis的mapper代理放在SqlSessionFactory中进行管理,另外,将SqlSessionFactory嫁给Spring容器管理。具体:通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。通过SqlSessionFactory创建sqlSession,通过单利模式管理SqlSessionFactory,交给Spring来进行管理。

我们整合的思路是,需要spring通过单例方式管理SqlSessionFactory,spring和mybatis整合生成代理对象,使用SQLSessionFactory创建SqlSession。(spring和mybatis整合自动完成)持久层的mapper需要由spring进行管理。


整合代码:

1、jar包



2、创建配置文件


首先看我们的目录结构:



mybatis下面的配置SqlMapConfig.xml


<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 别名定义 --><typeAliases><!-- 批量别名定义 指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以) --><package name="com.tgb.ncre.po" /></typeAliases><!-- 加载 映射文件 --><mappers><!--1、 可以一个一个的添加 --><!--<mapper resource="sqlmap/User.xml" />  --><!--2、建议使用, 批量加载mapper 指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中 上边规范的前提是:使用的是mapper代理方法 和spring整合后,使用mapper扫描器,这里不需要配置了 --> <package name="com.tgb.ncre.mapper"/>  </mappers></configuration></span>

db.properties文件:


<span style="font-size:18px;">jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/mybatisjdbc.username=rootjdbc.password=root</span>

添加log4j.properties文件:


<span style="font-size:18px;"># Global logging configuration#\u5728\u5f00\u53d1\u73af\u5883\u4e0b\u65e5\u5fd7\u7ea7\u522b\u8981\u8bbe\u7f6e\u6210DEBUG\uff0c\u751f\u4ea7\u73af\u5883\u8bbe\u7f6e\u6210info\u6216errorlog4j.rootLogger=DEBUG, stdout# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n</span>

sqlmap文件夹下我们暂时不用。是用dao直接注入SqlSessionFactory的时候,才用到的,我们这里用到的是在mapper中直接添加xml文件的。


下面是最重要的spring的applicationContext.xml文件,我们在这个文件下进行注入SqlSession的。


<span style="font-size:18px;"><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop" 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.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "><!-- 加载配置文件 --><context:property-placeholder location="classpath:db.properties" /><!-- 数据源,使用dbcp --><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /><property name="maxActive" value="10" /><property name="maxIdle" value="5" /></bean><!-- sqlSessinFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 加载mybatis的配置文件 --><property name="configLocation" value="mybatis/SqlMapConfig.xml" /><!-- 数据源 --><property name="dataSource" ref="dataSource" /></bean><!-- 原始dao接口 --> <bean id="userDao" class="com.tgb.ncre.dao.UserDaoImpl"><property name="sqlSessionFactory" ref="sqlSessionFactory"/></bean> <!-- mapper配置 MapperFactoryBean:根据mapper接口生成代理对象-->  <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"><!--mapperInterface指定mapper接口 --><property name="mapperInterface" value="com.tgb.ncre.mapper.UserMapper"/><property name="sqlSessionFactory" ref="sqlSessionFactory"/></bean>   <!-- mapper批量扫描,从mapper包中扫描出mapper接口,自动创建代理对象并且在spring容器中注册 遵循规范:将mapper.java和mapper.xml映射文件名称保持一致,且在一个目录 中自动扫描出来的mapper的bean的id为mapper类名(首字母小写)-->   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><!-- 指定扫描的包名 如果扫描多个包,每个包中间使用半角逗号分隔 --><property name="basePackage" value="com.tgb.ncre.mapper"/><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/></bean>    </beans></span>



配置文件就建好了,是这样的:





我们现在创建src文件中,我们的pojo的java兑现个,和mapper代理。

我们先看src的文件目录:




User类:


<span style="font-size:18px;">package cn.itcast.ssm.po;import java.io.Serializable;import java.util.Date;import java.util.List;public class User implements Serializable {//属性名和数据库表的字段对应private int id;private String username;// 用户姓名private String sex;// 性别private Date birthday;// 生日private String address;// 地址//用户创建的订单列表private List<Orders> ordersList;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + ", sex=" + sex+ ", birthday=" + birthday + ", address=" + address + "]";}public List<Orders> getOrdersList() {return ordersList;}public void setOrdersList(List<Orders> ordersList) {this.ordersList = ordersList;}}</span>

order类:


<span style="font-size:18px;">package com.tgb.ncre.po;import java.util.Date;import java.util.List;public class Orders {    private Integer id;    private Integer userId;    private String number;    private Date createtime;    private String note;        //用户信息    private User user;        //订单明细    private List<Orderdetail> orderdetails;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public Integer getUserId() {        return userId;    }    public void setUserId(Integer userId) {        this.userId = userId;    }    public String getNumber() {        return number;    }    public void setNumber(String number) {        this.number = number == null ? null : number.trim();    }    public Date getCreatetime() {        return createtime;    }    public void setCreatetime(Date createtime) {        this.createtime = createtime;    }    public String getNote() {        return note;    }    public void setNote(String note) {        this.note = note == null ? null : note.trim();    }public User getUser() {return user;}public void setUser(User user) {this.user = user;}public List<Orderdetail> getOrderdetails() {return orderdetails;}public void setOrderdetails(List<Orderdetail> orderdetails) {this.orderdetails = orderdetails;}}</span>

Orderdetail类:


<span style="font-size:18px;">package com.tgb.ncre.po;public class Orderdetail {    private Integer id;    private Integer ordersId;    private Integer itemsId;    private Integer itemsNum;        //明细对应的商品信�?    private Items items;        public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public Integer getOrdersId() {        return ordersId;    }    public void setOrdersId(Integer ordersId) {        this.ordersId = ordersId;    }    public Integer getItemsId() {        return itemsId;    }    public void setItemsId(Integer itemsId) {        this.itemsId = itemsId;    }    public Integer getItemsNum() {        return itemsNum;    }    public void setItemsNum(Integer itemsNum) {        this.itemsNum = itemsNum;    }public Items getItems() {return items;}public void setItems(Items items) {this.items = items;}@Overridepublic String toString() {return "Orderdetail [id=" + id + ", ordersId=" + ordersId+ ", itemsId=" + itemsId + ", itemsNum=" + itemsNum + "]";}    }</span>

Items类:


<span style="font-size:18px;">package com.tgb.ncre.po;import java.util.Date;public class Items {    private Integer id;    private String name;    private Float price;    private String pic;    private Date createtime;    private String detail;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name == null ? null : name.trim();    }    public Float getPrice() {        return price;    }    public void setPrice(Float price) {        this.price = price;    }    public String getPic() {        return pic;    }    public void setPic(String pic) {        this.pic = pic == null ? null : pic.trim();    }    public Date getCreatetime() {        return createtime;    }    public void setCreatetime(Date createtime) {        this.createtime = createtime;    }    public String getDetail() {        return detail;    }    public void setDetail(String detail) {        this.detail = detail == null ? null : detail.trim();    }}</span>

然后,我们看com.tgb.ncre.mapper:


Usermapper.java


<span style="font-size:18px;">package com.tgb.ncre.mapper;import static org.junit.Assert.*;import com.tgb.ncre.po.User;public interface UserMapper {//根据id查询用户信息public User findUserById(int id) throws Exception;}</span>

UserMapper.xml:


<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址-->                <mapper namespace="com.tgb.ncre.mapper.UserMapper"><select id="findUserById" parameterType="int" resultType="user">SELECT * FROM USER WHERE id=#{value}</select></mapper></span>

注意:大家一定要这里的两个mapper包中的java类和xml的名称一定要相同才行,否则,在applicationContext.xml中创建SqlSession的时候,扫描不到所有的文件。


好了,现在我们就进行test:


右击我们的UserMapper.java,选择“New”——“Others”:




之后,我们写代码:


<span style="font-size:18px;">package com.tgb.ncre.mapper;import org.junit.Before;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.tgb.ncre.po.User;public class UserMapperTest {private ApplicationContext applicationContext;@Beforepublic void setUp() throws Exception {applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");}@Testpublic void testFindUserById() throws Exception {UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");User user = userMapper.findUserById(1);System.out.println(user);}}</span>

Ok了,运行,JunitTest:


总结:


我们在研究持久层的框架的时候,要从多方面考虑,当我们学习Mybatis的时候,就要想有没有其他的ORM框架,拿出来进行比较。这样,我们才能很好地做技术选型,另外,之后,我们在学习Mybatis的时候,还要想到,如何才能一步一步优化。














1 0
原创粉丝点击