1 介绍
MyBatis是apache软件基金会下的一个开源项目,前身是Ibatis框架。2010年这个项目由apache软件基金会迁移到google code下,改名为MyBatis。2013年11月又迁移到了github。
MyBatis是一个持久层的框架,是对JDBC操作数据库的封装,使开发者只需要关注业务本身,不需要花费精力去处理加载驱动,创建数据库连接对象、创建statement语句对象、参数设置、结果集处理等一系列繁杂的代码过程。
MyBatis通过xml或者注解进行配置,将Java对象与sql语句中的参数自动映射生成最终执行的sql语句,并将sql语句执行结果自动映射成java对象,返回给业务层service应用。
2 入门程序
1. 配置项目pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yong</groupId>
<artifactId>MyBatisDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- mysql版本 -->
<mysql.version>5.1.30</mysql.version>
<!-- junit版本 -->
<junit.version>4.12</junit.version>
<!-- MyBatis版本号 -->
<mybatis.version>3.4.5</mybatis.version>
<!-- log4j日志包版本 -->
<slf4j.version>1.7.7</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<!-- mysql数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- MyBatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- log4j日志包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- junit依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2. 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
3. sqlMapConfig.xml
<?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>
<!-- 运行环境配置;default:默认使用的环境 -->
<environments default="develop">
<!-- id:环境标识 -->
<environment id="develop">
<!-- 事务配置,type="JDBC":使用JDBC事务 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源配置,POOLED:MyBatis框架的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>
4. User表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`sex` varchar(255) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`mobilephone` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;
5. User.java
package com.yong.po;
import java.util.Date;
public class User {
private Integer id; // int(11) NOT NULL AUTO_INCREMENT,
private String username; // varchar(255) DEFAULT NULL,
private String sex; // varchar(255) DEFAULT NULL,
private Date birthday; // date DEFAULT NULL,
private String mobilephone; // varchar(255) DEFAULT NULL,
private String email; // varchar(255) DEFAULT NULL,
private String password; // varchar(255) DEFAULT NULL,
public User() {
super();
}
public User(String username, String sex, Date birthday, String mobilephone, String email, String password) {
super();
this.username = username;
this.sex = sex;
this.birthday = birthday;
this.mobilephone = mobilephone;
this.email = email;
this.password = password;
}
public User(Integer id, String username, String sex, Date birthday, String mobilephone, String email,
String password) {
super();
this.id = id;
this.username = username;
this.sex = sex;
this.birthday = birthday;
this.mobilephone = mobilephone;
this.email = email;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getMobilephone() {
return mobilephone;
}
public void setMobilephone(String mobilephone) {
this.mobilephone = mobilephone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday
+ ", mobilephone=" + mobilephone + ", email=" + email + ", password=" + password + "]";
}
}
2.1 新增
1. Mapper映射文件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属性:名称空间,相当于java中package,用于防止sql语句名称冲突 -->
<mapper namespace="test">
<!-- mybatis针对每一种sql语句:新增/修改/删除/查询,提供了对应的标签:insert/update/delete/select -->
<!-- insert标签:用于放置新增sql语句
id属性:唯一区分一条sql语句
parameterType属性:输入参数类型
resultType属性:返回值类型
#{}:占位符,当参数传递的是pojo的时候,花括号中的内容是pojo的属性
查询主键:
useGeneratedKeys="true": 使用自动生成主键
keyColumn="id":表中列名
keyProperty="id":pojo中属性名 -->
<insert id="insert" parameterType="com.yong.po.User" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
<!-- selectKey标签:查询主键,说明:
keyColumn属性:主键字段(表)
keyProperty属性:主键属性(pojo)
resultType属性:指定主键字段类型
order属性:指定在insert语句执行前还是执行后,获取主键。
AFTER:在insert语句之后
BEFORE:在insert语句之前 -->
<!-- <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey> -->
insert into user (username, sex, birthday, mobilephone, email, password) values (#{username}, #{sex}, #{birthday}, #{mobilephone}, #{email}, #{password})
</insert>
</mapper>
2. 在sqlMapConfig配置文件中加载映射文件
<?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>
<!-- 运行环境配置;default:默认使用的环境 -->
<environments default="develop">
<!-- id:环境标识 -->
<environment id="develop">
<!-- 事务配置,type="JDBC":使用JDBC事务 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源配置,POOLED:MyBatis框架的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<!--加载User.xml映射文件,说明:resource属性:指定文件的位置-->
<mapper resource="sqlMap/User.xml"/>
</mappers>
</configuration>
3. 新增用户:
package com.yong.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
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.Before;
import org.junit.Test;
import com.yong.po.User;
public class MyBatisTest01 {
private SqlSessionFactory sqlSessionFactory = null;
@Before
public void initSqlSessionFactory() throws IOException {
// 加载MyBatis主配置文件
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 读取配置文件
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// sqlSessionFactory对象是MyBatis框架的核心对象,一个应用只需要一个(单例设计模式应用)
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
@Test
public void create() throws IOException {
// 使用sqlSessionFactory对象,创建sqlSession对象
// sqlSession对象,相当于jdbc中的connection对象
// sqlSession对象,线程不安全,每一个执行的方法都需要创建自己的sqlSession对象
// sqlSessionFactory.openSession()默认false,ture:自动提交事务, false:不自动提交事务
SqlSession sqlSession = sqlSessionFactory.openSession(true);
User user = new User("Yong", "男", new Date(), "186********", "110*******@qq.com", "123456");
System.out.println("新增前:"+user.toString());
// statement参数:执行的sql语句(名称空间+sql语句id)
// parameter参数:传入的参数值
sqlSession.insert("test.insert", user);
// 提交事务,推荐在获取sqlSession对象的时候打开事务自动提交
// sqlSession.commit();
System.out.println("新增后:"+user.toString());
sqlSession.close();
}
}
2.1.1 提交事务
方式一:
SqlSession sqlSession = sqlSessionFactory.openSession(true);
默认false,ture:自动提交事务, false:不自动提交事务
方式二:
sqlSession.commit();
2.1.2 获取新增后的主建
方式一:
在insert标签中声明使用自动生成的主键
<insert id="insert" parameterType="com.yong.po.User" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
方式二:
在insert标签中添加selectKey标签:
<!-- selectKey标签:查询主键,说明:
keyColumn属性:主键字段(表)
keyProperty属性:主键属性(pojo)
resultType属性:指定主键字段类型
order属性:指定在insert语句执行前还是执行后,获取主键。
AFTER:在insert语句之后
BEFORE:在insert语句之前 -->
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
2.2 查询
2.2.1 精确查询
1. 映射文件User.xml
<!-- select标签:用于放置查询sql语句
#{}占位符,相当于jdbc中的问号?当参数传递的是java简单类型的时候,花括号中的内容可以是任意字符串 -->
<select id="queryUserById" parameterType="int" resultType="com.yong.po.User">
select * from user where id=#{id}
</select>
2. 在sqlMapConfig配置文件中加载映射文件
<!-- 加载映射文件 -->
<mappers>
<!--加载User.xml映射文件,说明:resource属性:指定文件的位置-->
<mapper resource="sqlMap/User.xml"/>
</mappers>
3. 精确查询
@Test
public void queryUserById() throws IOException {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.queryUserById", 1);
System.out.println(user);
sqlSession.close();
}
2.2.2 模糊查询
1. 映射文件User.xml
<select id="queryUserByUsername" parameterType="string" resultType="com.yong.po.User">
<!-- ${}拼接符,当参数传递的是java简单类型的时候,花括号中的内容只能是:value -->
select * from user where username like '%${value}%'
</select>
2. 在sqlMapConfig配置文件中加载映射文件
<!-- 加载映射文件 -->
<mappers>
<!--加载User.xml映射文件,说明:resource属性:指定文件的位置-->
<mapper resource="sqlMap/User.xml"/>
</mappers>
3. 模糊查询
@Test
public void queryUserByName() {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> users = sqlSession.selectList("test.queryUserByUsername", "Y");
System.out.println(users);
sqlSession.close();
}
2.3 修改
1. 映射文件User.xml
<update id="update" parameterType="com.yong.po.User">
<!-- #{}:占位符,当参数传递的是pojo的时候,花括号中的内容是pojo的属性 -->
update user set Username = #{username}, sex = #{sex} where id = #{id}
</update>
2. 在sqlMapConfig配置文件中加载映射文件
<!-- 加载映射文件 -->
<mappers>
<!--加载User.xml映射文件,说明:resource属性:指定文件的位置-->
<mapper resource="sqlMap/User.xml"/>
</mappers>
3. 模糊查询
@Test
public void update() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setId(2);
user.setUsername("Jing");
user.setSex("女");
sqlSession.update("test.update", user);
//提交事务
// sqlSession.commit();
sqlSession.close();
}
2.4 删除
1. 映射文件User.xml
<delete id="delete" parameterType="int">
delete from user where id = #{id}
</delete>
2. 在sqlMapConfig配置文件中加载映射文件
<!-- 加载映射文件 -->
<mappers>
<!--加载User.xml映射文件,说明:resource属性:指定文件的位置-->
<mapper resource="sqlMap/User.xml"/>
</mappers>
3. 模糊查询
@Test
public void delete() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
sqlSession.update("test.delete", 2);
//提交事务
// sqlSession.commit();
sqlSession.close();
}