MyBatis学习(五)
Spring和MyBaits整合
1、整合思路
- 需要spring通过单例方式管理SqlSessionFactory。
- spring和mybatis整合生成代理对象,使用SqlSessionFactory创建SqlSession。(spring和mybatis整合自动完成)
- 持久层的mapper都需要由spring进行管理。
2、整合环境
- mybatis-3.4.6的jar包,下载地址:https://github.com/mybatis/mybatis-3/releases
- spring-4.3.9的jar包,下载链接:https://files.cnblogs.com/files/AmyZheng/lib.rar
- mybatis和spring的整合包mybatis-spring-1.3.2.jar:早期ibatis和spring整合是由spring官方提供,mybatis和spring整合由mybatis提供。下载地址:http://mvnrepository.com/artifact/org.mybatis/mybatis-spring
3、SqlSessionFactory
- 在applicationContext.xml配置sqlSessionFactory和数据源
- sqlSessionFactory在mybatis和spring的整合包下。
<?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:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <!-- 加载配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties" /> <!-- 数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean> <!-- sqlSessinFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载mybatis的配置文件 -->
<property name="configLocation" value="ecut/spring/mybaits-config.xml" />
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
4、原始dao开发(和spring整合后)
- 映射文件RoleMapper.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"> <!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用 -->
<mapper namespace="ecut.spring.mapper.RoleMapper"> <select id="getRole" parameterType="java.lang.Integer"
resultType="Role">
SELECT id , role_name as roleName , note FROM t_role WHERE id = #{value}
</select> </mapper> - 配置文件mybaits-config.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>
<typeAlias type="ecut.spring.po.Role" alias="Role"/>
</typeAliases>
<!-- 加载 映射文件 -->
<mappers> <!--通过resource方法一次加载一个映射文件 -->
<mapper resource="ecut/spring/mapper/Role.xml"/>
</mappers> </configuration> - 接口dao
package ecut.spring.dao; import ecut.spring.po.Role; public interface RoleDao { //根据id获取角色
public Role getRole(Integer id) throws Exception ; } - 接口dao实现类(继承SqlSessionDaoSupport)
package ecut.spring.dao; import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport; import ecut.spring.po.Role; public class RoleDaoImpl extends SqlSessionDaoSupport implements RoleDao{
// SqlSessionDaoSupport有方法setSqlSessionFactory @Override
public Role getRole(Integer id) throws Exception {
//继承SqlSessionDaoSupport,通过this.getSqlSession()得到sqlSessoin
SqlSession session =this.getSqlSession();
//执行查询操作
Role role = session.selectOne("test.getRole", id);
// Spring 管理资源,使用完会自动关闭,释放资源
return role;
} }让RoleDaoImpl实现类继承SqlSessionDaoSupport,因为 SqlSessionDaoSupport有方法setSqlSessionFactory()方法,因此在applicationContext中使用提供setter方法进行注入,setter方法依赖于无参构造和setter方法,且在创建factory时候只需读取配置文件,因此在bean中需要配置configLocation属性。SqlSessionFactory通过Spring的配置文件注入,再由spring和mybatis整合自动完成SqlSessionFactory创建SqlSession。在接口实现类中通过this.getSqlSession()的方法获取到session完成操作。
<!-- sqlSessinFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载mybatis的配置文件 -->
<property name="configLocation" value="ecut/spring/mybaits-config.xml" />
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
</bean> - 配置dao
<!-- 原始dao接口 --> <bean id="roleDao" class="ecut.spring.dao.RoleDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>在applicationContext.xml中配置dao。dao接口实现类需要注入SqlSessoinFactory,通过spring进行注入。
- 测试类
package ecut.spring.test; import java.io.IOException; import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import ecut.spring.dao.RoleDao;
import ecut.spring.po.Role; public class RoleDaoImplTest { private AbstractApplicationContext container; private RoleDao roleDao; @Before
public void init() throws IOException {
// 指定configuration metadata配置元数据
String configLocations = "classpath:ecut/**/spring/applicationContext.xml";
// 创建spring IOC容器
container = new ClassPathXmlApplicationContext(configLocations);
roleDao = (RoleDao) container.getBean("roleDao", RoleDao.class);
} @Test
public void testGetRole() throws Exception {
// 从容器中获取的bean实例中获取属性值
Role role = roleDao.getRole(1);
System.out.println(role); } @After
public void destroy(){
// 关闭spring的IOC容器
container.close();
}
}
5、mapper代理开发
- mapper类
package ecut.spring.mapper; import ecut.spring.po.Role; public interface RoleMapper { //根据id获取角色
public Role getRole(Integer id) throws Exception ; } - mapper配置文件
<?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有特殊重要的作用 -->
<mapper namespace="ecut.spring.mapper.RoleMapper"> <select id="getRole" parameterType="java.lang.Integer"
resultType="Role">
SELECT id , role_name as roleName , note FROM t_role WHERE id = #{value}
</select> </mapper> - 通过MapperFactoryBean创建代理对象
<!-- mapper配置
MapperFactoryBean:根据mapper接口生成代理对象
-->
<bean id="roleMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!-- mapperInterface指定mapper接口 -->
<property name="mapperInterface" value=" ecut.spring.mapper.RoleMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>不整合之前是要通过session去创建RoleMapper对象,再由mybaits自动生成的mapper代理对象
SqlSession session = factory.openSession();
//创建RoleMapper对象,mybaits自动生成的mapper代理对象
RoleMapper roleMapper = session.getMapper(RoleMapper.class);通过MapperFactoryBean创建代理对象存在的问题:需要针对每个mapper进行配置,麻烦。
- 通过MapperScannerConfigurer进行mapper扫描(建议使用)
<!-- mapper批量扫描,从mapper包中扫描出mapper接口,自动创建代理对象并且在spring容器中注册
遵循规范:将mapper.java和mapper.xml映射文件名称保持一致,且在一个目录 中
自动扫描出来的mapper的bean的id为mapper类名(首字母小写)
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定扫描的包名
如果扫描多个包,每个包中间使用半角逗号分隔 -->
<property name="basePackage" value="ecut.spring.mapper"/>
<!-- 不能使用 name="sqlSessionFactory" 会使数据源配置后执行-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>若mapper 的名称是TRoleMapper自动扫描出来的mapper的bean的id为TRoleMapper而不是首字母小写tRoleMapper。可以根据日志来确定bean的id是多少,如RoleMapper的日志为DEBUG [main] - Creating shared instance of singleton bean 'roleMapper',则可以知道RoleMapper的id是roleMapper。
- 测试类
package ecut.spring.test; import java.io.IOException; import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import ecut.spring.mapper.RoleMapper;
import ecut.spring.po.Role; public class RoleMapperTest { private AbstractApplicationContext container;
private RoleMapper roleMapper; @Before
public void init() throws IOException {
// 指定configuration metadata配置元数据
String configLocations = "classpath:ecut/**/spring/applicationContext.xml";
// 创建spring IOC容器
container = new ClassPathXmlApplicationContext(configLocations);
roleMapper = (RoleMapper) container.getBean("roleMapper", RoleMapper.class);
} @Test
public void testGetRole() throws Exception {
// 从容器中获取的bean实例中获取属性值
Role role = roleMapper.getRole(1);
System.out.println(role); } @After
public void destroy(){
// 关闭spring的IOC容器
container.close();
}
}
逆向工程
1、什么是逆向工程
- mybaits需要程序员自己编写sql语句,mybatis官方提供逆向工程 可以针对单表自动生成mybatis执行所需要的代码(mapper.java,mapper.xml、po..)
- 企业实际开发中,常用的逆向工程方式:由于数据库的表生成java代码。
2、环境配置
jar包下载地址:http://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core/1.3.7
3、使用方法
- 运行逆向工程

