mybatis入门
什么是 MyBatis ?
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
- mybatis 官方教学的案例网址
- http://www.mybatis.org/mybatis-3/zh/index.html(mybatis基础案例)
- http://www.mybatis.org/spring/zh/index.html(mybatis整合spring案例)
**安装mybatis的方法
1.要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于 classpath 中即可。
2.使用maven创建的项目添加的一依赖
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
3.由于mybatis主要操作的是数据库所以我们需要引入MySQL的依赖笔者使用的是这个数据库,如果你想找别的依赖也可以去maven的官网找
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
好了现在我们就搭建好了mybatis的基本开发环境了
由于使用的是Intellij开发环境,使用maven构建在Intellij构建项目的时
在默认的情况下maven打包的时候,对于src/main/java目录只打包源代码,而不会打包其他文件。所以此时如果把对应的mapper文件放到src/main/java目录下时,不会打包到最终的jar文件夹中,也不会输出到target文件夹中,由于在进行单元测试的时候执行的是/target目录下/test-classes下的代码,所以在测试的时候也不会成功。
为了实现在maven默认环境下打包时,Mybatis的接口和mapper文件在同一包中,可以通过将接口文件放在src/main/java某个包中,而在src/main/resources目录中建立同样的包,这是一种约定优于配置的方式,这样在maven打包的时候就会将src/main/java和src/main/resources相同包下的文件合并到同一包中。
这就是我们创建的mapper文件放在resource下的原因,而没有放在demo12下的mapper,笔者尝试过必须放到下面才能够运行。好了现在目录结构讲完了我们讨论下mybatis中的核心对象
- SqlSessionFactoryBuilder(构造器): 他主要根据我们的XML或者JAVA配置的信息来创建sqlSessionFactory。
- SqlSessionFactory(工厂接口):每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。
- SqlSession: 一个既可以发送sql去执行并返回结果,也可以获取mapper的接口完全包含了面向数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行
Sql Mapper: mybatis新设计的组件,需要给出对应的sql和映射规则,他负责去执行,并且返回结果。
他们之间的关系如下
程序开始—–>SqlSessionFactoryBuilder创建sqlsessionFactory——->sqlSessionFactory创建sqlSession———–>sqlSession有两种选择第一种直接去执行数据库语句进行CURD第二种———>SQL Mapper———>操作数据库
核心对象的生命周期
SqlSessionFactoryBuilder它的主要任务就是构建SqlSessionFactory,它可以构建多个该对象,一旦我们构建了SqlSessionFactory,SqlSessionFactoryBuilder的作用就已经完结了,所以实例的最佳作用域是方法作用域(也就是局部方法变量)。最好还是不要让其一直存在以保证所有的 XML 解析资源开放给更重要的事情。因此我们应该毫不犹豫的将他回收。
SqlSessionFactory主要的作用是创建sqlSession,sqlSession是一个会话类似于JDBC的connection对象,每次程序想要访问数据库都要通过sqlSessionfactory,因此他的生命周期应该是Mybatis整个的生命周期。但是每次创建SqlSessionFactory都会打开更过的连接,那么会对数据库的消耗过大。所以我们应该采用单利模式。管理好资源的分配。
SqlSession:它相当于一个回话。他的生命周期应该是在请求数据库处理事务的过程中。它是一个线程不安全的对象,在涉及多线程的时候要格外注意,每次创建sqlSession的时候都应该及时的将他关闭。一般在finally中关闭资源的引用
构建SqlSessionFactory的方式
在我们实际的项目当中使用主要有XML配置方式和注解方式如果我们的操作数据的时候比较简单的话我们可以使用注解来配置,但是当我们的查询操作十分的复杂的时候注解就会显得无能为力了,这是使用XML则是正确的选择
下面给出我的XML方式的配置
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--定义别名-->
<typeAliases>
<typeAlias type="demo12.po.Role" alias="role"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!--采用JDBC的事务来管理-->
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManager>
<!--配置数据库链接信息-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>
</dataSource>
</environment>
</environments>
<!--定义映射文件-->
<mappers>
<mapper resource="mappper/roleMapper.xml"></mapper>
</mappers>
</configuration>
下面是映射器
在之前版本的 MyBatis 中是可选的,容易引起混淆因此是没有益处的。现在的命名空间则是必须的,目的是希望能比只是简单的使用更长的完全限定名来区分语句更进一步。
命名空间使得你所见到的接口绑定成为可能,尽管你觉得这些东西未必用得上,你还是应该遵循这里的规定以防哪天你改变了主意。出于长远考虑,使用命名空间,并将它置于合适的 Java 包命名空间之下,你将拥有一份更加整洁的代码并提高了 MyBatis 的可用性。
命名解析:为了减少输入量,MyBatis 对所有的命名配置元素(包括语句,结果映射,缓存等)使用了如下的命名解析规则。
完全限定名(比如“com.mypackage.MyMapper.selectAllThings”)将被直接查找并且找到即用。
短名称(比如“selectAllThings”)如果全局唯一也可以作为一个单独的引用。如果不唯一,有两个或两个以上的相同名称(比如“com.foo.selectAllThings ”和“com.bar.selectAllThings”),那么使用时就会收到错误报告说短名称是不唯一的,这种情况下就必须使用完全限定名。
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="demo12.mapper.RoleMapper">
<select id="getRole" parameterType="long" resultType="role">
SELECT * FROM t_role WHERE id=#{id}
</select>
<delete id="deleteRole" parameterType="long">
DELETE FROM t_role WHERE id=#{id}
</delete>
<insert id="insertRole" parameterType="role">
INSERT INTO t_role(role_name,note) VALUES (#{role_name},#{note})
</insert>
</mapper>
单例工具SqlsessionFactory
package demo12.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by Administrator on 2017/7/6.
*/
public class SqlSessionFactoryutil {
//sqlSessionFactory对象
private static SqlSessionFactory sqlSessionFactory = null;
//线程锁
private static final Class Class_Lock = SqlSessionFactoryutil.class;
/**
* 私有化构造器
*/
private SqlSessionFactoryutil(){}
/**
* 构建SqlsessionFactory
*/
public static SqlSessionFactory initSqlSessionFactory(){
String resource = "mybatis-config.xml";
InputStream inputStream =null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
synchronized (Class_Lock){
if (sqlSessionFactory == null){
sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
}
}
return sqlSessionFactory;
}
/**
* 打开sqlSession
*/
public static SqlSession openSqlSession(){
if (sqlSessionFactory == null){
initSqlSessionFactory();
}
return sqlSessionFactory.openSession();
}
}
mapper映射的借口
public interface RoleMapper {
Role getRole(Long id);
int deleteRole(Long id);
int insertRole(Role role);
}
po代码
package demo12.po;
/**
* Created by Administrator on 2017/7/6.
*/
public class Role {
private String role_name;
private Long id ;
private String note ;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getRole_name() {
return role_name;
}
public void setRole_name(String role_name) {
this.role_name = role_name;
}
@Override
public String toString() {
return "Role{" +
"role_name='" + role_name + '\'' +
", id=" + id +
", note='" + note + '\'' +
'}';
}
}
测试代码
package demo12;
import demo12.mapper.RoleMapper;
import demo12.po.Role;
import demo12.util.SqlSessionFactoryutil;
import org.apache.ibatis.session.SqlSession;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
SqlSession sqlSession = null ;
sqlSession = SqlSessionFactoryutil.openSqlSession();
System.out.println(sqlSession);
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = new Role();
role.setId(1L);
role.setNote("testNote1");
role.setRole_name("tom1");
roleMapper.insertRole(role);
//roleMapper.deleteRole(0L);
// Role role1 = roleMapper.getRole(0L);
// System.out.println(role1+role1.getRole_name());
sqlSession.commit();
}
}
下面是数据库代码需要创建数据库mybatis
CREATE TABLE `t_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`note` varchar(40) DEFAULT NULL,
`role_name` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_role
-- ----------------------------
INSERT INTO `t_role` VALUES ('1', 'testNote1', 'tom1');
INSERT INTO `t_role` VALUES ('2', 'testNote1', 'tom1');
INSERT INTO `t_role` VALUES ('3', 'testNote1', 'tom1');
由于作者水平有限如有错误还请指出。