上篇文章中我们介绍了MyBatis的一些基础知识:https://www.cnblogs.com/yybinger/p/11833737.html,这篇我们来写一个简单的MyBatis访问数据库的demo。
1、引入MyBatis所需要的jar包
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <!-- 加载类路径下的配置文件 --> 7 <properties resource="db.properties"/> 8 <!-- 设置实体类的类型别名 --> 9 <typeAliases> 10 <typeAlias type="com.ly.mybatis.demo.entity.Employee" alias="Employee"/> 11 <typeAlias type="com.ly.mybatis.demo.entity.Dept" alias="Dept"/> 12 </typeAliases> 13 14 <!-- MyBatis可以配置成适应多种环境,这种机制有助于SQL映射应用于多种数据库之中, 15 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置; 16 或者想在具有相同 Schema 的多个生产数据库中 使用相同的 SQL 映射。有许多类似的使用场景。 17 不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。 18 所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推。 19 // 不传第二个参数使用default属性对应的环境 20 SqlSessionFactory sqlSessionFactory1 = new SqlSessionFactoryBuilder().build(is); 21 SqlSessionFactory sqlSessionFactory2 = new SqlSessionFactoryBuilder().build(is, "development"); 22 --> 23 <environments default="development"> 24 <environment id="development"> 25 <!-- 事物管理器的配置 26 在MyBatis中有两种类型的事物管理器,即type="JDBC|MANAGED", 27 JDBC - 直接使用JDBC的提交和回滚设置,依赖于从数据源得到的连接来管理事物作用域。 28 MANAGED - 这个配置几乎没做什么。它从来不提交或者回滚一个连接,而是让容器来管理事物的整个生命周期(比如 JEE 应用服务器的上下文), 29 默认情况下它会关闭连接,然而一些容器并不希望这么做,因此需要将closeConnection属性设置为false 30 来阻止它默认的关闭行为。例如: 31 <transactionManager type="MANAGED"> 32 <property name="closeConnection" value="false"/> 33 </transactionManager> 34 --> 35 <transactionManager type="JDBC"/> 36 <!-- 数据源的配置 37 有三种内建的数据源类型(也就是 type=”[UNPOOLED|POOLED|JNDI]”): 38 UNPOOLED – 每次被请求时打开和关闭连接。 39 POOLED – 利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 40 这是一种使得并发 Web 应用快速响应请求的流行处理方式。 41 JNDI – 为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。 42 --> 43 <dataSource type="POOLED"> 44 <property name="driver" value="${dataSource.driver}"/> 45 <property name="url" value="${dataSource.url}"/> 46 <property name="username" value="${dataSource.username}"/> 47 <property name="password" value="${dataSource.password}"/> 48 </dataSource> 49 </environment> 50 </environments> 51 52 <mappers> 53 <!-- 告诉MyBatis去哪里找SQL 映射语句,注意:不要带后缀.xml,否则会报错找不到文件 --> 54 <mapper resource="mybatis/mapper/EmployeeMapper"/> 55 <mapper resource="mybatis/mapper/DeptMapper"/> 56 </mappers> 57 </configuration>
2、准备数据源db.properties并配置mybatis-config.xml文件
dataSource.driver=com.mysql.cj.jdbc.Driver dataSource.url=jdbc:mysql://localhost:3306/ly_test dataSource.username=root dataSource.password=root
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <!-- 加载类路径下的配置文件 --> 7 <properties resource="db.properties"/> 8 <!-- 设置实体类的类型别名 --> 9 <typeAliases> 10 <typeAlias type="com.ly.mybatis.demo.entity.Employee" alias="Employee"/> 11 <typeAlias type="com.ly.mybatis.demo.entity.Dept" alias="Dept"/> 12 </typeAliases> 13 14 <!-- MyBatis可以配置成适应多种环境,这种机制有助于SQL映射应用于多种数据库之中, 15 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置; 16 或者想在具有相同 Schema 的多个生产数据库中 使用相同的 SQL 映射。有许多类似的使用场景。 17 不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。 18 所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推。 19 // 不传第二个参数使用default属性对应的环境 20 SqlSessionFactory sqlSessionFactory1 = new SqlSessionFactoryBuilder().build(is); 21 SqlSessionFactory sqlSessionFactory2 = new SqlSessionFactoryBuilder().build(is, "development"); 22 --> 23 <environments default="development"> 24 <environment id="development"> 25 <!-- 事物管理器的配置 26 在MyBatis中有两种类型的事物管理器,即type="JDBC|MANAGED", 27 JDBC - 直接使用JDBC的提交和回滚设置,依赖于从数据源得到的连接来管理事物作用域。 28 MANAGED - 这个配置几乎没做什么。它从来不提交或者回滚一个连接,而是让容器来管理事物的整个生命周期(比如 JEE 应用服务器的上下文), 29 默认情况下它会关闭连接,然而一些容器并不希望这么做,因此需要将closeConnection属性设置为false 30 来阻止它默认的关闭行为。例如: 31 <transactionManager type="MANAGED"> 32 <property name="closeConnection" value="false"/> 33 </transactionManager> 34 --> 35 <transactionManager type="JDBC"/> 36 <!-- 数据源的配置 37 有三种内建的数据源类型(也就是 type=”[UNPOOLED|POOLED|JNDI]”): 38 UNPOOLED – 每次被请求时打开和关闭连接。 39 POOLED – 利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 40 这是一种使得并发 Web 应用快速响应请求的流行处理方式。 41 JNDI – 为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。 42 --> 43 <dataSource type="POOLED"> 44 <property name="driver" value="${dataSource.driver}"/> 45 <property name="url" value="${dataSource.url}"/> 46 <property name="username" value="${dataSource.username}"/> 47 <property name="password" value="${dataSource.password}"/> 48 </dataSource> 49 </environment> 50 </environments> 51 52 <mappers> 53 <!-- 告诉MyBatis去哪里找SQL 映射语句 --> 54 <mapper resource="mybatis/mapper/EmployeeMapper.xml"/> 55 <mapper resource="mybatis/mapper/DeptMapper.xml"/> 56 </mappers> 57 </configuration>
3、编写实体类
Employee实体类:
1 package com.ly.mybatis.demo.entity; 2 3 import lombok.Data; 4 5 import java.math.BigDecimal; 6 import java.util.Date; 7 8 @Data 9 public class Employee { 10 /** 11 * 员工编号 12 */ 13 private String empno; 14 /** 15 * 员工姓名 16 */ 17 private String ename; 18 /** 19 * 岗位 20 */ 21 private String job; 22 /** 23 * 直接领导编号 24 */ 25 private String mgr; 26 /** 27 * 雇佣日期,入职日期 28 */ 29 private Date hiredate; 30 /** 31 * 薪水 32 */ 33 private BigDecimal sal; 34 /** 35 * 提成 36 */ 37 private BigDecimal comm; 38 /** 39 * 部门编号 40 */ 41 private String deptno; 42 43 }
Dept实体类:
1 package com.ly.mybatis.demo.entity; 2 3 import lombok.Data; 4 5 @Data 6 public class Dept { 7 /** 8 * 部门编号 9 */ 10 private String deptno; 11 /** 12 * 部门名称 13 */ 14 private String dname; 15 /** 16 * 部门地址 17 */ 18 private String loc; 19 }
4、编写mapper.xml
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.ly.mybatis.demo.mapper.EmployeeMapper"> 7 <!-- 此处的id是唯一标识,下面查询返回的resultMap就是这个id值 8 type是实体类型,由于已经在mybatis-config.xml中配置了实体类的别名typeAliase,此处直接使用的别名 9 --> 10 <resultMap id="BaseResultMap" type="Employee"> 11 <id column="empno" property="empNo" jdbcType="VARCHAR"/> 12 <result column="ename" property="empName" jdbcType="VARCHAR"/> 13 <result column="job" property="job" jdbcType="VARCHAR"/> 14 <result column="mgr" property="mgr" jdbcType="VARCHAR"/> 15 <result column="hiredate" property="hireDate" jdbcType="DATE"/> 16 <result column="sal" property="sal" jdbcType="DECIMAL"/> 17 <result column="comm" property="comm" jdbcType="DECIMAL"/> 18 <result column="deptno" property="deptNo" jdbcType="VARCHAR"/> 19 </resultMap> 20 21 <select id="selectByPk" resultMap="BaseResultMap"> 22 select * from emp where empno = #{empNo} 23 </select> 24 </mapper>
5、编写Mapper接口
1 package com.ly.mybatis.demo.mapper; 2 3 import com.ly.mybatis.demo.entity.Employee; 4 5 public interface EmployeeMapper { 6 Employee selectByPk(String id); 7 }
6、读取配置文件,获取SqlSession并操作数据库
JdbcUtil工具类:
1 package com.ly.mybatis.demo.util; 2 3 import lombok.extern.slf4j.Slf4j; 4 import org.apache.ibatis.io.Resources; 5 import org.apache.ibatis.session.SqlSession; 6 import org.apache.ibatis.session.SqlSessionFactory; 7 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 8 9 import java.io.IOException; 10 import java.io.InputStream; 11 12 @Slf4j 13 public class JdbcUtil { 14 private static SqlSessionFactory sqlSessionFactory; 15 private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>(); 16 17 static { 18 try { 19 InputStream is = Resources.getResourceAsStream("mybatis/mybatis-config.xml"); 20 sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); 21 } catch (IOException e) { 22 log.error("Init sqlSessionFactory failure :{}", e); 23 } 24 } 25 26 /** 27 * 单例 28 */ 29 private JdbcUtil() {} 30 31 public static SqlSession getSqlSession() { 32 // 从当前线程中获取sqlSession对象 33 SqlSession sqlSession = threadLocal.get(); 34 if (sqlSession == null) { 35 sqlSession = sqlSessionFactory.openSession(); 36 // 将SqlSession对象与当前线程绑定在一起 37 threadLocal.set(sqlSession); 38 } 39 return sqlSession; 40 } 41 42 public static void closeSqlSession() { 43 SqlSession sqlSession = threadLocal.get(); 44 if (sqlSession != null) { 45 sqlSession.close(); 46 // 分开当前线程与SqlSession对象的关系,目的是尽早进行垃圾回收 47 threadLocal.remove(); 48 } 49 } 50 }
测试类:
1 package com.ly.mybatis.demo; 2 3 import com.ly.mybatis.demo.util.JdbcUtil; 4 5 import java.sql.Connection; 6 7 public class MyBatisTest { 8 public static void main(String[] args) { 9 Connection connection = JdbcUtil.getSqlSession().getConnection(); 10 System.out.println(connection); 11 } 12 13 }
运行程序之后,控制台输出:
Employee{empNo='7839', empName='吴九', job='总裁', mgr='null', hireDate=Tue Nov 17 14:00:00 CST 1981, sal=5000, comm=null, deptNo='10'}
至此,一个简单的MyBatis操作MySQL数据库的demo已经完成了。