为什么是Mybatis 首先使用JDBC操作数据库存在以下的问题
首先是硬编码问题:数据库连接,账号,密码和SQL语句等直接写在代码中,每次修改都需要修改源代码并且重新编译,非常不方便。
然后是数据库操作繁琐:使用JDBC操作数据库非常繁琐:设置SQL语句变量,执行SQL语句,处理返回集;而Mybatis只需要两行代码就可以完成这些操作。
操作Mybatis 导入MyBatis 首先我们需要在项目中导入关于MyBatis的依赖,在这里我们使用Maven将MyBatis导入项目中:
1 2 3 4 5 6 7 8 <dependencies > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.2</version > </dependency > </dependencies >
编写MyBatis的配置文件 每一个基于MyBAtis的应用都是以一个SqlSessionFactory
的实例为核心的。实例SqlSessionFactory
可以通过SqlSessionFactoryBuilder
获得,而SqlSessionFactoryBuilder
则会通过XML配置文件获取数据库配置信息创建实例SqlSessionFactory
。
为了获取该配置文件,MyBatis中实现了一个Resources
工具类,用于获取配置文件的输入流:
1 2 3 String resource = "org/mybatis/example/mybatis-config.xml" ;InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream);
配置文件 XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。后面会再探讨 XML 配置文件的详细内容,这里先给出一个简单的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration > <environments default ="development" > <environment id ="development" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="${driver}" /> <property name ="url" value ="${url}" /> <property name ="username" value ="${username}" /> <property name ="password" value ="${password}" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="DepartMentMapper.xml" /> </mappers > </configuration >
通过上面的代码,我们将在如下介绍一下配置文件的一些属性:
environments:MyBatis可以配置以适应不同的环境(既可以配置多个environment,并且通过default铁环不同的environment)
typeAliases:为类设置别名,方便编码,可以使用包扫描简化。
SQL映射文件 在项目中我们可以通过xml文件来编写SQL映射文件,其具体内容一般如下:
1 2 3 4 5 6 7 8 9 10 11 12 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="test" > <select id ="selectAll" resultType ="com.takune.pojo.Department" > select * from department; </select > </mapper >
正式编码 接下来我们就可以编写对应的DAO类来存储查询的信息;然后利用Mybatis实现数据库的查询操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public static void main (String[] args) throws IOException { String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); List<Department> departmentList = sqlSession.selectList("test.selectAll" ); System.out.println(departmentList); sqlSession.close(); }
Mapper代理 上面我们可以看到,在执行SQL语句的第三步依旧存在依靠字符串的硬编码问题,因此为了解决这个硬编码的问题同时提高编码效率,我们可以使用Mapper代理的方法,步骤如下:
定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放在同一目录下
设置SQL映射文件的namespace属性为Mapper接口全限定名;
在Mapper接口中定义与SQL映射文件中的id相同的方法,并且保持参数类型,个数和返回值一致
最后编码执行,调用接口中的方法即可执行SQL语句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public static void main (String[] args) throws IOException { String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class); List<Department> departmentList = departmentMapper.selectAll(); System.out.println(departmentList); sqlSession.close(); }
Mapper代理中的注意事项 在使用Mapper代理的过程中,我们总会遇到这样那样的问题,以下将介绍一些常见的注意事项:
数据库字段与实体类变量名不一致 在实际开发中,不同的领域,不同的团队中的变量有着不同的命名风格,比如说驼峰命名等,这样经常会导致一个问题:由于数据库字段和实体类对应的变量名不一样,导致MyBatis自动封装数据的功能失效,因此为了解决这个问题,我们将采用resultMap
来解决:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <select id ="selectAll" resultType ="brand" > select * from db.tb_brand; </select > <resultMap id ="brandResultMap" type ="brand" > <result column ="brand_name" property ="brandName" /> <result column ="company_name" property ="companyName" /> </resultMap > <select id ="selectAll" resultMap ="brandResultMap" > select * from db.tb_brand; </select >
带变量的SQL语句 在实际开发过程中,我们写SQL语句时经常会有获取用户输入的条件进行查询的需求,因此我们需要解决这样的的问题:
1 2 3 4 5 6 7 8 9 <select id ="selectById" resultMap ="brandResultMap" > select * from db.tb_brand where id = #{id}; </select >
带多个变量的SQL语句 在实际开发中我们经常会遇到多条件查询的业务情况,在使用Mapper代理的前提下设置多个参数有如下三种方法:
散装参数:需要使用@Param("SQL中的占位符名称")
实体类封装参数:只需要保证SQL中占位符名称与实体类属性名称对应上即可设置成功;
map集合:保证SQL中占位符名称与map集合的键名称对上,即可设置成功。
动态SQL 在项目开发过程中,经常会出现动态条件查询的问题,假如说为了每一种可能的条件写一条SQL语句是非常繁琐的,因此为了解决这个问题,MyBatis通过一些特定的标签实现了动态SQL的功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <select id ="selectByMul" resultMap ="brandResultMap" > select * from db.tb_brand <where > <if test ="brandName != null and brandName != ''" > and brand_name like #{brandName} </if > <if test ="companyName != null and companyName != ''" > and company_name like #{companyName} </if > <if test ="status != null" > and status = #{status} </if > </where > </select > <select id ="findActiveBlogLike" resultType ="Blog" > SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose > <when test ="title != null" > AND title like #{title} </when > <when test ="author != null and author.name != null" > AND author_name like #{author.name} </when > <otherwise > AND featured = 1 </otherwise > </choose > </select >