一:Mybatis框架概述
1:什么是Mybatis
官方定义:
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
- mybatis 是一个优秀的基于 java 的持久层框架,它内部封装了对JDBC的操作,使开发者只需要关注 sql 语句本身,而不需要花费精力去注册驱动、创建Connection、Statement等对象,也不需要手动设置配置参数。
- mybatis 通过 xml 或注解的方式对要执行的各种 statement(声明) 配置起来,并通过 java 对象和 statement 中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。
- 采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。
注:ORM思想(Object Relational Mapping) 对象关系映射,简单说就是把数据库表和实体类的属性一一映射,让我们操作实体类就可以操作数据库表
2:Mybatis的引入
在我们没学过mybatis的时候,我相信大部分人都是手写JDBC,手动关连接、映射对象,这就导致开发者效率低下;可是如今mybatis的登场我们可以简化了对持久层(CRUD)的操作了。
原生态的JDBC编写:
实体类就是对应数据库的几个字段
1 # 配置文件名称 db_config.properties 2 driver=com.mysql.jdbc.Driver 3 url=jdbc:mysql://localhost:3306/demo_school 4 username=root 5 password=123 6 7 8 ******************************************************* 9 10 /** 11 * @author ant 12 * @Class 获取连接数据库对象的工具类 13 */ 14 //获取Connection对象 15 public class JDBCUtils { 16 //聚合Connection对象 17 private static Connection con; 18 19 //静态块来创建Connection对象 20 static { 21 try { 22 //通过类加载机制来读取配置文件 23 InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("db_config.properties"); 24 //创建读取文件对象 25 Properties pro = new Properties(); 26 //传入流(配置文件) 27 pro.load(in); 28 //获取四大配置 29 String driver = pro.getProperty("driver"); 30 String url = pro.getProperty("url"); 31 String username = pro.getProperty("username"); 32 String password = pro.getProperty("password"); 33 34 //注册驱动 35 Class.forName(driver); 36 //获取连接 37 con = DriverManager.getConnection(url, username, password); 38 39 //抛出IO异常 读取文件位置 40 } catch (IOException e) { 41 e.printStackTrace(); 42 //抛出空对象异常 43 } catch (ClassNotFoundException e) { 44 e.printStackTrace(); 45 //抛出sql异常 46 } catch (SQLException e) { 47 e.printStackTrace(); 48 } 49 } 50 51 //返回数据库连接对象 52 public static Connection getCon() { 53 return con; 54 } 55 56 //关闭连接对象 57 public static void close(Connection con) { 58 try { 59 if (con != null) { 60 con.close(); 61 } 62 } catch (SQLException e) { 63 e.printStackTrace(); 64 } 65 } 66 } 67 68 69 **************************************************** 70 71 /** 72 * @author ant 73 * @Class Clinet类测试 74 */ 75 public class test { 76 77 public static void main(String[] args) throws IOException { 78 79 //调用工具类获取Connection对象 80 Connection con = JDBCUtils.getCon(); 81 try { 82 //获取预处理 statement 83 PreparedStatement ps = con.prepareStatement("select * from teacher where tname=?"); 84 //为预处理语句设置占位符数据 85 ps.setString(1, "张老师"); 86 //查询语句 87 ResultSet resultSet = ps.executeQuery(); 88 //循环 89 while (resultSet.next()) { 90 //获取每个字段数据 91 int tid = resultSet.getInt("tid"); 92 String tname = resultSet.getString("tname"); 93 String tsex = resultSet.getString("tsex"); 94 int tage = resultSet.getInt("tage"); 95 double tsalary = resultSet.getDouble("tsalary"); 96 String taddress = resultSet.getString("taddress"); 97 //赋予对象上 98 Teacher t = new Teacher(tid, tname, tsex, tage, tsalary, taddress); 99 //打印 100 System.out.println("打印数据了:"); 101 System.out.println(t.toString()); 102 } 103 104 //关闭连接 105 resultSet.close(); 106 JDBCUtils.close(con); 107 108 } catch (SQLException e) { 109 e.printStackTrace(); 110 } 111 } 112 } 113 114 **************************************************** 115 打印数据了: 116 Teacher{tid=1, tname='张老师', tsex='男', tage=28, tsalary=10858.0, taddress='江苏南京'}
资料导入:SQL建库建表语句来自本人腾讯文档
通过上面的JDBC原生编写会发现繁琐,而且还存在一些问题
- 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
- Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java代码。
- 使用 preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能多也可能少,修改 sql 还要修改代码,系统不易维护。
- 对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo 对象解析比较方便。
二:Mybatis框架入门编写
1:准备工作
这个下面是mybatis版本号,有些朋友没有那个啥,可能会访问不了那个网站
2:开始搭建Mybatis案例
(1):配置文件开发代码编写
1 注:这个是maven坐标 2 3 <dependencies> 4 <!--导入mybatis坐标--> 5 <dependency> 6 <groupId>org.mybatis</groupId> 7 <artifactId>mybatis</artifactId> 8 <version>3.4.6</version> 9 </dependency> 10 <!--导入mysql驱动 我选的是5.x.x 的版本 稳定点--> 11 <dependency> 12 <groupId>mysql</groupId> 13 <artifactId>mysql-connector-java</artifactId> 14 <version>5.1.32</version> 15 </dependency> 16 <!--导入log4j日志坐标--> 17 <dependency> 18 <groupId>log4j</groupId> 19 <artifactId>log4j</artifactId> 20 <version>1.2.17</version> 21 </dependency> 22 </dependencies> 23 24 +++++++++++++++++++++++++++++++++++++++++ 25 注:下面的是实体老师类 Teacher 26 27 package cn.xw.domain; 28 /** 29 * @author ant 30 * @bean 这个是老师类 31 */ 32 public class Teacher { 33 private int tid; //老师id 34 private String tname; //老师姓名 35 private String tsex; //老师性别 36 private int tage; //老师年龄 37 private double tsalary; //老师薪资 38 private String taddress; //老师住址 39 //下面省去构造器/get/set/tostring 你们自己加一下 40 } 41 42 +++++++++++++++++++++++++++++++++++++++++ 43 注:操作TeacherDao接口类 44 45 /** 46 * @author ant 47 * @interface 数据操作的接口 老师的dao 48 */ 49 public interface TeacherDao { 50 51 //查询全部老师信息 52 List<Teacher> findAll(); 53 54 } 55 +++++++++++++++++++++++++++++++++++++++++ 56 57 注:下面这个是配置文件TeacherDao.xml 58 59 <?xml version="1.0" encoding="UTF-8" ?> 60 <!DOCTYPE mapper 61 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 62 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 63 <!--TeacherDao类的配置文件 还有使用namespace指明要配置的类--> 64 <mapper namespace="cn.xw.dao.TeacherDao"> 65 <!--每个方法就会对应一个查询 id是方法名 resultType是实体类--> 66 <select id="findAll" resultType="cn.xw.domain.Teacher"> 67 select * from teacher; 68 </select> 69 </mapper> 70 71 +++++++++++++++++++++++++++++++++++++++++ 72 73 注:主配置文件SqlMapConfig.xml 74 75 <?xml version="1.0" encoding="UTF-8" ?> 76 <!DOCTYPE configuration 77 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 78 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 79 <!--mybatis的主配置文件--> 80 <configuration> 81 <!--配置环境 default="mysql" 说明找下面的一个id为mysql的配置 将来这个下面会有许多如oracle配置啦等等--> 82 <environments default="mysql"> 83 <!--配置一个名为mysql的 数据库连接配置 --> 84 <environment id="mysql"> 85 <!--配置事务类型--> 86 <transactionManager type="JDBC"></transactionManager> 87 <!--配置数据源连接池--> 88 <dataSource type="POOLED"> 89 <!--四大配置 driver驱动 url数据库地址 username/password账号密码--> 90 <property name="driver" value="com.mysql.jdbc.Driver"/> 91 <property name="url" value="jdbc:mysql://localhost:3306/demo_school"/> 92 <property name="username" value="root"/> 93 <property name="password" value="123"/> 94 </dataSource> 95 </environment> 96 </environments> 97 <!--映射的配置文件位置 映射配置文件指的是每个dao独立的配置文件 --> 98 <mappers> 99 <mapper resource="cn/xw/dao/TeacherDao.xml"></mapper> 100 </mappers> 101 </configuration> 102 103 +++++++++++++++++++++++++++++++++++++++++ 104 105 注:测试类Client 106 107 public class Client { 108 public static void main(String[] args) throws IOException { 109 //获取配置文件的流信息 110 InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml"); 111 //创建一个SqlSessionFactoryBuilder,这个后期方便创建一个工厂对象 112 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 113 //通过SqlSessionFactory来创建一个SqlSessionFactory工厂对象 114 SqlSessionFactory factory = builder.build(config); 115 //通过工厂方法来创建一个具体的sqlSession对象来操作数据库 116 SqlSession sqlSession = factory.openSession(); 117 //通过动态代理的方式来获取具体的被代理类 118 TeacherDao mapper = sqlSession.getMapper(TeacherDao.class); 119 //获取数据循环打印 120 List<Teacher> teachers = mapper.findAll(); 121 for (Teacher teacher : teachers) { 122 System.out.println(teacher.toString()); 123 } 124 //关闭 125 config.close(); 126 sqlSession.close(); 127 } 128 }
文字描述搭建入门案例:
①:创建一个maven工程并导入相应的坐标
②:创建实体类和dao接口
③:创建mybatis的主配置文件SqlMapConfig.xml
④:创建dao接口的映射配置文件xxx.xml
(2):注解开发代码编写
在写完配置文件开发后,会发现操作数据库变得容易,但是这么说吧,现在的查询就一个类一条sql语句的配置,如果将来开发中有特别多的类和各种各样的sql配置,你就会发现配置太繁琐了,所有我接下来就和大家介绍另一种写法:注解开发
注解开发和配置文件开发挺相似的,大家接下来就跟着我的操作来完成,(前提你的配置文件开发的那些代码可以运行)
①:删除配置文件目录,cn.xw.dao.TeacherDao.xml是配置路径,把cn下的全部目录删除,如果保留来写注解开发会出错
②:更改主配置文件SqlMapConfig.xml 只需要更改<mappers>标签即可,其它不动
1 <!--映射的配置文件位置 映射配置文件指的是每个dao独立的配置文件 --> 2 <mappers> 3 <!--class配置的是注解 表示配置src目录下的dao操作类--> 4 <mapper class="cn.xw.dao.TeacherDao"></mapper> 5 <!--这个是配置文件开发 配置文件路径 我们直接注释--> 6 <!--<mapper resource="cn/xw/dao/TeacherDao.xml"></mapper>--> 7 </mappers>
③:更改dao接口,我这里是TeacherDao接口
1 /** 2 * @author ant 3 * @interface 数据操作的接口 老师的dao 4 */ 5 public interface TeacherDao { 7 //查询全部老师信息 8 //这里的注解后面会详细介绍 这里只是做个入门 9 @Select("select * from teacher;") 10 List<Teacher> findAll(); 12 }
大功告成,其它的不用修改,运行就可以了
(3):实现类开发代码编写
这个实现类开发的方法极少有人写,因为用这种写法根没使用框架差不多,繁琐,最多在学习中了解这种写法
项目的架构和配置文件开发的框架差不多,只是在dao的下面多了一个实现类
1 注:pom.xml文件 2 3 <dependencies> 4 <!--导入mybatis坐标--> 5 <dependency> 6 <groupId>org.mybatis</groupId> 7 <artifactId>mybatis</artifactId> 8 <version>3.4.6</version> 9 </dependency> 10 <!--导入mysql驱动 我选的是5.x.x 的版本 稳定点--> 11 <dependency> 12 <groupId>mysql</groupId> 13 <artifactId>mysql-connector-java</artifactId> 14 <version>5.1.32</version> 15 </dependency> 16 <!--导入log4j日志坐标--> 17 <dependency> 18 <groupId>log4j</groupId> 19 <artifactId>log4j</artifactId> 20 <version>1.2.17</version> 21 </dependency> 22 </dependencies> 23 24 **************************************************** 25 26 注:实体类 Teacher 27 28 public class Teacher { 29 30 private int tid; //老师id 31 private String tname; //老师姓名 32 private String tsex; //老师性别 33 private int tage; //老师年龄 34 private double tsalary; //老师薪资 35 private String taddress; //老师住址 36 //下面的构造器/getset/toString省略你们自己写上就行 37 } 38 39 **************************************************** 40 41 注:TeacherDao接口 42 43 /** 44 * @author ant 45 * @interface 抽象老师接口 46 */ 47 public interface TeacherDao { 48 49 //接口方法 查询全部老师 50 List<Teacher> findAll(); 51 } 52 53 **************************************************** 54 55 注:TeacherDaoImpl实现类 56 57 /** 58 * @author ant 59 * @class TeacherDao接口的实现类 60 */ 61 public class TeacherDaoImpl implements TeacherDao { 62 //聚合mybatis工厂对象 63 private SqlSessionFactory factory; 64 65 //构造器传入对象 66 public TeacherDaoImpl(SqlSessionFactory factory) { 67 this.factory = factory; 68 } 69 70 //查询全部方法 71 public List<Teacher> findAll() { 72 //获取SqlSession 73 SqlSession sqlSession = factory.openSession(); 74 //调用查询方法 带list后缀的说明数据有多个 75 List<Teacher> teachers = sqlSession.selectList("cn.xw.dao.TeacherDao.findAll"); 76 //关闭对象 77 sqlSession.close(); 78 //返回数据 79 return teachers; 80 } 81 } 82 83 **************************************************** 84 85 注:配置文件 resource/cn/xw/dao/TeacherDao.xml 86 87 <?xml version="1.0" encoding="UTF-8" ?> 88 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 89 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 90 <mapper namespace="cn.xw.dao.TeacherDao"> 91 <select id="findAll" resultType="cn.xw.domain.Teacher"> 92 select * from teacher; 93 </select> 94 </mapper> 95 96 **************************************************** 97 98 注:主配置文件SqlMapConfig.xml 和配置文件开发配置的一样 99 100 <?xml version="1.0" encoding="UTF-8" ?> 101 <!DOCTYPE configuration 102 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 103 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 104 <!--mybatis的主配置文件--> 105 <configuration> 106 <!--配置环境 default="mysql" 说明找下面的一个id为mysql的配置 将来这个下面会有许多如oracle配置啦等等--> 107 <environments default="mysql"> 108 <!--配置一个名为mysql的 数据库连接配置 --> 109 <environment id="mysql"> 110 <!--配置事务类型--> 111 <transactionManager type="JDBC"></transactionManager> 112 <!--配置数据源连接池--> 113 <dataSource type="POOLED"> 114 <!--四大配置 driver驱动 url数据库地址 username/password账号密码--> 115 <property name="driver" value="com.mysql.jdbc.Driver"/> 116 <property name="url" value="jdbc:mysql://localhost:3306/demo_school"/> 117 <property name="username" value="root"/> 118 <property name="password" value="123"/> 119 </dataSource> 120 </environment> 121 </environments> 122 123 <!--映射的配置文件位置 映射配置文件指的是每个dao独立的配置文件 --> 124 <mappers> 125 <!--这个是配置文件开发 配置文件路径--> 126 <mapper resource="cn/xw/dao/TeacherDao.xml"></mapper> 127 </mappers> 128 </configuration> 129 130 **************************************************** 131 注:测试类客户端 132 133 public class Client { 134 135 public static void main(String[] args) throws IOException { 136 137 //获取配置文件的流信息 138 InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml"); 139 //创建一个SqlSessionFactoryBuilder,这个后期方便创建一个工厂对象 140 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 141 //通过SqlSessionFactory来创建一个SqlSessionFactory工厂对象 142 SqlSessionFactory factory = builder.build(config); 143 144 //创建TeacherDao的实现类 传入SqlSessionFactory工厂对象 145 TeacherDao teacherDao = new TeacherDaoImpl(factory); 146 147 //通过TeacherDao的实现类调用findAll方法查询全部,返回数据 打印 148 List<Teacher> teachers = teacherDao.findAll(); 149 for (Teacher teacher : teachers) { 150 System.out.println(teacher.toString()); 151 } 152 //关闭对象 153 config.close(); 154 } 155 }
(4):总结
通过上面的三种写法,我们对mybatis有了一个小小的了解 ,但是这个了解只是最基础的,其实mybatis的写法有配置文件开发、注解开发、实现类开发;这三种最常用的也就注解和配置文件2中,那个实体类开发只需要了解一下即可。如果想深入了解,这点还是远远不够的,而且一旦出现多表将无法完成一系列CRUD操作,所有还得继续学习。
这三种开发方式我将会在接下来的几篇里详细介绍,包括配置文件、多表操作、缓存.......