mybatis与spring集成
集成思路:
需要spring来管理数据源信息。
需要spring通过单例方式管理SqlSessionFactory。
使用SqlSessionFactory创建SqlSession。(spring和mybatis整合自动完成)
持久层的mapper都需要由spring进行管理,spring和mybatis整合生成mapper代理对象。
集成步骤:
1、jar包集成;
2、配置文件集成(数据源);
3、SqlSessionFactory集成;
4、Mapper接口集成;
集成架包如下:
Mybatis的jar包(mybatis核心包、依赖包)
Spring的jar包
Spring与mybatis的集成包
数据库驱动包
Dbcp连接池包
Mybatis的SqlMapConfig.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>
<!-- 设置全局参数 -->
<settings>
<!-- lazyLoadingEnabled:延迟加载的开关,默认是false -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- aggressiveLazyLoading:默认为true,一旦为true上面的懒加载开关失效 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- cacheEnabled:二级缓存的总开关 默认是false-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 定义别名 -->
<typeAliases>
<!-- 批量定义别名 -->
<!-- name:指定需要别名定义的包的名称 它的别名就是类名(类名的首字母大小写都可)-->
<package name="cn.java.ssm.po"></package>
</typeAliases>
<!-- 注意:与spring集成后,数据源和事务交给spring来管理 -->
<!-- 加载mapper文件 -->
<mappers>
<mapper resource="mybatis/sqlmap/User.xml"></mapper>
<!-- 批量加载mapper
注意:mapper接口文件和mapper映射文件,名称相同,在同一个包下
-->
<package name="cn.java.mybatis.mapper"/>
</mappers>
</configuration>
Spring的applicationContext.xml
<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 ">
<!-- 引用java配置文件 -->
<context:property-placeholder location="db.properties"/>
<!-- 配置数据源,使用dbcp连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
</bean>
</beans>
Spring对SqlSessionFactory进行管理配置
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- mybatis的配置文件路径 -->
<property name="configLocation" value="sqlMapConfig.xml"></property>
<!-- SqlSessionFactory需要数据源信息,之前是写在sqlmapconfig.xml,现在需要重新指定 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
原始dao方式
public interface UserDao {
// 1、 根据用户ID来查询用户信息;
public User findUserById(int id);
// 2、 根据用户名称来模糊查询用户信息列表;
public List<User> findUsersByName(String name);
// 3、 添加用户;
public void insertUser(User user);
}
编写dao实现类(继承SqlSessionDaoSupport),通过this.getSqlSession()获取sqlsession。
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
@Override
public User findUserById(int id) {
return this.getSqlSession().selectOne("test.findUserById", id);
}
}
编写Mapper映射文件
Spring定义bean
<!-- 由spring管理原始dao的实现 -->
<bean id="userDao" class="cn.java.mybatis.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
编写测试代码
public class UserDaoTest {
//spring上下文
private ApplicationContext ctx;
@Before
public void setUp() throws Exception {
//读取spring的上下文,然后封装到ctx
ctx = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
}
@Test
public void testFindUserById() {
//创建userdao对象
UserDao userDao = (UserDao) ctx.getBean("userDao");
//调用userdao对象的方法
User user = userDao.findUserById(1);
System.out.println(user);
}
}
Mapper代理方式
public interface UserMapper {
// 1、 根据用户ID来查询用户信息
public User findUserById(int id);
}
编写mapper映射文件
Spring定义bean
Mapper代理开发方式有两种bean的定义方法,一种是MapperFactoryBean,一种是MapperScannerConfigurer。
通过MapperFactoryBean创建代理对象
<!-- mapper代理开发方式之单个mapper配置 -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="cn.java.mybatis.mapper.UserMapper"></property>
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
通过MapperScannerConfigurer批量扫描创建代理对象
存在问题:一个mapper定义一个bean,很麻烦。
<!-- mapper代理开发方式之批量mapper配置 -->
<!-- bean的名字默认为mapper接口类名的首字母小写 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定批量mapper配置的包名 -->
<property name="basePackage" value="cn.java.mybatis.mapper"></property>
<!-- 指定使用的SqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
private ApplicationContext ctx;
@Before
public void setUp() throws Exception {
ctx = new ClassPathXmlApplicationContext(
"spring/applicationContext.xml");
}
@Test
public void testFindUserById() {
// 创建mapper对象
UserMapper userMapper = (UserMapper) ctx.getBean("userMapper");
// 调用mapper对象的方法
User user = userMapper.findUserById(1);
System.out.println(user);
}
Mybatis的逆向工程
什么是逆向工程:
简单点说,就是通过数据库中的单表,自动生成java代码。
Mybatis官方提供了逆向工程,可以针对单表自动生成mybatis代码(mapper.java\mapper.xml\po类)
企业开发中,逆向工程是个很常用的工具。
下载逆向工程
https://github.com/mybatis/generator/releases/tag/mybatis-generator-1.3.2
使用方法:
1、创建generator配置文件;
2、使用java类来执行逆向工程;
3、把生成的代码拷贝到项目中。
4、在正式项目中使用逆向工程生成的代码
第一步:创建generator配置文件
在classpath下,创建generator.xml配置文件:
(文件内容可以从逆向工程的jar包中docs目录下的index.html中找到相关代码)
<?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/mybatis" userId="root"
password="mysql">
</jdbcConnection>
<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"
userId="yycg"
password="yycg">
</jdbcConnection> -->
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="cn.java.ssm.po"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="cn.java.ssm.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="cn.java.ssm.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="items"></table>
<table tableName="orders"></table>
<table tableName="orderdetail"></table>
<table tableName="user"></table>
</context>
</generatorConfiguration>
第二步:使用java类来执行逆向工程
public class Generator {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("config/generator.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);
}
}
第三步:把生成的代码拷贝到项目中
如果正式项目中已经有po类所在的包了,那么就只需要拷贝po类到指定包下就可以。
如果正式项目中没有po包,那么就把逆向工程中整个po类的包拷贝过去。
Mapper.xml和mapper.java的拷贝与po类一样。
第四步:使用生成的代码
public class ItemsMapperTest {
// spring上下文
private ApplicationContext ctx;
@Before
public void setUp() throws Exception {
// 读取spring的上下文,然后封装到ctx
ctx = new ClassPathXmlApplicationContext(
"spring/applicationContext.xml");
}
@Test
public void testSelectByExample() {
ItemsMapper mapper = (ItemsMapper) ctx.getBean("itemsMapper");
ItemsExample example = new ItemsExample();
//使用它进行参数封装传递
Criteria criteria = example.createCriteria();
//设置参数
criteria.andNameEqualTo("背包");
List<Items> list = mapper.sele