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

引言

先前做的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 configuration
PUBLIC "-//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.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.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\u6216error
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.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;
	}
	@Override
	public 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;
	}

	@Override
	public 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 mapper
PUBLIC "-//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;

	@Before
	public void setUp() throws Exception {
		applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
	}

	@Test
	public 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的时候,还要想到,如何才能一步一步优化。

时间: 2024-10-05 04:45:10

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

spring整合mybatis之mapper开发

1.1    整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象. 4.数据库的连接以及数据库连接池事务管理都交给spring容器来完成. 1.2   整合需要的jar包 1.spring的jar包 2.Mybatis的jar包 3.Spring+mybatis的整合包. 4.Mysql的

Spring Boot 整合mybatis时遇到的mapper接口不能注入的问题

现实情况是这样的,因为在练习spring boot整合mybatis,所以自己新建了个项目做测试,可是在idea里面mapper接口注入报错,后来百度查询了下,把idea的注入等级设置为了warning,至于怎末设置可以自行百度,这里不再赘述,但是接下来spring boot能够运行起来,但是通过浏览器访问的时候,就会报错,后来也是经过多方查询,发现了问题的原因,特此记录一下: spring  boot整合mybatis时,要将mapper装配到spring容器中,要在mapper接口中加上@M

spring boot集成MyBatis 通用Mapper 使用总结

spring boot集成MyBatis 通用Mapper 使用总结 2019年 参考资料: Spring boot集成 MyBatis 通用Mapper SpringBoot框架之通用mapper插件(tk.mybatis) spring boot 如何优雅的使用mybatis-spring-boot-starter 三分钟让你看懂Springboot 中 Mybatis 的使用 Spring Boot 集成MyBatis__动力节点 ===================== end 原文地

MyBatis入门(六)---mybatis与spring的整合

一.整合需要 1.1.方法 上一章中的数据 需要spring通过单例方式管理SqlSessionFactory spring和mybatis整合生成代理对象,使用SqlSessionFactory创建SqlSession (spring和mybatis整合自动完成) 持久层的mapper都需要由spring进行管理 二.创建项目整合环境 2.1.创建项目 2.2.数据 db.properties #数据库配置信息 #驱动 driverClass=com.mysql.jdbc.Driver #连接

【Struts2】如何实现Struts2与Spring的整合 外加 MyBatis 框架

1,简介 一般没有人会用Spring+Struts2+MyBatis这样的框架了,可不能简称为SSM.因为SSM是Spring+SpringMVC+Mybatis的简称.SSH是Spring+Struts2+Hibernate,不过现在SSH用的人也不多了.这里笔者把Sping+Struts2+Mybatis放在一起就是纯粹的实现一下功能.主要讨论的还是Struts2和Spring. 如果不使用Spring框架,Struts2框架内部还是有机制可以利用反射创建对象,之所以要把Spring+Str

Mybatis通用Mapper

转:http://blog.csdn.net/isea533/article/details/41457529 极其方便的使用Mybatis单表的增删改查 项目地址:http://git.oschina.net/free/Mapper 优点? 不客气的说,使用这个通用Mapper甚至能改变你对Mybatis单表基础操作不方便的想法,使用它你能简单的使用单表的增删改查,包含动态的增删改查. 程序使用拦截器实现具体的执行Sql,完全使用原生的Mybatis进行操作. 你还在因为数据库表变动重新生成x

由“单独搭建Mybatis”到“Mybatis与Spring的整合/集成”

在J2EE领域,Hibernate与Mybatis是大家常用的持久层框架,它们各有特点,在持久层框架中处于领导地位. 本文主要介绍Mybatis(对于较小型的系统,特别是报表较多的系统,个人偏向Mybatis),对于它,个人比较喜欢的是: 使用简单.方便: 支持的XML动态SQL的编写,方便浏览.修改,同时降低SQL与应用程序之间的耦合. 不喜欢的是: 出现错误时,调试不太方便 本文主要介绍Mybatis的搭建,是学习Mybatis过程后整理的札记,其中包括“单独搭建Mybaits”和常用的“M

Mybatis使用Mapper方式CURD

Mybatis 使用Dao代码方式进行增.删.改.查和分页查询. 1.Maven的pom.xml 2.配置文件 2.1.db.properties 2.2.mybatis.xml 1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http

Mybatis使用Dao代码方式CURD

Mybatis 使用Dao代码方式进行增.删.改.查. 1.Maven的pom.xml 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.or