学习了hibernate这个持久层框架以后,在来学习Mybatis简直是无压力,由于Mybatis入门门栏很低,若是学习过了hibernate的话,对于Mybatis的学习很简单了,若是没学习过hibernate直接学习Mybatis也不要紧,也很好理解。html
写Mybatis这一章节博客,大体分为这样一种思路 java
mybatis入门 --> 全局配置文件和映射文件详解 --> 高级映射(一对一,一对多,多对多) -->延迟加载机制 -->一级缓存,二级缓存(整合ehcache) --> spring整合mybatis --> 逆向工程mysql
若是你想直接查看mybatis的标准helloworld,那么跳过这章,看第二章。spring
1、Mybatis的简介sql
mybatis封装了jdbc的持久层框架,前身为ibatis,在配置文件中编写sql,是不彻底orm映射框架。数据库
查看百度百科的介绍apache
一、支持普通sql查询缓存
二、高级映射session
三、存储过程mybatis
四、消除了几乎全部jdbc代码和参数的手工设置以及结果集的检索,等等特色,都会讲解到,今天先认识一下为何说mybatis消除了全部jdbc代码和参数的设置,经过普通的jdbc有哪些不足,从而认识到mybatis的好处。
2、分析jdbc的问题
1 //一、注册驱动,什么是驱动?可以让java链接数据库,也就是实现jdbc接口规范就是驱动 2 Class.forName("com.mysql.jdbc.Driver");//硬编码 3 /* 4 * 二、经过驱动管理者获取数据库链接 5 * DriverManager是驱动实现类的管理者。 6 * url:链接数据库的位置,端口号,数据库名 7 * jdbc:mysql://localhost:3306/test_01 8 */ 9 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test_1", "root", "root");//(硬编码) 10 /* 11 * 三、得到sql语句执行者 12 * statement:执行sql语句对象 13 * sql语句必须是完整的。 14 * preparedStatement:预处理(经常使用) 15 * sql语句能够不是完整的,能够将参数用?替代,而后在预编译后加入未知参数 16 * 17 */ 18 //定义sql语句,?表示占位符 19 String sql = "select * from user where id = ?"; //硬编码 20 PreparedStatement ps = conn.prepareStatement(sql); 21 ps.setInt(1, 1); //硬编码 22 //四、获取sql语句执行结果,resultset 23 /* 24 * executeQuery():查询操做 25 * executeUpdate():增删改操做 26 */ 27 ResultSet rs= ps.executeQuery(); 28 //五、处理结果 29 while(rs.next()){ 30 System.out.println(rs.getInt(1));;//index表明第几列,从1开始 31 } 32 33 //六、关闭链接 34 rs.close(); 35 ps.close(); 36 conn.close();
1 //一、注册驱动,什么是驱动?可以让java链接数据库,也就是实现jdbc接口规范就是驱动 2 Class.forName("com.mysql.jdbc.Driver");//硬编码 3 /* 4 * 二、经过驱动管理者获取数据库链接 5 * DriverManager是驱动实现类的管理者。 6 * url:链接数据库的位置,端口号,数据库名 7 * jdbc:mysql://localhost:3306/test_01 8 */ 9 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test_1", "root", "root");//(硬编码) 10 /* 11 * 三、得到sql语句执行者 12 * statement:执行sql语句对象 13 * sql语句必须是完整的。 14 * preparedStatement:预处理(经常使用) 15 * sql语句能够不是完整的,能够将参数用?替代,而后在预编译后加入未知参数 16 * 17 */ 18 //定义sql语句,?表示占位符 19 String sql = "select * from user where id = ?"; //硬编码 20 PreparedStatement ps = conn.prepareStatement(sql); 21 ps.setInt(1, 1); //硬编码 22 //四、获取sql语句执行结果,resultset 23 /* 24 * executeQuery():查询操做 25 * executeUpdate():增删改操做 26 */ 27 ResultSet rs= ps.executeQuery(); 28 //五、处理结果 29 while(rs.next()){ 30 System.out.println(rs.getInt(1));;//index表明第几列,从1开始 31 } 32 33 //六、关闭链接 34 rs.close(); 35 ps.close(); 36 conn.close();
这种方式的缺陷
一、建立链接存在硬编码
二、执行statement时存在硬编码
三、频繁的开闭数据库链接,会影响数据库的性能。
如今就对这个所产生的问题与使用mybatis进行对比。
3、初级的mybatis
跟hibernate同样,也是须要拥有两个配置文件,
全局配置文件 和 映射文件,在编写这两个映射文件以前,必须建立mybatis环境(jar包等)
建立java工程
3.一、jar包
mysql(1)
Mybatis(1个核心包+9个依赖包)
总共11个jar
3.二、初始化数据库脚本
暂时只须要一张表 id是自增的,为主键
3.三、添加log4j.properties
该内容能够在mybatis的jar包中找到
1 # Global logging configuration 2 log4j.rootLogger=DEBUG, stdout 3 # MyBatis logging configuration... 4 log4j.logger.org.mybatis.example.BlogMapper=TRACE 5 # Console output... 6 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 7 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
1 # Global logging configuration 2 log4j.rootLogger=DEBUG, stdout 3 # MyBatis logging configuration... 4 log4j.logger.org.mybatis.example.BlogMapper=TRACE 5 # Console output... 6 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 7 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
3.四、全局配置文件
建议使用sqlMapConfig.xml,内容以下
这次的配置
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 属性 8 <properties></properties> 9 全局参数设置 10 <settings></settings> 11 类型别名 12 <typeAliases></typeAliases> 13 类型处理器 14 <typeHandles></typeHandles> 15 对象工厂 16 <objectFactory></objectFactory> 17 插件 18 <plugins></plugins> 19 以上属性在后边会详细讲解到,如今咱们就只须要关注一下下面的配置便可 20 以下所配置的就是使用这点东西。 21 environments(环境信息集合) 22 environment(单个环境信息) 23 transactionManager(事物) 24 dataSource(数据源) 25 environment 26 environments 27 mappers(映射器) 28 --> 29 30 31 <!-- 配置mybatis的环境信息 --> 32 <environments default="development"> 33 <environment id="development"> 34 <!-- 配置JDBC事务控制,由mybatis进行管理 --> 35 <transactionManager type="JDBC"></transactionManager> 36 <!-- 配置数据源,采用dbcp链接池 --> 37 <dataSource type="POOLED"> 38 <property name="driver" value="com.mysql.jdbc.Driver"/> 39 <property name="url" value="jdbc:mysql://localhost:3306/test_1?useUnicode=true&characterEncoding=utf8"/> 40 <property name="username" value="root"/> 41 <property name="password" value="root"/> 42 </dataSource> 43 </environment> 44 </environments> 45 <!-- 加载mapper映射文件 --> 46 <mappers> 47 <mapper resource="sqlmap/User.xml"/> 48 </mappers> 49 </configuration>
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 属性 8 <properties></properties> 9 全局参数设置 10 <settings></settings> 11 类型别名 12 <typeAliases></typeAliases> 13 类型处理器 14 <typeHandles></typeHandles> 15 对象工厂 16 <objectFactory></objectFactory> 17 插件 18 <plugins></plugins> 19 以上属性在后边会详细讲解到,如今咱们就只须要关注一下下面的配置便可 20 以下所配置的就是使用这点东西。 21 environments(环境信息集合) 22 environment(单个环境信息) 23 transactionManager(事物) 24 dataSource(数据源) 25 environment 26 environments 27 mappers(映射器) 28 --> 29 30 31 <!-- 配置mybatis的环境信息 --> 32 <environments default="development"> 33 <environment id="development"> 34 <!-- 配置JDBC事务控制,由mybatis进行管理 --> 35 <transactionManager type="JDBC"></transactionManager> 36 <!-- 配置数据源,采用dbcp链接池 --> 37 <dataSource type="POOLED"> 38 <property name="driver" value="com.mysql.jdbc.Driver"/> 39 <property name="url" value="jdbc:mysql://localhost:3306/test_1?useUnicode=true&characterEncoding=utf8"/> 40 <property name="username" value="root"/> 41 <property name="password" value="root"/> 42 </dataSource> 43 </environment> 44 </environments> 45 <!-- 加载mapper映射文件 --> 46 <mappers> 47 <mapper resource="sqlmap/User.xml"/> 48 </mappers> 49 </configuration>
3.五、映射文件和操做
User.xml 暂时这样取。
<?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"> <!-- namespace:命名空间,对sql进行一个分类管理 --> <!-- 注意:namespace在mapper代理时,具备重要且特殊的做用 --> <mapper namespace="test"> //编写映射条件,也就是下面的 </mapper>
<?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"> <!-- namespace:命名空间,对sql进行一个分类管理 --> <!-- 注意:namespace在mapper代理时,具备重要且特殊的做用 --> <mapper namespace="test"> //编写映射条件,也就是下面的 </mapper>
该映射文件是为了解决jdbc中statement的硬编码的问题,因此,在此映射文件中,只须要指定输入参数类型,返回结果参数类型,sql语句等就差很少了,也就是将本来jdbc所遇到的硬编码问题所有是使用xml配置文件来替代,有什么须要就修改配置文件便可,如今来看看该映射文件是如何编写的。
经过增删改查这四个操做来说解。
3.6.一、查询 按id查询出user对象 注意看下面的注释
1 <!-- 2 使用id进行查询 3 查询,使用select来表示一个查询的statement,至关于statement.executeQuery 4 id:表示该statement惟一标识 5 parameterType:输入参数类型 6 resultType:输出参数类型,使用的是User类,则会将查询出来的记录封装到该类中 7 #{id}:使用#{}接收输入的参数,其中的"id"属性名任意,能够为uid,也能够为别的。 8 --> 9 <select id="findUserById" parameterType="java.lang.Integer" resultType="com.wuhao.mybatis.domain.User"> 10 SELECT * FROM user WHERE id= #{id} 11 </select> 12
1 <!-- 2 使用id进行查询 3 查询,使用select来表示一个查询的statement,至关于statement.executeQuery 4 id:表示该statement惟一标识 5 parameterType:输入参数类型 6 resultType:输出参数类型,使用的是User类,则会将查询出来的记录封装到该类中 7 #{id}:使用#{}接收输入的参数,其中的"id"属性名任意,能够为uid,也能够为别的。 8 --> 9 <select id="findUserById" parameterType="java.lang.Integer" resultType="com.wuhao.mybatis.domain.User"> 10 SELECT * FROM user WHERE id= #{id} 11 </select> 12
操做
1 //根据用户id进行查询。findUserById 2 @Test 3 public void test() throws IOException{ 4 //跟hibernate同样,须要获取一大堆东西 5 // 一、读取配置文件 6 String resource = "SqlMapConfig.xml"; 7 InputStream inputStream = Resources.getResourceAsStream(resource); 8 // 二、根据配置文件建立SqlSessionFactory 9 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 10 // 三、SqlSessionFactory建立SqlSession 11 SqlSession sqlSession = sqlSessionFactory.openSession(); 12 // 四、SqlSession执行statement,并返回映射结果 13 14 /* 15 * test.findUserById:在映射配置文件中,mapper的namespace为test, 16 * 其中有一个select,也就表明查询的statement。 17 * 1:输入参数为1 18 * 返回的结果类型为User 19 */ 20 User user = sqlSession.selectOne("test.findUserById", 1); 21 System.out.println(user); 22 23 //五、关闭sqlsession资源 24 sqlSession.close(); 25 }
1 //根据用户id进行查询。findUserById 2 @Test 3 public void test() throws IOException{ 4 //跟hibernate同样,须要获取一大堆东西 5 // 一、读取配置文件 6 String resource = "SqlMapConfig.xml"; 7 InputStream inputStream = Resources.getResourceAsStream(resource); 8 // 二、根据配置文件建立SqlSessionFactory 9 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 10 // 三、SqlSessionFactory建立SqlSession 11 SqlSession sqlSession = sqlSessionFactory.openSession(); 12 // 四、SqlSession执行statement,并返回映射结果 13 14 /* 15 * test.findUserById:在映射配置文件中,mapper的namespace为test, 16 * 其中有一个select,也就表明查询的statement。 17 * 1:输入参数为1 18 * 返回的结果类型为User 19 */ 20 User user = sqlSession.selectOne("test.findUserById", 1); 21 System.out.println(user); 22 23 //五、关闭sqlsession资源 24 sqlSession.close(); 25 }
3.6.二、查询, 模糊查询,对username字段进行模糊查询
user.xml映射文件
操做
3.6.三、增长User, insert
user.xml,insert操做,对主键id有几种不一样的处理方式,具体看下图的解释
操做
3.6.四、删除 delete
映射文件
操做
3.6.五、更新 update
映射文件
操做
小总结:编写了最基础的全局配置文件和映射文件。
全局配置文件:链接数据库所须要的账号密码等属性,事务等操做
映射文件:经过对比原始jdbc链接数据库,其实mybatis中的映射文件就是对statement的硬编码进行改进,咱们配置的都市statement须要的东西
sql语句、输入参数类型代替sql语句中的占位符,输出参数类型表示输出结果,均可以对应着statement的操做
parameterType:指定输入参数的java类型,能够填写别名或Java类的全限定名。别名的用法在详细讲解全局配置文件的时候会讲解到,在那边能够配置
resultType:指定输出结果的java类型,能够填写别名或Java类的全限定名。
#{}和${}的用法
#{}:至关于预处理中的占位符?
#{}里面的参数表示接收java输入参数的名称
#{}能够接受HashMap、简单类型、POJO类型的参数
简单类型:#{}里面能够是value,能够是任意值
POJO类型的参数:必须是POJO中的属性名
hashmap:key值名
${}:至关于拼接SQL串,对传入的值不作任何解释的原样输出。
${}会引发SQL注入,因此要谨慎使用。
${}能够接受HashMap、简单类型、POJO类型的参数。
当接受简单类型的参数时,${}里面只能是value。
sqlSession操做时selectOne和selectList
selectOne:只能查询0或1条记录,大于1条记录的话,会报错
selectList:能够查询0或N条记录
对于增删改操做,切记须要commmit操做才可以生效。
4、开发dao的方式
上面咱们就单纯测试了使用mybatis对数据库的增删改查操做,在开发中,咱们都是开发dao接口和dao实现类,那么就在dao实现类中调用sqlsession的方法对数据库的增删改差操做便可。
4.一、dao接口
4.二、daoImpl 实现类
4.三、测试
小总结:
这样开发有一个很差的地方,就是不可以直接使用dao接口中的方法,而是使用的sqlSession中的方法,这样让人不能一目了然,因此咱们在开发中都不使用这种方式进行开发,而是使用Mapper代理的方式,什么意思呢?接下来说讲。
5、Mapper代理开发的方式
Mapper代理开发方式就是开发mapper接口(至关于dao接口)
一、mapper接口的全限定名要和mapper映射文件的namespace一致
二、mapper接口的方法名称要和mapper映射文件的statement的id一致
三、mapper接口的方法参数类型要和mapper映射文件的statement的parameterType一致
四、mapper接口的方法返回值类型要和 mapper映射文件的statement的resultType一致
这样直接看确定很差理解,因此直接上代码。
三样东西,mapper接口,两个配置文件,一个全局配置文件,一个映射文件,可是这个映射文件就有要求了,除了上面所说的四点以外,另一点也最好遵循,这里用不到,可是后面会讲解为何会这样使用,就是mapper接口的名称要和映射文件的名称相同,
mapper接口,UserMapper.java
映射文件,UserMapper.xml
全局配置文件。sqlMapConfig.xml
其余都跟上面同样,重点讲一下这个mappers加载映射文件的问题,为何须要mapper接口和映射文件同名,而且放入同一目录下
为了方便批量加载映射文件。而使用这种方式,前提条件就是接口和映射文件同名而且放入同一目录下。
测试
直接调用方法名便可
6、总结
mybatis的基本用法就是这样,我想你们应该都有点感受了,就是在映射文件中编写statement,将输入参数和输出结果进行映射,因此说mybatis是不彻底映射的框架。懂了基本的用法以后,那么以后就会详细讲解其中的问题,全局配置文件当中的配置,映射文件中的详细配置(高级映射),延迟加载,一级缓存二级缓存等用法。
原文出处:https://www.cnblogs.com/surfcater/p/10225738.html