MyBatis和Hibernate一样,是一个优秀的持久层框架。已经说过很多次了,原生的jdbc操作存在大量的重复性代码(如注册驱动,创建连接,创建statement,结果集检测等)。框架的作用就是把这些繁琐的代码封装,这样可以让程序员专注于sql语句本身。
MyBatis通过XML或者注解的方式将要执行的sql语句配置起来,并通过java对象和sql语句映射成最终执行的sql语句。最终由MyBatis框架执行sql,并将结果映射成java对象并返回。
一,MyBatis的执行流程
二,MyBatis经典入门案例(原始DAO实现用户表的增删改查)
1,环境准备
mysql建库:
CREATE TABLE `user4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(20) , `password` varchar(20) , `age` int(11) , PRIMARY KEY (`id`) )
项目目录如下:
下面一一讲解这些文件。
2,全局配置文件:SqlMapConfig.xml
主要是2个标签:
environments-用于获取连接池连接,将来与spring整合时,这个就不要啦,由spring来配置数据库连接。
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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/user"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>
3,创建主体类:User.class
package com.jimmy.domain;
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
//get,set方法省略
}
4,创建映射文件:User.xml
映射文件就是框架的核心啦,下面这个文件就配置了java对象与数据库表之间的映射。
我们看到,其中4个标签:select,insert ,delete ,update 分别对应着“查,增,删,改”操作。每个标签中还有一些属性,下面来解释下:
<?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属性,不然会报错,可看做包名-->
<mapper namespace="user">
<select id="findUserById" parameterType="int" resultType="com.jimmy.domain.User">
select * from user4 where id = #{id}
</select>
<select id="findUserAll" resultType="com.jimmy.domain.User">
select * from user4
</select>
<insert id="insertUser" parameterType="com.jimmy.domain.User">
insert into user4(username,password,age) values(#{username},#{password},#{age})
</insert>
<delete id="deleteUserById" parameterType="int">
delete from user4 where id=#{id}
</delete>
<update id="updateUserPassword" parameterType="com.jimmy.domain.User">
update user4 set password=#{password} where id=#{id}
</update>
</mapper>
5,创建dao接口和实现类
package com.jimmy.dao;
import java.util.List;
import com.jimmy.domain.User;
// 接口
public interface UserDao {
public User findUserById(int id) throws Exception ;
public List<User> findAllUsers() throws Exception;
public void insertUser(User user) throws Exception;
public void deleteUserById(int id) throws Exception;
public void updateUserPassword(User user) throws Exception;
}
package com.jimmy.dao.impl;
import java.io.InputStream;
import java.util.List;
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 com.jimmy.dao.UserDao;
import com.jimmy.domain.User;
// 实现类
public class UserDaoImpl implements UserDao {
public User findUserById(int id) throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------
User user = session.selectOne("user.findUserById",id); //参数一:namespace.id
//--------------
session.close();
return user;
}
public List<User> findAllUsers() throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------------
List<User> users = session.selectList("user.findUserAll");
//----------------------
session.close();
return users;
}
public void insertUser(User user) throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------------
session.insert("user.insertUser", user);
session.commit(); //增删改,一定一定要加上commit操作
//----------------------
session.close();
}
public void deleteUserById(int id) throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------------
session.delete("user.deleteUserById", id);
session.commit(); //增删改,一定一定要加上commit操作
//----------------------
session.close();
}
public void updateUserPassword(User user) throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------------
session.update("user.updateUserPassword", user);
session.commit(); //增删改,一定一定要加上commit操作
//----------------------
session.close();
}
}
6,编写测试类
package com.jimmy.test;
import java.util.List;
import org.junit.Test;
import com.jimmy.dao.UserDao;
import com.jimmy.dao.impl.UserDaoImpl;
import com.jimmy.domain.User;
public class Test3 {
@Test
public void testFindUserById() throws Exception{
UserDao userDao = new UserDaoImpl();
User user = userDao.findUserById(7);
System.out.println(user);
}
@Test
public void testFindAllUser() throws Exception{
UserDao userDao = new UserDaoImpl();
List<User> findAllUsers = userDao.findAllUsers();
for (User user2 : findAllUsers) {
System.out.println(user2);
}
}
@Test
public void testInsertUser() throws Exception{
UserDao userDao = new UserDaoImpl();
User user = new User();
user.setUsername("张三");
user.setPassword("lalal");
user.setAge(12);
userDao.insertUser(user);
}
@Test
public void testDeleteUserById() throws Exception{
UserDao userDao = new UserDaoImpl();
userDao.deleteUserById(3);
}
@Test
public void testUpdateUserPassword() throws Exception{
UserDao userDao = new UserDaoImpl();
User user = new User();
user.setId(9);
user.setPassword("newpassword");
userDao.updateUserPassword(user);
}
}
至此,一个完整的Mybatis入门案例已经初步完成。
回过头来看DAO的实现类,原始dao开发存在一些问题:
三,Mapper代理开发模式
Mapper代理的开发方式,程序员只需要编写mapper接口(相当于dao接口)即可,而不同再写dao实现类啦。Mybatis会自动的为mapper接口生成动态代理实现类。不过要实现mapper代理的开发方式,需要遵循一些开发规范。
上面4句话的意思是:接口的包名,类名,参数,返回值分别对应着映射文件的namespace,id,parameterType,resultType。
下面来改造上面的例子。
1,环境准备,同上。
2,全局配置文件,同上。记得引用新的映射文件。
3,创建主题类,同上。
4,创建映射文件:UserMapper.xml。文件名一般加上“Mapper”。
下面这个文件跟原始dao编程只有一点不同,就是namespace值。
<?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属性,不然会报错,且mapper开发时设置为Mapper接口的全限定名-->
<mapper namespace="com.jimmy.dao.UserMapper">
<select id="findUserById" parameterType="int" resultType="com.jimmy.domain.User">
select * from user4 where id = #{id}
</select>
<select id="findUserAll" resultType="com.jimmy.domain.User">
select * from user4
</select>
<insert id="insertUser" parameterType="com.jimmy.domain.User">
insert into user4(username,password,age) values(#{username},#{password},#{age})
</insert>
<delete id="deleteUserById" parameterType="int">
delete from user4 where id=#{id}
</delete>
<update id="updateUserPassword" parameterType="com.jimmy.domain.User">
update user4 set password=#{password} where id=#{id}
</update>
</mapper>
5,创建Mapper接口,这里就没有实现类啦。
注意,函数一定要注意4点规范。
package com.jimmy.dao;
import java.util.List;
import com.jimmy.domain.User;
public interface UserMapper {
public User findUserById(int id);
public List<User> findUserAll();
public void insertUser(User user);
public void deleteUserById(int id);
public void updateUserPassword(User user);
}
6,编写测试类
package com.jimmy.test;
import java.io.InputStream;
import java.util.List;
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 com.jimmy.dao.UserMapper;
import com.jimmy.domain.User;
public class Test1 {
@Test
public void findUserByID() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.findUserById(2);
System.out.println(user);
//--------------
session.close();
}
@Test
public void findAll() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------------
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> user = mapper.findUserAll();
for (User user2 : user) {
System.out.println(user2);
}
//----------------------
session.close();
}
@Test
public void insertTest() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------------
User user = new User();
user.setUsername("lalala");
user.setPassword("asdf");
user.setAge(12);
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.insertUser(user);
session.commit();
//----------------------
session.close();
}
@Test
public void deleteUserById() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------------
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.deleteUserById(2);
session.commit();
//----------------------
session.close();
}
@Test
public void updateUserPassword() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------------
User user = new User();
user.setId(4);
user.setPassword("newPassword3");
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.updateUserPassword(user);
session.commit();
//----------------------
session.close();
}
}