1.Mybatis下载
Mybatis是开源的持久层框架,能够度jdbc进行简单的封装,但其并不是完全的ORM(Object Relational Mapping,对象关系映射),无法脱离数据库进行适配。目前Mybatis能够在githup上直接下载:https://github.com/mybatis/mybatis-3/releases,有多个版本可以选择。
2.Mybatis文件介绍
lib:mybatis依赖包;mybatis-3.4.6.jar:核心包;
3.mybatis配置
创建一个项目,网站/后台随意,将核心包和lib中的依赖包全都添加到项目中的lib下,没有lib自己创建,创建路径build path。
导入mybatis包后,别忘了导入数据库连接包。
4.创建配置文件
创建config配置文件夹,首先配置SqlMapConfig.xml。该文件主要用来配置数据库连接环境,在没有spring进行管理的同时对数据源进行配置,同时设置与表的映射对象。
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 <!-- 和spring整合后 environments配置将废除 --> 7 <environments default="development"> 8 <environment id="development"> 9 <!-- 使用jdbc事务管理 --> 10 <transactionManager type="JDBC" /> 11 <!-- 数据库连接池 --> 12 <dataSource type="POOLED"> 13 <property name="driver" value="com.mysql.jdbc.Driver" /> 14 <property name="url" 15 value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> 16 <property name="username" value="root" /> 17 <property name="password" value="xxxx" /> 18 </dataSource> 19 </environment> 20 </environments> 21 22 <mappers> 23 <mapper resource="sqlmap/User.xml"/> 24 </mappers> 25 26 </configuration>
更多mybatis中SqlMapConfig.xml配置可以参考http://blog.knowsky.com/197049.htm,有详细的介绍。(具体关于dtd是从哪里找的,还在研究。。。)
其中<mapper>是作为映射关系。具体下面介绍。
创建log4j.properties日志设置文件:
1 # Global logging configuration 2 log4j.rootLogger=DEBUG, stdout 3 # Console output... 4 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 6 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
全局的日志设置,主要用来打印在控制台中。
5.创建映射关系类
1 package com.mybatis.pojo; 2 3 import java.io.Serializable; 4 import java.util.Date; 5 6 public class User implements Serializable { 7 private int id; 8 private String username;// 用户姓名 9 private String sex;// 性别 10 private Date birthday;// 生日 11 private String address;// 地址
在src目录下创建User类,添加几个简单的数据。注意:Mybatis无法像hibernate那样根据类自动创建表,访问数据库时必须保证数据库存在。
6.配置映射关系文件
可以下config目录下创建sqlmap文件夹,在其中创建User.xml SQL映射文件:
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 <!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 --> 6 <mapper namespace="test"> 7 8 <select id="findUserById" 9 parameterType="Integer" 10 resultType="com.mybatis.pojo.User" 11 > 12 select * from user where id = #{v} 13 </select> 14
15 </mapper>
(同样这里还是不知道dtd哪里找的),mapper标签内主要写sql语句,用过select、update、delete标签进行区别,其中namespace属性为了区分相同id的SQL语句。
设置完之后在SqlMapConfig.xml文件中加载配置文件:
7.运行测试程序
测试程序步骤:
1. 创建SqlSessionFactoryBuilder对象
2. 加载SqlMapConfig.xml配置文件
3. 创建SqlSessionFactory对象
4. 创建SqlSession对象
5. 执行SqlSession对象执行查询,获取结果User
6. 打印结果
7. 释放资源
1 package com.mybatis.junit; 2 3 import static org.junit.Assert.*; 4 5 import java.io.File; 6 import java.io.InputStream; 7 import java.util.Properties; 8 9 import javax.annotation.Resource; 10 11 import org.apache.ibatis.io.Resources; 12 import org.apache.ibatis.session.SqlSession; 13 import org.apache.ibatis.session.SqlSessionFactory; 14 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 15 import org.junit.Test; 16 17 import com.mybatis.pojo.User; 18 import com.mysql.jdbc.interceptors.SessionAssociationInterceptor; 19 20 public class MybatisFirstTest { 21 @Test 22 public void testName() throws Exception { 23 //加载核心配置文件 24 String resource = "SqlMapConfig.xml"; 25 InputStream in = Resources.getResourceAsStream(resource); 26 27 //sessionFactory类 28 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in); 29 30 //sqlSession 31 SqlSession sqlSession = sessionFactory.openSession(); 32 33 //执行sql语句 34 User user = sqlSession.selectOne("test.findUserById", 1); 35 36 System.out.println(user.getBirthday()); 37 38 sqlSession.close(); 39 } 40 }
在执行sql语句过程中"test.findUserById"就是查找的User.xml文件中test域下的id为findUserById的SQL语句。
8.CURD操作
了解mybatis的运行流程,接下来分析下增删改查操作,测试代码都差不多,主要是执行sql语句的区别:
8.1 查询
dao层根据名字模糊查询,返回需要list。
在User.xml中如下:
1 <!-- id表示dao层中根据这个调用 2 parameterType:传入数据的类型 3 resultType:返回结果类型(这里返回list,mybatis会自动转成User的集合类型) 4 ${value}:对于字符串拼接中的占位符,必须用value 5 #{ss}:普通占位符,ss和任意取 6 --> 7 <select id="findUserByUsername" parameterType="String" resultType="com.mybatis.pojo.User"> 8 select * from user where username like '%${value}%' 9 </select>
8.2 添加
1 //执行sql语句 2 User user = new User(); 3 user.setUsername("li"); 4 user.setBirthday(new Date()); 5 user.setAddress("北京"); 6 user.setSex("女"); 7 sqlSession.insert("test.insertUser", user); 8 sqlSession.commit();
通过调用insert方法进行插入操作,注意需要进行提交操作
1 <insert id="insertUser" parameterType="com.mybatis.pojo.User"> 2 3 <!-- selectKey 标签实现主键返回 --> 4 <!-- keyColumn:主键对应的表中的哪一列 --> 5 <!-- keyProperty:主键对应的pojo中的哪一个属性 --> 6 <!-- order:设置在执行insert语句前执行查询id的sql,孩纸在执行insert语句之后执行查询id的sql --> 7 <!-- resultType:设置返回的id的类型 --> 8 <selectKey keyColumn="id" keyProperty="id" order="AFTER" 9 resultType="int"> 10 select last_insert_id() 11 </selectKey> 12 <!--传入的是User类,只要 #{username}中占位符名字与User类中的属性名一致,那么Mybatis会自动匹配 --> 13 insert into user(username,sex,birthday,address) 14 values(#{username},#{sex},#{birthday},#{address}) 15 </insert>
8.3 更新
1 //执行sql语句 2 User user = new User(); 3 user.setId(1); 4 user.setUsername("lihhhhh"); 5 user.setBirthday(new Date()); 6 user.setAddress("北京2"); 7 user.setSex("女2"); 8 sqlSession.update("updateUserById",user); 9 sqlSession.commit();
1 <update id="updateUserById" 2 parameterType="com.mybatis.pojo.User" 3 > 4 update user 5 set username=#{username},sex=#{sex} where id = #{id} 6 </update>
8.4 删除
调用语句:sqlSession.delete("deleteUserById", 1);
User.xml中:<delete id="deleteUserById" parameterType="Integer">
delete user where id = #{x}
</delete>
9.Mybatis解决jdbc的问题
1、数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。
解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。
2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。