Mybatis和其他主流框架的整合使用
MyBatis历史
-
MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下,iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到Github
-
iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBatis提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
MyBatis特性
-
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
-
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
-
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
-
1 <dependencies> 2 <dependency> 3 <groupId>org.mybatis</groupId> 4 <artifactId>mybatis</artifactId> 5 <version>3.5.10</version> 6 </dependency> 7 <dependency> 8 <groupId>mysql</groupId> 9 <artifactId>mysql-connector-java</artifactId> 10 <version>8.0.33</version> 11 </dependency> 12 </dependencies>
要使用Mybatis需要配置Mybatis的核心配置,在resources资源文件夹下创建一个mybatis配置文件(名字随意),并写入配置,配置参考Mybatis官方文档mybatis – MyBatis 3 | 入门
在数据源<dataSource>的配置中,配置好driver,url,username,password
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "https://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <environments default="development"> 7 <environment id="development"> 8 <transactionManager type="JDBC"/> 9 <dataSource type="POOLED"> 10 <property name="driver" value="com.mysql.cj.jdbc.Driver"/> 11 <property name="url" value="jdbc:mysql://localhost:3307/mybatis"/> 12 <property name="username" value="root"/> 13 <property name="password" value="root"/> 14 </dataSource> 15 </environment> 16 </environments> 17 <!--<mappers> 18 <mapper resource="org/mybatis/example/BlogMapper.xml"/> 19 </mappers>--> 20 </configuration>
现在需要一个数据库和表和一些数据用做连接测试
1 CREATE DATABASE IF NOT EXISTS `mybatis` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 2 3 CREATE TABLE USER( 4 `id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT 'ID', 5 `name` VARCHAR(100) COMMENT '姓名', 6 `age` TINYINT UNSIGNED COMMENT '年龄', 7 `gender` TINYINT UNSIGNED COMMENT '性别, 1:男, 2:女', 8 `phone` VARCHAR(11) COMMENT '手机号' 9 ) COMMENT '用户表'; 10 11 INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'白眉鹰王',55,'1','18800000000'); 12 INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'金毛狮王',45,'1','18800000001'); 13 INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'青翼蝠王',38,'1','18800000002'); 14 INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'紫衫龙王',42,'2','18800000003'); 15 INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'光明左使',37,'1','18800000004'); 16 INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'光明右使',48,'1','18800000005');
构建整体项目结构controller、service、mapper三层架构,创建一个实体类对应数据库的表结构,创建MyBatis的映射文件xxxMapper.xml
-
-
表所对应的实体类的类名+Mapper.xml
-
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
-
因此一个映射文件对应一个实体类,对应一张表的操作
-
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
-
在resources文件目录下创建mapper的时候需要和main文件目录下的mapper同包名,在创建directory的时候,目录结构不能使用点,而是用/代替
User实体类中的属性需要和表中的字段名相对应,这里也可以用Lombok注解
然后在mapper中写我们需要的语句,查询语句用<select>、增加语句用<insert>、删除语句用<delete>、修改语句用<update>标签,返回类型resultType要和实体类中的实体类名称对应
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 6 <mapper namespace="mapper.UserMapper"> 7 8 <select id="selectAll" resultType="pojo.User"> 9 SELECT id, name, age, gender, phone FROM user 10 </select> 11 </mapper>
写好了之后回到mybatis-config.xml中配置一下mapper映射
在UserMapper中将UserMapper.xml中配置好的方法声明一下,方法名要和上面的id对应上
在service层写好业务逻辑代码,在接口中声明方法,在实现类中实现方法
1 public class UserServiceImpl implements UserService { 2 3 @Override 4 public List<User> selectAll() throws IOException { 5 //读取MyBatis的核心配置文件 6 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); 7 //获取SqlSessionFactoryBuilder对象 8 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); 9 //通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象 10 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is); 11 //获取sqlSession,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务 12 SqlSession sqlSession = sqlSessionFactory.openSession(); 13 //通过代理模式创建UserMapper接口的代理实现类对象 14 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 15 //调用UserMapper接口中的方法,就可以根据UserMapper的全类名匹配元素文件,通过调用的方法名匹配映射文件中的SQL标签,并执行标签中的SQL语句 16 List<User> users = mapper.selectAll(); 17 return users; 18 } 19 }
在controller层中写好处理结果代码
1 public class UserController { 2 private UserService userService = new UserServiceImpl(); 3 4 public void selectAll() throws IOException { 5 List<User> users = userService.selectAll(); 6 users.forEach(System.out::println); 7 } 8 }
创建一个Test类去测试mybatis数据库连接,因为没有引入单元测试依赖,所以这里用主函数去测试
发现结果成功输出打印
如果SQL语句比较简单,可以使用mybatis中的注解,查询语句用@Select、增加语句用@Insert、删除语句用@Delete、修改语句用@Update注解
在里面写上sql语句,再运行发现,也可以查询成功。
当然,复杂一点的sql语句和动态SQL建议还是使用Mapper配置,只是简单的sql语句写在注解里面可以简化,复杂的sql只会增加代码的复杂度
总结
在Maven项目中,使用mybatis需要先导入mybatis依赖和连接数据库的依赖,然后创建mybatis配置文件,在配置文件中配置数据源细信息,随后创建MyBatis的映射文件Mapper,在mapper文件中写好对应的语句,然后在业务层进行SqlSession连接,调用mapper中的方法,再在controller层处理返回方法。
2、用Spring框架整合Mybatis
1 <dependencies> 2 <dependency> 3 <groupId>org.mybatis</groupId> 4 <artifactId>mybatis</artifactId> 5 <version>3.5.10</version> 6 </dependency> 7 <dependency> 8 <groupId>mysql</groupId> 9 <artifactId>mysql-connector-java</artifactId> 10 <version>8.0.33</version> 11 </dependency> 12 <dependency> 13 <groupId>org.springframework</groupId> 14 <artifactId>spring-context</artifactId> 15 <version>5.3.30</version> 16 </dependency> 17 <dependency> 18 <groupId>com.alibaba</groupId> 19 <artifactId>druid</artifactId> 20 <version>1.2.20</version> 21 </dependency> 22 <dependency> 23 <groupId>org.mybatis</groupId> 24 <artifactId>mybatis-spring</artifactId> 25 <version>1.3.2</version> 26 </dependency> 27 <dependency> 28 <groupId>org.springframework</groupId> 29 <artifactId>spring-jdbc</artifactId> 30 <version>5.3.2</version> 31 </dependency> 32 </dependencies>
构建整体项目结构
2.1、基于XML整合Mybatis
- 导入Mybatis整合Spring的相关坐标
- 编写Mapper和Mapper.xml
- 配置SqlSessionFactoryBean和MapperScannerConfigurer
- 编写测试代码
和上面步骤相同,编写Mapper和Mapper.xml,一定要放在相同路径下
在UserMapper.xml中写我们需要的语句,并在UserMapper接口中写对应id的方法声明;
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 6 <mapper namespace="mapper.UserMapper"> 7 8 <select id="selectAll" resultType="pojo.User"> 9 SELECT id, name, age, gender, phone FROM user 10 </select> 11 </mapper>
public interface UserMapper { List<User> selectAll(); }
同样的,简单的SQL语句也可以用@Select注解编写,不需要UserMapper.xml配置
在Spring配置文件中配置SqlSessionFactoryBean
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 5 6 <!--配置SqlSessionFactoryBean,作用将SqlSessionFactory存储到spring容器--> 7 <bean class="org.mybatis.spring.SqlSessionFactoryBean"> 8 <property name="dataSource" ref="dataSource"></property> 9 </bean> 10 11 <!--配置数据源信息--> 12 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> 13 <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> 14 <property name="url" value="jdbc:mysql://localhost:3307/mybatis"></property> 15 <property name="username" value="root"></property> 16 <property name="password" value="root"></property> 17 </bean> 18 </beans>
对应的是之前配置文件中的
1 <dataSource type="POOLED"> 2 <property name="driver" value="com.mysql.cj.jdbc.Driver"/> 3 <property name="url" value="jdbc:mysql://localhost:3307/mybatis"/> 4 <property name="username" value="root"/> 5 <property name="password" value="root"/> 6 </dataSource>
在Spring配置文件中配置MapperScannerConfigurer
1 <!--MapperScannerConfigurer,作用扫描指定的包,产生Mapper对象存储到Spring容器--> 2 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 3 <property name="basePackage" value="mapper"></property> 4 </bean>
对应的是
1 <mappers> 2 <package name="com.tedu.mapper"/> 3 </mappers>
在Spring配置文件中配置好之后,在使用的时候就不用手动创建了,直接注入即可。
在UserServiceImpl属性中添加UserMapper,并为其添加setter方法用于注入。
1 public class UserServiceImpl implements UserService { 2 private UserMapper userMapper; 3 4 public void setUserMapper(UserMapper userMapper) { 5 this.userMapper = userMapper; 6 } 7 8 @Override 9 public List<User> selectAll() { 10 return userMapper.selectAll(); 11 } 12 }
同样,在UserController属性中添加UserService,并为其添加setter方法用于注入。在selectAll方法中处理返回的结果。
1 public class UserController { 2 private UserService userService; 3 4 public void setUserService(UserService userService) { 5 this.userService = userService; 6 } 7 8 public void selectAll(){ 9 List<User> users = userService.selectAll(); 10 users.forEach(System.out::println); 11 } 12 }
在Spring配置文件中配置上述UserService和UserController用于注入
1 <bean id="userServiceImpl" class="service.impl.UserServiceImpl"> 2 <property name="userMapper" ref="userMapper"></property> 3 </bean> 4 5 <bean id="userContorller" class="controller.UserController"> 6 <property name="userService" ref="userServiceImpl"></property> 7 </bean>
最后创建一个测试类进行数据库连接测试
1 public class TestSelectAll { 2 public static void main(String[] args) { 3 ApplicationContext context = new ClassPathXmlApplicationContext("application.xml"); 4 UserController userController = context.getBean(UserController.class); 5 userController.selectAll(); 6 } 7 }
可以在控制台看到打印的结果
总结
基于XML方式整合Mybatis首先需要创建Spring的配置文件,在XML配置文件中去配置bean,将bean对象交由Spring容器管理,其余的mapper和普通方法一样。需要配置数据源DataSource,配置SqlSessionFactoryBean、配置MapperScannerConfigurer,再配置UserMapper、UserService和UserController。在测试类中用ClassPathXmlApplicationContext和getBean获取到UserContorller对象再调用其方法即可。这种方式不用编写mybatis-config.xml配置文件,在Spring配置文件中全部配置了,虽然简化了部分操作,但是还是较为繁琐,下面讲一种用注解方式整合mybatis。
2.2、基于注解整合Mybatis
导入和上述基于XML整合mybatis方法相同的依赖
再构建同样的项目结构
还需要在resources资源目录下面添加一个配置文件用于存放数据源配置信息
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3307/mybatis
除了像上面方法构建的项目结构之外,还需要一个配置类进行配置
1 @Configuration 2 @ComponentScan("cn.test") 3 @PropertySource("classpath:jdbc.properties") 4 @MapperScan("cn.test.mapper") 5 public class MybatisConfig { 6 7 @Bean 8 public DataSource dataSource( 9 @Value("${jdbc.driver}") String driver, 10 @Value("${jdbc.username}") String username, 11 @Value("${jdbc.password}") String passwrod, 12 @Value("${jdbc.url}") String url 13 ){ 14 DruidDataSource dataSource = new DruidDataSource(); 15 dataSource.setDriverClassName(driver); 16 dataSource.setUsername(username); 17 dataSource.setPassword(passwrod); 18 dataSource.setUrl(url); 19 return dataSource; 20 } 21 22 @Bean 23 public SqlSessionFactoryBean sqlSessionFactoryBean(@Autowired DataSource dataSource){ 24 SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 25 sqlSessionFactoryBean.setDataSource(dataSource); 26 return sqlSessionFactoryBean; 27 } 28 }
@Configuration注解是声明该类是一个配置类
@ComponentScan注解是包扫描,扫描该包和该包的子孙包中的类带有@Component注解的类,交由Spring容器管理
@PropertySource注解是设置资源文件目录,classpath后是properties文件的路径,加载后可以用${}占位符获取properties文件中的属性
@MapperScan注解是设置Mapper文件扫描,相当于mybatis配置文件中<mapper>标签
配置文件中用@Bean注解配置非自定义Bean的配置,在dataSource方法中传入连接数据库四要素并且用@Value注解去注入值,其中用${}占位符获取properties文件中的属性,最后方法返回dataSource,同样的用sqlSessionFactoryBean方法sqlSessionFactoryBean,在参数中用@AutoWried注入dataSource参数,其中@AuroWired注解可省略,最后方法返回sqlSessionFactoryBean。
这样,在Config配置文件中就完成了SqlSessionFactoryBean和MapperScannerConfigurer的配置
接下来就是编写UserMapper和UserMapper.xml文件,这里就不在用XML配置文件进行演示,如需要,上面的其他方法都有演示,这里就用注解的方式编写SQL语句。
随后,编写三层架构的代码,在UserController中,用@AuroWired注解自动注入UserService,并且在类上加上@Controller注解,表示该类是Contriller层类并交由Spring容器管理
1 @Controller 2 public class UserController { 3 @Autowired 4 private UserService userService; 5 6 public void findAll() { 7 List<User> all = userService.findAll(); 8 all.forEach(System.out::println); 9 } 10 }
在UserServiceImpl中用,@AuroWired注解自动注入UserMapper,并且在类上加上@Service注解,表示该类是Service层类并交由Spring容器管理
1 @Service 2 public class UserServiceImpl implements UserService { 3 4 @Autowired 5 private UserMapper userMapper; 6 @Override 7 public List<User> findAll() { 8 return userMapper.findAll(); 9 } 10 }
在UserMapper中,编写SQL方法,用@Select注解编写SQL语句,因为在配置文件中加了@MapperScan("cn.test.mapper")注解,所以在此类上不需要加任何Component注解
1 public interface UserMapper { 2 @Select("SELECT id, name, age, gender, phone FROM user") 3 List<User> findAll(); 4 }
最后,编写测试方法进行数据库连接测试
1 public class TestAnnoMyBatis { 2 public static void main(String[] args) { 3 ApplicationContext context = new AnnotationConfigApplicationContext(MybatisConfig.class); 4 UserController userController = context.getBean(UserController.class); 5 userController.findAll(); 6 } 7 }
在测试方法中用AnnotationConfigApplicationContext方法加载MybatisConfig配置文件,同样在控制台中可以看到成功输出结果
总结
基于注解整合Mybatis方法中,我们不需要配置任何XML文件,其他操作基本相同,只需要新增一个配置文件,在配置文件中用一些注解和方法去完成配置。同时,在管理Bean时,也是用注解去自动装配,交由Spring容器去管理。大大简化了配置。
3、SpringBoot整合Mybatis
用SpringBoot框架整合Mybatis相对就较为简单了
首先创建于一个SpringBoot项目
在勾选依赖的时候,需要勾选MyBatisFarmework依赖和MySql依赖进行数据的连接和Mybatis的使用
创建完成之后在application.properties配置文件中配置数据源
spring.datasource.url=jdbc:mysql://localhost:3307/mybatis?serverTimezone=Asia/Shanghai&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
然后在UserMapper中开始写SQL语句
1 @Mapper 2 public interface UserMapper { 3 4 @Select("SELECT id, name, age, gender, phone FROM user") 5 List<User> userList(); 6 }
一定要在UserMapper类上加上@Mapper注解,@Mapper注解是识别他为mybatis的mapper接口,会自动的把 加@Mapper 注解的接口生成动态代理类。
同样的,在UserService中用@AutoWired对UserMapper进行注入,并在该类上加上@Service注解
1 @Service 2 public class UserServiceImpl implements UserService { 3 @Autowired 4 private UserMapper userMapper; 5 6 public List<User> userList(){ 7 return userMapper.userList(); 8 } 9 }
在UserController中用@AutoWired对UserService进行注入并处理返回的结果,并在该类上加上@Controiller注解
1 @Controller 2 public class UserController { 3 @Autowired 4 private UserService userService; 5 6 public void userList(){ 7 List<User> users = userService.userList(); 8 users.forEach(System.out::println); 9 } 10 }
最后在SpringBoot的测试类中写一个测试方法进行数据库连接的测试
1 @SpringBootTest 2 class SpringBootMybatisApplicationTests { 3 4 @Autowired 5 private UserController userController; 6 @Test 7 public void test(){ 8 userController.userList(); 9 } 10 11 }
可以看到控制台成功输出结果
总结
使用SpringBoot框架整合Mybatis更为简单,只需要在application.properties配置文件中配置数据源四要素就行,随后就可以直接在Mapper中写SQL语句,最后可以在SpringBootTest类中直接进行测试。