什么是MyBatis
简单来说,MyBatis是一个实现了数据库持久化的开源框架,支持三种语言:Java、.Net以及Ruby。当然我们只关心Java的使用,所以可以将MyBatis理解为一个JDBC的封装框架。
我们知道Java开发经常使用到的JDBC封装框架就是Hibernate和MyBtis,那么他们有什么区别和共同点?
MyBatis和Hibernate都是ORM(Object Relational Mapping 对象关系映射)框架。
MyBatis是“半自动化”的ORM实现,这里的半自动化是相对于Hibernate提供的全面数据库封装机制的“全自动化”ORM实现而言,“全自动化”实现了POJO和数据库表之间的映射,以及sql的自动生成和执行。
而MyBatis的关注点,在于POJO和sql之间的映射关系。
MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索。MyBatis可以使用简单的xml或者注解用于配置和原始映射。通过接口将JavaBean映射成数据库中的记录。
MyBatis框架的优点:
- 与JDBC相比,减少了50%的代码量。
- MyBatis是最简单的持久化框架,小巧并且简单易学。
- MyBatis相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在xml中,从程序代码中彻底分离,降低耦合度,便以统一管理和优化,并可重用。
- 提供xml标签,支持编写动态sql语句。
- 提供映射标签,支持对象与数据库的ORM字段关系映射。
MyBatis框架的缺点:
- SQL语句编写工作量大,尤其是字段对、表关联多的时候,对开发人员的SQL语句功底有一定要求。
- 因为都是SQL语句编写,SQL语句依赖数据库,导致移植性比较差,不能随便更换数据库。
MyBatis框架使用场景:
MyBatis专注与SQL本身,是一个足够灵活的DAO层解决方案。对性能要求很高,或者需求变化比较多的项目,如互联网项目,MyBatis是一个不错的选择。
快速入门
1:搭建环境,maven配置MyBatis依赖jar包。
1 <dependency> 2 <groupId>org.mybatis</groupId> 3 <artifactId>mybatis</artifactId> 4 <version>3.4.5</version> 5 </dependency> 6 <dependency> 7 <groupId>mysql</groupId> 8 <artifactId>mysql-connector-java</artifactId> 9 </dependency>
2:新建数据表
1 CREATE TABLE `t_user` ( 2 `id` int(11) NOT NULL DEFAULT '0', 3 `username` varchar(50) DEFAULT NULL, 4 `password` varchar(50) DEFAULT NULL, 5 PRIMARY KEY (`id`) 6 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
3:创建对应的实体类User
1 package com.yulei.mybaits.model; 2 3 /** 4 * 实体类User 5 * @author 码农小菜鸡 6 * 7 */ 8 public class User { 9 10 private int id; 11 private String username; 12 private String password; 13 14 public int getId() { 15 return id; 16 } 17 public void setId(int id) { 18 this.id = id; 19 } 20 public String getUsername() { 21 return username; 22 } 23 public void setUsername(String username) { 24 this.username = username; 25 } 26 public String getPassword() { 27 return password; 28 } 29 public void setPassword(String password) { 30 this.password = password; 31 } 32 33 }
4:添加MyBatis的配置文件config.xml(文件名可自定义)。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 4 <configuration> 5 <environments default="development"> 6 <environment id="development"> 7 <transactionManager type="JDBC"/> 8 <dataSource type="POOLED"> 9 <property name="driver" value="com.mysql.jdbc.Driver"/> 10 <property name="url" value="jdbc:mysql://219.235.1.148:3306/school?characterEncoding=utf-8"/> 11 <property name="username" value="root"/> 12 <property name="password" value="123456"/> 13 </dataSource> 14 </environment> 15 </environments> 16 </configuration>
5:MyBatis开发有两种方式:
- 使用原生接口,Mapper代理实现自定义接口。
(1):创建Mapper文件UserMapper.xml。
出于规范,namespcae通常设置为 包名 + 文件名。
parameterType为参数的数据类型。
resultType为返回值数据类型。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="com.yulei.mybatis.model.mapper.userMapper"> 6 7 <select id="getUserById" parameterType="int" resultType="com.yulei.mybaits.model.User"> 8 select * from t_user where id = #{id} 9 </select> 10 11 </mapper>
(2):在全局配置文件 config.xml 中注册userMapper.xml。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 4 <configuration> 5 <environments default="development"> 6 <environment id="development"> 7 <transactionManager type="JDBC"/> 8 <dataSource type="POOLED"> 9 <property name="driver" value="com.mysql.jdbc.Driver"/> 10 <property name="url" value="jdbc:mysql://219.235.1.148:3306/school?characterEncoding=utf-8"/> 11 <property name="username" value="root"/> 12 <property name="password" value="123456"/> 13 </dataSource> 14 </environment> 15 </environments> 16 17 <mappers> 18 <mapper resource="com.yulei.mybatis.model.mapper.userMapper.xml" /> 19 </mappers> 20 </configuration>
(3):测试类调用原生接口执行SQL语句获取结果。
1 public class Test { 2 3 @org.junit.Test 4 public void TestMyBatis() { 5 String resource = "config.xml"; 6 try { 7 InputStream inputStream = Resources.getResourceAsStream(resource); 8 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 9 SqlSessionFactory sqlSessionFactory = builder.build(inputStream); 10 //获取sqlsession 11 SqlSession session = sqlSessionFactory.openSession(); 12 //调用MyBatis原生接口执行sql 13 //statemt为userMapper.xml多的 namespcae值 + “.” + select标签的id值 14 String statemt = "com.yulei.mybatis.model.mapper.userMapper.getUserById"; 15 User user = session.selectOne(statemt, 1); 16 System.out.println(user); 17 } catch (IOException e) { 18 e.printStackTrace(); 19 } 20 } 21 }
执行结果为:
User{id=1, username='yulei', password='123456'}
- 在实际开发中,我们推荐使用第二种方式:自定义接口,但是不需要实现该接口,通过Mapper代理来实现。
(1):自定义接口
1 public interface UserDao { 2 3 /** 4 * 新增用户 5 * @param user 6 * @return 7 */ 8 public int addUser(User user); 9 10 /** 11 * 删除用户 12 * @param id 13 * @return 14 */ 15 public int deleteUser(int id); 16 17 /** 18 * 修改用户 19 * @param user 20 * @return 21 */ 22 public int updateUser(User user); 23 24 /** 25 * 根据id查找用户 26 * @param id 27 * @return 28 */ 29 public User selectUserById(int id); 30 31 }
(2):创建userDao.xml,定义接口方法对应的SQL语句。
MyBatis会根据规则自动创建UserDao接口实现类的代理对象,规则如下:
1)userDao.xml 中 namespace为接口的全类名。
2)userDao.xml 中 statement 的 id 为接口中对应的方法明。
3)userDao.xml 中 statement 的 parameterType 和接口中对应方法的参数类型一致。
4)userDao.xml 中 statement 的resultTypte 和接口中对应方法的返回值类型一致。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 6 <mapper namespace="com.yulei.mybatis.dao.UserDao"> 7 8 <insert id="addUser" parameterType="com.yulei.mybatis.model.User"> 9 insert into t_user (username, password) values (#{username}, #{password}) 10 </insert> 11 12 <delete id="deleteUser" parameterType="int"> 13 delete from t_user where id = #{id} 14 </delete> 15 16 <update id="updateUser" parameterType="com.yulei.mybatis.model.User"> 17 update t_user set username=#{username}, password=#{password} where id = #{id} 18 </update> 19 20 <select id="getUserById" parameterType="int" resultType="com.yulei.mybatis.model.User"> 21 select * from t_user where id = #{id} 22 </select> 23 24 </mapper>
(3):在config.xml中注册userDao.xml。
(4):测试:
1 public class Test2 { 2 3 @org.junit.Test 4 public void TestMyBatis2() { 5 String resource = "config.xml"; 6 try { 7 InputStream inputStream = Resources.getResourceAsStream(resource); 8 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 9 SqlSessionFactory sqlSessionFactory = builder.build(inputStream); 10 //获取sqlsession 11 SqlSession session = sqlSessionFactory.openSession(); 12 UserDao userDao = session.getMapper(UserDao.class); 13 14 //新增 15 User user = new User(); 16 user.setUsername("yudian"); 17 user.setPassword("111111"); 18 System.out.println(userDao.addUser(user)); 19 session.commit(); 20 21 //删除 22 System.out.println(userDao.deleteUser(2)); 23 session.commit(); 24 25 //修改 26 User user2 = userDao.selectUserById(1); 27 user2.setUsername("yulei222"); 28 userDao.updateUser(user2); 29 session.commit(); 30 31 //查询用户 32 User user3 = userDao.selectUserById(1); 33 System.out.println(user3); 34 35 } catch (IOException e) { 36 e.printStackTrace(); 37 } 38 } 39 40 }