spring-jdbc+mybatis实现示例 【README】特别注意SqlSessionFactory是依赖SqlSessionFactoryBean创建业务Mapper是依赖MapperFactoryBean创建所以若要研究spring整合mybaits的源码需要从SqlSessionFactoryBeanMapperFactoryBean入手【1】spring-jdbc开发例子【1.1】定义防腐层supportpublic interface IUserSupport { void save(UserPO userPO); ListUserPO getUsers(); } public class UserSupportImpl implements IUserSupport { private JdbcTemplate jdbcTemplate; public UserSupportImpl(DataSource dataSource) { this.jdbcTemplate new JdbcTemplate(dataSource); } Override public void save(UserPO userPO) { String userId String.valueOf(System.currentTimeMillis()); jdbcTemplate.update(insert into spring_user_tbl(id, name, age, sex) values(?,?,?,?), new Object[]{userId, userPO.getName(), userPO.getAge(), userPO.getSex()} , new int[]{Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.VARCHAR}); } Override public ListUserPO getUsers() { ListUserPO list jdbcTemplate.query(select * from spring_user_tbl, new UserRowMapper()); return list; } }【1.2】定义dao层【UserPO】Data NoArgsConstructor public class UserPO { private String id; private String name; private int age; private String sex; public UserPO(String name, int age, String sex) { this.name name; this.age age; this.sex sex; } public UserPO(String id, String name, int age, String sex) { this.id id; this.name name; this.age age; this.sex sex; } }【UserRowMapper】public class UserRowMapper implements RowMapper { Override public Object mapRow(ResultSet rs, int rowNum) throws SQLException { UserPO person new UserPO(rs.getString(id), rs.getString(name), rs.getInt(age), rs.getString(sex)); return person; } }【1.3】spring-beans.xml?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:aophttp://www.springframework.org/schema/aop xmlns:contexthttp://www.springframework.org/schema/context xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/aop/spring-context-3.0.xsd bean iddataSource classorg.apache.commons.dbcp2.BasicDataSource destroy-methodclose property namedriverClassName valuecom.mysql.cj.jdbc.Driver / property nameurl valuejdbc:mysql://localhost:3306/myspring / property nameusername valueroot / property namepassword valuerootroot / property nameinitialSize value2 / property namemaxIdle value2 / property nameminIdle value1 / /bean bean iduserService classcom.tom.srccode.deep.analysis.chapter8.springjdbc.UserSupportImpl constructor-arg refdataSource/ /bean /beans【1.4】测试用例Slf4j public class SpringJdbcMain { public static void main(String[] args) { ApplicationContext applicationContext new ClassPathXmlApplicationContext(/a_src_deep_analysis/chapter08/beans0801.xml); UserSupportImpl userSupport applicationContext.getBean(userService, UserSupportImpl.class); UserPO userPO new UserPO(lisi, 14, 男); userSupport.save(userPO); // 查询数据 ListUserPO users userSupport.getUsers(); users.forEach(System.out::println); } }【打印结果】org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext3930015a org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 2 bean definitions from class path resource [a_src_deep_analysis/chapter08/beans0801.xml] org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean dataSource org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean userService org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL update org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [insert into spring_user_tbl(id, name, age, sex) values(?,?,?,?)] org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource org.springframework.jdbc.core.JdbcTemplate - Executing SQL query [select * from spring_user_tbl] org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource UserPO(id1001, namezhangsan, age10, sex男) UserPO(id1782651335094, namezhangsan, age10, sex男) UserPO(id1782651354529, namezhangsan, age10, sex男) UserPO(id1782651362859, namezhangsan, age10, sex男) UserPO(id1783116902846, namelisi, age14, sex男) UserPO(id3, name张三03, age33, sex男)【2】spring-mybaits开发例子【2.1】定义dao层Data NoArgsConstructor public class UserPO { private String id; private String name; private int age; private String sex; public UserPO(String name, int age, String sex) { this.name name; this.age age; this.sex sex; } public UserPO(String id, String name, int age, String sex) { this.id id; this.name name; this.age age; this.sex sex; } } // UserMapper public interface UserMapper { void insertUser(UserPO user); UserPO getUser(String id); }【2.2】定义Mybatis工具Slf4j public class MybatisUtils { Getter private final static SqlSessionFactory sqlSessionFactory; static { String resource a_src_deep_analysis/chapter9/mybatis-config.xml; Reader reader null; try { reader Resources.getResourceAsReader(resource); } catch (Exception e) { log.error(读取 mybatis-config.xml文件异常, e); } sqlSessionFactory new SqlSessionFactoryBuilder().build(reader); } }【2.2.1】mybaits-config.xml?xml version1.0 encodingUTF-8 ? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN https://mybatis.org/dtd/mybatis-3-config.dtd configuration settings setting namecacheEnabled valuetrue/ setting namedefaultExecutorType valueSIMPLE/ /settings typeAliases typeAlias aliasUserPO typecom.tom.srccode.deep.analysis.chapter9.UserPO / /typeAliases environments defaultdevelopment environment iddevelopment transactionManager typejdbc / dataSource typePOOLED property namedriver valuecom.mysql.cj.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/myspring/ property nameusername valueroot/ property namepassword valuerootroot/ /dataSource /environment /environments mappers mapper resourcea_src_deep_analysis/chapter9/UserMapper.xml / /mappers /configuration【2.2.2】UserMapper?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN https://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.tom.srccode.deep.analysis.chapter9.UserMapper insert idinsertUser parameterTypeUserPO INSERT INTO spring_user_tbl (id, name, age, sex) VALUES(#{id}, #{name}, #{age}, #{sex}) /insert select idgetUser resultTypeUserPO parameterTypestring select * from spring_user_tbl where id#{id} /select /mapper【2.3】测试用例public class Chapter9UnitTest { static SqlSessionFactory sqlSessionFactory MybatisUtils.getSqlSessionFactory(); Test public void testAdd() { SqlSession sqlSession sqlSessionFactory.openSession(); try { UserMapper mapper sqlSession.getMapper(UserMapper.class); UserPO userPO new UserPO(4, 张三04, 44, 男); mapper.insertUser(userPO); sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); } finally { sqlSession.close(); } } Test public void testGet() { SqlSession sqlSession sqlSessionFactory.openSession(); try { UserMapper mapper sqlSession.getMapper(UserMapper.class); UserPO userPO mapper.getUser(4); log.info(userPO {}, userPO); } catch (Exception e) { sqlSession.rollback(); } finally { sqlSession.close(); } } }【2.3.1】测试新增DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using class org.apache.ibatis.logging.slf4j.Slf4jImpl adapter. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Created connection 836969741. DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl31e3250d] DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.insertUser - Preparing: INSERT INTO spring_user_tbl (id, name, age, sex) VALUES(?, ?, ?, ?) DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.insertUser - Parameters: 4(String), 张三04(String), 44(Integer), 男(String) DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.insertUser - Updates: 1 DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl31e3250d] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl31e3250d] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl31e3250d] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 836969741 to pool.【2.3.2】测试查询DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using class org.apache.ibatis.logging.slf4j.Slf4jImpl adapter. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Created connection 1220759559. DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl48c35007] DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.getUser - Preparing: select * from spring_user_tbl where id? DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.getUser - Parameters: 4(String) DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.getUser - Total: 1 INFO com.tom.srccode.deep.analysis.chapter9.Chapter9UnitTest - userPO UserPO(id4, name张三04, age44, sex男) DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl48c35007] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl48c35007] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 1220759559 to pool.【2.4】spring与mybatis整合例子【2.4.1】spring与mybatis整合配置xml【spring-mybatis-beans.xml】配置了SqlSessionFactoryBean用于注入SqlSessionFactory配置了 MapperFactoryBean用于注入 业务Mapper如UserMapper?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd bean iddataSource classorg.apache.commons.dbcp2.BasicDataSource destroy-methodclose property namedriverClassName valuecom.mysql.cj.jdbc.Driver / property nameurl valuejdbc:mysql://localhost:3306/myspring / property nameusername valueroot / property namepassword valuerootroot / property nameinitialSize value2 / property namemaxIdle value2 / property nameminIdle value1 / /bean bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property nameconfigLocation valueclasspath:a_src_deep_analysis/chapter9/mybatis-config.xml/ property namedataSource refdataSource/ /bean bean iduserMapper classorg.mybatis.spring.mapper.MapperFactoryBean property namemapperInterface valuecom.tom.srccode.deep.analysis.chapter9.UserMapper / property namesqlSessionFactory refsqlSessionFactory / /bean /beans【spring-mybatis-config.xml 】?xml version1.0 encodingUTF-8 ? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN https://mybatis.org/dtd/mybatis-3-config.dtd configuration settings setting namecacheEnabled valuetrue/ setting namedefaultExecutorType valueSIMPLE/ /settings typeAliases typeAlias aliasUserPO typecom.tom.srccode.deep.analysis.chapter9.UserPO / /typeAliases mappers mapper resourcea_src_deep_analysis/chapter9/UserMapper.xml / /mappers /configuration【2.4.2】测试用例Slf4j public class SpringMybatisIntegrateUnitTest { Test public void test() { ApplicationContext context new ClassPathXmlApplicationContext(a_src_deep_analysis/chapter9/spring-mybatis-beans.xml); UserMapper userMapper context.getBean(UserMapper.class); log.info(user {}, userMapper.getUser(3)); } }【2.4.3】打印结果DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext1e4a7dd4 DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 3 bean definitions from class path resource [a_src_deep_analysis/chapter9/spring-mybatis-beans.xml] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean dataSource DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean sqlSessionFactory DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using class org.apache.ibatis.logging.slf4j.Slf4jImpl adapter. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.mybatis.spring.SqlSessionFactoryBean - Parsed configuration file: class path resource [a_src_deep_analysis/chapter9/mybatis-config.xml] DEBUG org.mybatis.spring.SqlSessionFactoryBean - Property mapperLocations was not specified. DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean userMapper DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession DEBUG org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession6f2cb653] was not registered for synchronization because synchronization is not active DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource [Finalizer] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. DEBUG org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [858727880, URLjdbc:mysql://localhost:3306/myspring, MySQL Connector/J] will not be managed by Spring DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.getUser - Preparing: select * from spring_user_tbl where id? DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.getUser - Parameters: 3(String) DEBUG com.tom.srccode.deep.analysis.chapter9.UserMapper.getUser - Total: 1 DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession6f2cb653] INFO com.tom.srccode.deep.analysis.chapter9.SpringMybatisIntegrateUnitTest - user UserPO(id3, name张三03, age33, sex男)