建议使用java程序方式,不依赖开发工具。
- 生成代码的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test" userId="root"
password="123456">
</jdbcConnection> <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver> <!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="ecut.reverse.po"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="ecut.reverse.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="ecut.reverse.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="t_dubber"></table>
<table tableName="t_comic"></table>
<table tableName="t_role"></table> <!-- 有些表的字段需要指定java类型
<table schema="" tableName="">
<columnOverride column="" javaType="" />
</table> -->
</context>
</generatorConfiguration>参照地址http://www.mybatis.org/generator/configreference/xmlconfig.html进行逆向工程配置文件配置
- 执行生成程序
package ecut.reverse; import java.io.File;
import java.util.ArrayList;
import java.util.List; import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback; public class GeneratorSqlmap { public void generator() throws Exception{ List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//指定 逆向工程配置文件
File configFile = new File("./src/generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null); }
public static void main(String[] args) throws Exception {
try {
GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
generatorSqlmap.generator();
} catch (Exception e) {
e.printStackTrace();
} } }参照地址http://www.mybatis.org/generator/configreference/xmlconfig.html,运行后生成代码如下

测试类
package ecut.reverse.test; import java.io.IOException;
import java.util.List; import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import ecut.reverse.mapper.TRoleMapper;
import ecut.reverse.po.TRole;
import ecut.reverse.po.TRoleExample; public class RoleTest { private AbstractApplicationContext container; private TRoleMapper roleMapper; @Before
public void init() throws IOException {
// 指定configuration metadata配置元数据
String configLocations = "classpath:ecut/**/reverse/applicationContext.xml";
// 创建spring IOC容器
container = new ClassPathXmlApplicationContext(configLocations);
// 从容器中获取的bean实例中获取属性值
roleMapper = (TRoleMapper) container.getBean("TRoleMapper", TRoleMapper.class);
} //根据主键删除
@Test
public void testDeleteByPrimaryKey() {
roleMapper.deleteByPrimaryKey(8);
} //插入
@Test
public void testInsert() {
//构造 角色对象
TRole role = new TRole();
role.setRoleName("路飞");
role.setNote("海贼王");
role.setComicId(2);
roleMapper.insert(role);
} //自定义条件查询
@Test
public void testSelectByExample() {
TRoleExample roleExample = new TRoleExample();
//通过criteria构造查询条件
TRoleExample.Criteria criteria = roleExample.createCriteria();
criteria.andComicIdEqualTo(2);
criteria.andIdGreaterThanOrEqualTo(2);
//可能返回多条记录
List<TRole> list = roleMapper.selectByExample(roleExample); for(TRole r:list){
System.out.println("id="+r.getId()+",roleName="+r.getRoleName()+",note="+r.getNote()+",comicId="+r.getComicId());
}
} //根据主键查询
@Test
public void testSelectByPrimaryKey() {
TRole role = roleMapper.selectByPrimaryKey(1);
System.out.println("id="+role.getId()+",roleName="+role.getRoleName()+",note="+role.getNote()+",comicId="+role.getComicId());
} //更新数据
@Test
public void testUpdateByPrimaryKey() { //对所有字段进行更新,需要先查询出来再更新
TRole role = roleMapper.selectByPrimaryKey(8); role.setComicId(3);;
//没有非空判断
roleMapper.updateByPrimaryKey(role);
//如果传入字段不空为才更新,在批量更新中使用此方法,不需要先查询再更新
//roleMapper.updateByPrimaryKeySelective(record); } @After
public void destroy(){
// 关闭spring的IOC容器
container.close();
} }mapper 的名称是TRoleMapper自动扫描出来的mapper的bean的id为TRoleMapper而不是首字母小写tRoleMapper。可以根据日志来确定bean的id是多少,如TRoleMapper的日志为DEBUG [main] - Creating shared instance of singleton bean 'TRoleMapper',则可以知道TRoleMapper的id是TRoleMapper。
MyBaits视频及资料
转载请于明显处标明出处
https://www.cnblogs.com/AmyZheng/p/9385887.html
MyBatis学习(五)的更多相关文章
- mybatis 学习五 二级缓存不推荐使用
mybatis 二级缓存不推荐使用 一 mybatis的缓存使用. 大体就是首先根据你的sqlid,参数的信息自己算出一个key值,然后你查询的时候,会先把这个key值去缓存中找看有没有value,如 ...
- mybatis学习五 log4j
1. log4j(log for java)由 apache 推出的开源免费日志处理的类库.2. 为什么需要日志: 2.1 在项目中编写 System.out.println();输出到控制台,当项 ...
- mybatis 学习五 动态SQL语句
3.1 selectKey 标签 在insert语句中,在Oracle经常使用序列.在MySQL中使用函数来自动生成插入表的主键,而且需要方法能返回这个生成主键.使用myBatis的selectKey ...
- mybatis学习 (五) POJO的映射文件
Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心. 1.parameterType(输入类型) 通过parameterType ...
- mybatis学习笔记(五):mybatis 逆向工程
mybatis学习笔记(五):mybatis 逆向工程 在日常开发中,如果数据库中存在多张表,自己手动创建 多个pojo 类和编写 SQL 语法配置文件,未免太过繁琐,mybatis 也提供了一键式生 ...
- (转)MyBatis框架的学习(五)——一对一关联映射和一对多关联映射
http://blog.csdn.net/yerenyuan_pku/article/details/71894172 在实际开发中我们不可能只是对单表进行操作,必然要操作多表,本文就来讲解多表操作中 ...
- mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(附demo和搭建过程遇到的问题解决方法)
文章介绍结构一览 一.使用maven创建web项目 1.新建maven项目 2.修改jre版本 3.修改Project Facts,生成WebContent文件夾 4.将WebContent下的两个文 ...
- (原创)mybatis学习二,spring和mybatis的融合
mybatis学习一夯实基础 上文介绍了mybatis的相关知识,这一节主要来介绍mybaits和spring的融合 一,环境搭建 1,jar包下载,下载路径为jar包 2,将包导入到java工程中 ...
- 【MyBatis学习笔记】
[MyBatis学习笔记]系列之预备篇一:ant的下载与安装 [MyBatis学习笔记]系列之预备篇二:ant入门示例 [MyBatis学习笔记]系列之一:MyBatis入门示例 [MyBatis学习 ...
- Mybatis学习笔记二
本篇内容,紧接上一篇内容Mybatis学习笔记一 输入映射和输出映射 传递简单类型和pojo类型上篇已介绍过,下面介绍一下包装类型. 传递pojo包装对象 开发中通过可以使用pojo传递查询条件.查询 ...
随机推荐
- CSP2019第一轮游记
Day -1 发现还有\(2\)天就初赛了\((?)\) 赶紧复习\(ing\) 然后基础知识基本上都不知道 后面的大题--全靠蒙 感觉第一轮就要\(\mathrm{AFO}\)啊\(QwQ\) Da ...
- C. Grid game 思维+问题转化
C. Grid game 思维+问题转化 题意 每当有一行或者一列方格的时候,都可以消气这一行或者这一列,一共有两种形状的方块,一种是横的两个,一种是竖着的两个,按时间顺序放在4*4的格子里面,问怎么 ...
- 磁盘分区(1):fdisk和parted
一.Linux存储管理 关于Linux硬盘的识别: (1)如果是IDE设备,在计算机中将被识别为hd,第一个IDE设备会被识别为hda,第二个IDE设备会被识别为hdb,依此类推. (2)如果是SAT ...
- 【做题笔记】P1330 封锁阳光大学
读题易得:对于有边的两个点 \(u,v\) ,能且仅能其中一点对这条边进行封锁. 什么意思呢?假设给这张图上的点进行染色,那么对于上述的两个点 \(u,v\) ,\(u,v\) 必须异色(理解这一点很 ...
- Java学习笔记(八)面向对象---抽象类
当多个类中出现相同功能,但是功能主体不同时,我们可以向上抽取,只抽取功能定义,而不抽取功能主体. 抽象类的特点 抽象方法一定在抽象类中. 抽象方法和抽象类都必须被abstract关键字修饰. 抽象类不 ...
- MyBatis(2)——增删改查
增删改查: 1.在实体类的映射文件中增加insert.update.delete标签与数据库语句,例如 <!-- 会去获取到对应的实体类的getter方法 --> <insert i ...
- js判断非127开头的IP地址
js验证回送地址,IP地址不能以127开头 回送地址(127.x.x.x)是本机回送地址(Loopback Address) var ipNotStartWith127 = function(ip) ...
- c语言thread用法记录。
https://blog.csdn.net/hitwengqi/article/details/8015646 先是c++11之前的 1.最基础,进程同时创建5个线程,各自调用同一个函数 #inclu ...
- map文章
STL map常用操作简介 http://www.kuqin.com/cpluspluslib/20071231/3264.html STL中map用法详解 http://www.kuqin.com/ ...
- 【安卓逆向】反编译ELF的另类技巧
IDA 反编译 ObjDump反编译 ObjDump是ndk环境自带的一个脚本,在android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebu ...