首先简单说一下为什么使用mybatis,我们上一个项目使用的JDBC,所有的sql语句都是写在java程序中,这样的就会使sql语句与java程序高度耦合,不符合我们的高内聚,低耦合情况,我们只希望你给我一个接口并且返回指定类型的程序,具体如何实现我不管,这样才会更好的进行操作,Hibernate跟mybatis都属于这种情况,hibernate属于全自动框架,mybatis属于半自动框架,什么意思?hibernate对于简单的数据库操作很方便,但是一旦涉及到复杂的数据库操作或者想要对sql语句优化就会很乏力,无法处理,因为sql是内部产生的,mybatis解决了这个问题。我们常听说的sql语句优化,就是这种情景。Mybatis是一款半自动化的持久性框架,他支持定制化sql,存储过程以及高级映射的优秀的持久性框架。
mybatis的入门程序也可以看:https://mybatis.org/mybatis-3/getting-started.html。
首先第一步下载我们所需的jar包,直接去github:https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.5.3,下载最新版的,我这个不知道为啥下载失败,因此使用的是网上中的3.4.6,但都差不多。
如果后续不想要写javabean的get,set方法,可以下载lombok包,同时把junit包加进去,我没有起项目,直接就是一般的java程序,下面截图是主要的代码
首先看一下我们引用的第三方包,者mybatis基础上增加了一个mysql连接包,junit测试包,以及lombok包
首先我们看一下配置文件,SqlMappingConfig.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> <!--这个目前还是需要的,后续spring整合之后,会使用spring的连接池--> <environments default="development"> <environment id="development"> <!--声明使用JDBC的事务管理--> <transactionManager type="JDBC"/> <!--数据库连接吃的配置操作--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="mysql"/> </dataSource> </environment> </environments> <!--指定映射文件,一般这个文件跟我们的映射类放在同一级目录下--> <mappers> <mapper resource="com/yang/domain/Customer.xml"/> </mappers> </configuration>
接下来我们需要定义一个javabean与数据库对应,Customer
package com.yang.domain; import lombok.Getter; import lombok.Setter; // 引用lombok中的get,set方法,自动为我们生成getattr,setattr方法,这个就是数据库的映射表,字段要与数据库一致 //@Getter @Setter // 我这里还是搞上set get方法 public class Customer { private Integer id; private String username; private String job; private String phone; private String email; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "Customer{" + "id=" + id + ", username=‘" + username + ‘\‘‘ + ", job=‘" + job + ‘\‘‘ + ", phone=‘" + phone + ‘\‘‘ + ", email=‘" + email + ‘\‘‘ + ‘}‘; } }
我们在同级目录下定义我们这个customer的映射表,注意resultType不要写成resultMap,我一开始就写错了,mybatis报错也没有定位,有一点错误就会报出来,找了半天错误。。。。。
<?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"> <!--查询映射关系表--> <mapper namespace="myCustomer"> <!--根据id查询--> <select id="queryCustomerById" parameterType="java.lang.Integer" resultType="com.yang.domain.Customer"> SELECT * FROM `customer` WHERE id = #{id} </select> <!--查询所有--> <select id="queryAllCustomer" resultType="com.yang.domain.Customer"> SELECT * FROM `customer` </select> <!--添加--> <insert id="insertCustomer" parameterType="com.yang.domain.Customer"> /*这个获取返回id,并且赋值给我们返回的对象,如果没有这个那么返回的customer对象中id就会为空*/ <selectKey keyColumn="id" keyProperty="id" resultType="Integer" order="AFTER"> select last_insert_id() </selectKey> insert into `customer`(username, job, phone, email) values (#{username}, #{job}, #{phone}, #{email}) </insert> <!--更新--> <update id="updateCustomer" parameterType="com.yang.domain.Customer"> update `customer` set username=#{username} where id=#{id} </update> <!--删除--> <delete id="deleteCustomer" parameterType="com.yang.domain.Customer"> delete from `customer` where id=#{id} </delete> </mapper>
因为我们这个有增删改查,因此在获取操作数据库的session会话做了一个工具类的封装,MyBatisUtil
package com.yang.util; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.InputStream; // 为了方便测试,我们封装一个获取连接对象的工具类 public class MyBatisUtil { // 声明session工厂 public static final SqlSessionFactory sessionFactory; static { // 加载配置文件 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); InputStream inputStream = null; try { // 读取配置文件 inputStream = Resources.getResourceAsStream("SqlMappingConfig.xml"); } catch (Exception e) { e.printStackTrace(); } // 获取session工厂 sessionFactory = sqlSessionFactoryBuilder.build(inputStream); } // 获取连接对象 public static SqlSession openSession() { return sessionFactory.openSession(); } }
最终看一下我们的测试文件
package com.yang.test; import com.yang.domain.Customer; import com.yang.util.MyBatisUtil; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class TestCustomer { // 查询单个用户 @Test public void test() { // 获取session连接对象(会话) SqlSession sqlSession = MyBatisUtil.openSession(); // 执行sql语句,查询查询一条数据使用selectOne Customer customer = sqlSession.selectOne("queryCustomerById", 1); System.out.println(customer); // Customer{id=1, username=‘yang‘, job=‘射手‘, phone=‘13499887733‘, email=‘12341241@qq.com‘} // 完毕之后需要关闭会话 sqlSession.close(); } // 查询所有用户 @Test public void testList() { SqlSession sqlSession = MyBatisUtil.openSession(); List<Customer> customers = sqlSession.selectList("queryAllCustomer"); for (Customer customer : customers) { System.out.println(customer); // Customer{id=1, username=‘yang‘, job=‘射手‘, phone=‘13499887733‘, email=‘12341241@qq.com‘} .... } sqlSession.close(); } // 插入操作 @Test public void insert() { SqlSession sqlSession = MyBatisUtil.openSession(); Customer customer = new Customer(); customer.setUsername("yang"); customer.setPhone("18122222222"); Integer id = sqlSession.insert("insertCustomer", customer); // 当改变数据库时,我们需要手动提交 sqlSession.commit(); System.out.println(customer); // Customer{id=12, username=‘yang‘, job=‘null‘, phone=‘18122222222‘, email=‘null‘} System.out.println(id); // 1 这个是影响的行数,想要id直接去返回的结果集中去拿 sqlSession.close(); } // 更新操作 @Test public void update() { SqlSession sqlSession = MyBatisUtil.openSession(); Customer customer = sqlSession.selectOne("queryCustomerById", 1); customer.setUsername("yang"); System.out.println(customer); // Customer{id=1, username=‘yang‘, job=‘射手‘, phone=‘13499887733‘, email=‘12341241@qq.com‘} sqlSession.update("updateCustomer", customer); System.out.println(customer); // Customer{id=1, username=‘yang‘, job=‘射手‘, phone=‘13499887733‘, email=‘12341241@qq.com‘} sqlSession.commit(); sqlSession.close(); } // 删除 @Test public void delete() { SqlSession sqlSession = MyBatisUtil.openSession(); Customer customer = sqlSession.selectOne("queryCustomerById", 3); System.out.println(customer); sqlSession.delete("deleteCustomer", customer); sqlSession.commit(); sqlSession.close(); } }
通过编写代码,已经对mybatis有了基本的认识,我们具体看一下mybatis的执行流程图,可以采用debug模式一步一步看: