Mybatis 入门
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
一、理解什么是MyBatis?
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。 MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索。
MyBatis 可以使用简单的XML 或注解用于配置和原始映射,将接口和 Java 的 POJO( Plain Old Java Objects,普通的Java 对象)映射成数据库中的记录.
1). MyBatis提供3种语言实现的版本,包括:java,.NET和Ruby.
2). 它提供的持久层框架包括SQL Maps和Data Access Object(DAO)
3). MyBatis和Hibernate的对比?
mybatis提供一种半自动话的实现。
Hibernate提供了一种全面的数据库封装技术,全自动ORM实现了POJO和数据库表的映射,以及SQL的自动生成和执行。可以不用写任何SQL
mybatis的着力点在于POJO和SQL之间的映射关系,需要手动去写sql。
二、简单例子(快速入门)
1)创建java maven project
2)引入依赖
<dependencies>
<!-- Mysql驱动包 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>3)创建数据库数据(mysql)
create table user(
id int not null primary key auto_increment,
name varchar(20),
age int(4),
sex varchar(20));4)**添加配置文件
mysql 驱动配置jdbc.properties(这样可以优化性能)
mysql_driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=root
password=123456
添加log4j.properties
#Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output…
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
添加mybatis配置文件mybatis.cfg.xml
MyBatis的xml配置文件包含了设置和影响MyBatis行为的属性,XML配置文件的层次饥结构如下:
Configuration
Properties属性
Settings设置
typeAliases类型别名
typeHandlers类型处理器
ObjectFactory对象工厂
Plugins插件
Environments环境
Environment环境变量
transactionManager事物管理器
datasource数据源
mappers映射器
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties"/>
<settings>
<!--选择日志系统-->
<!--<setting name="logImpl" value="STDOUT_LOGGING" />-->
<setting name="logImpl" value="LOG4J" />
</settings>
<typeAliases>
<typeAlias alias="User" type="com.mybatis.vo.User"/>
</typeAliases>
<environments default="mysql"><!--环境集合-->
<environment id="mysql">
<!--指定事务管理类型, 使用jdbc的提交和回滚设置-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED"><!--缓存jdbc的链接/含有链接池连接类型-->
<property name="driver" value="${mysql_driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- Using mapper interface classes -->
<mapper class="com.mybatis.mapper.UserMapper"/>
<!-- Using classpath relative resources -->
<mapper resource="com/mybatis/mapper/UserMapper.xml"/>
</mappers>
</configuration>a. MyBatis 内置日志工厂基于运行时自省机制选择合适的日志工具。它会使用第一个查找得到的工具(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。
logImpl 可选的值有:
SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING
默认值:
Not set
如需对 XML 文件记录日志,只要对命名空间增加日志记录功能即可:
log4j.logger.org.mybatis.example.BlogMapper=TRACE
b. transactionManager 事务管理器
type=”JDBC|MANAGER” ( JdbcTransaction 和 ManagedTransaction )
JdbcTransaction管理机制:即利用java.sql.Connection对象完成对事务的提交(commit())、
回滚(rollback())、关闭(close())等
ManagedTransaction管理机制:这种机制MyBatis自身不会去实现事务管理,
而是让web容器如(JBOSS,Weblogic)来实现对事务的管理
注意:如果我们使用MyBatis构建本地程序,即不是WEB程序,若将type设置成”MANAGED”,那么,我们执行的任何update操作,即使我们最后执行了commit操作,数据也不会保留,不会对数据库造成任何影响。因为我们将MyBatis配置成了“MANAGED”,即MyBatis自己不管理事务,而我们又是运行的本地程序,没有事务管理功能,所以对数据库的update操作都是无效的。
c. dataSource 数据源
type=”POOLED” 使用mybatis自带的数据连接池
type=”UNPOOLED” 直接的jdbc 不用连接池
type=”JNDI” 用户自身配置的 数据连接池
5)创建对应的实体对象
package com.mybatis.vo;
public class User {
private Integer id;
private String name;
private Integer age;
private String sex;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
6)创建方法接口UserMapper.java和定义操作t_user表的sql映射文件UserMapper.xml
提供简单的增删改查数据信息。
package com.mybatis.mapper;
import com.mybatis.vo.User;
public interface UserMapper {
public int addUser(User user);
public int deleteUserById(int id);
public int updateUser(User user);
public User selectByUserId(int id);
}SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
UserMapper.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">
<mapper namespace="com.mybatis.mapper.UserMapper">
<!-- 自定义返回结果集 -->
<resultMap id="userMap" type="User">
<id property="id" column="id" javaType="java.lang.Integer"></id>
<result property="name" column="name" javaType="java.lang.String"></result>
<result property="age" column="age" javaType="java.lang.Integer"></result>
<result property="sex" column="sex" javaType="java.lang.String"></result>
</resultMap>
<insert id="addUser" parameterType="User" >
insert into user (name, age, sex) values (#{name}, #{age}, #{sex});
</insert>
<delete id="deleteUserById" parameterType="int">
delete from user where id =#{id};
</delete>
<update id="updateUser" parameterType="User">
update user set name=#{name}, age=#{age}, sex=#{sex} where id=#{id};
</update>
<select id="selectByUserId" parameterType="int" resultMap="userMap">
select * from user where id=#{id};
</select>
</mapper>7)测试类
package com.mybatis.mapper;
import com.mybatis.vo.User;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class UserMapperTest {
@Test
public void testAddUser() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
//4. 创建会话
SqlSession session = sqlSessionFactory.openSession(true);
User user = new User();
user.setName("林黛玉");
user.setAge(18);
user.setSex("女");
//使用全限定名来调用映射方法
// session.insert("com.mybatis.mapper.UserMapper.addUser", user);
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.addUser(user);
session.close();
}
private SqlSessionFactory getSqlSessionFactory() throws IOException {
//1. 获取mybatis核心配置文件
String source = "mybatis-config.xml";
//2. 转换为流
InputStream in = Resources.getResourceAsStream(source);
//3. 创建会话工厂
return new SqlSessionFactoryBuilder().build(in);
}
@Test
public void testDeleteUserById() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession(true);
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.deleteUserById(3);
session.close();
}
@Test
public void testGetUser() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession(true);
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectByUserId(1);
System.out.println(user);
session.close();
}
@Test
public void testUpdateUser() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession session = sqlSessionFactory.openSession(true);
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectByUserId(1);
user.setName("小李");
user.setAge(30);
mapper.updateUser(user);
session.close();
}
}