Mybatis介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
Mybatis是面向sql的持久层框架,他封装了jdbc访问数据库的过程,我们开发,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。
Demo演练
根据用户ID查询用户信息
映射文件与sql
<!-- id:statementId
resultType:查询结果集的数据类型
parameterType:查询的入参
-->
<select id="getUserById" parameterType="int" resultType="com.itpx.mybatis.pojo.User" >
SELECT * FROM USER WHERE id = #{id1}
</select>
MyBatis访问数据库代码
@Test
public void testGetUserByid() throws IOException {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
// 查找配置文件创建输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 加载配置文件,创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sfb.build(inputStream);
// 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行查询,参数一:要查询的statementId ,参数二:sql语句入参
User user = sqlSession.selectOne("user.getUserById", 1);
// 输出查询结果
System.out.println(user);
// 释放资源
sqlSession.close();
}
抽取SqlSessionFactoryUtils工具类,共享SqlSessionFactory创建过程
/**
* SqlSessionFactory工具类
*
* @author
*
*/
public class SqlSessionFactoryUtils {
/**
* 单例SqlSessionFactory
*/
private static SqlSessionFactory sqlSessionFactory;
static {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
try {
// 查找配置文件创建输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 加载配置文件,创建SqlSessionFactory对象
sqlSessionFactory = sfb.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取单例SqlSessionFactory
* @return
*/
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
根据用户名查找用户列表
映射文件与sql
<!-- resultType:如果要返回数据集合,只需设定为每一个元素的数据类型 -->
<select id="getUserByName" parameterType="string" resultType="com.itpx.mybatis.pojo.User">
<!-- SELECT * FROM USER WHERE username LIKE #{name} -->
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
MyBatis访问数据库代码
@Test
public void getUserByName() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//List<User> users = sqlSession.selectList("user.getUserByName", "%张%");
List<User> users = sqlSession.selectList("user.getUserByName", "张");
for (User user : users) {
System.out.println(user);
}
// 释放资源
sqlSession.close();
}
添加用户
映射文件与sql
<insert id="insertUser" parameterType="com.itpx.mybatis.pojo.User">
INSERT INTO USER
(`username`,
`birthday`,
`sex`,
`address`)
VALUES (#{username},
#{birthday},
#{sex},
#{address});
</insert>
MyBatis访问数据库代码
@Test
public void testInsertUser() throws IOException {
// 创建SqlSession对象
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
User user = new User();
user.setUsername("张飞");
user.setAddress("深圳市黑马");
user.setBirthday(new Date());
user.setSex("1");
// 执行插入
sqlSession.insert("user.insertUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
Mysql自增返回
映射文件与sql
<!-- useGeneratedKeys:标识插入使用自增id
keyProperty:与useGeneratedKeys配套使用,用于绑定主键接收的pojo属性
-->
<insert id="insertUserKey" parameterType="com.itpx.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!-- selectKey:用于配置主键返回
keyProperty:要绑定的pojo属性
resultType:属性数据类型
order:指定什么时候执行,AFTER之后
-->
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO USER
(`username`,
`birthday`,
`sex`,
`address`,
`uuid2`)
VALUES (#{username},
#{birthday},
#{sex},
#{address},
#{uuid2});
</insert>
Mysql的uuid返回主键
注:在使用uuid之前数据库user表要先加上uuid2字段、user的pojo也要加上相应属性
<!-- useGeneratedKeys:标识插入使用自增id
keyProperty:与useGeneratedKeys配套使用,用于绑定主键接收的pojo属性
-->
<insert id="insertUserUUID" parameterType="com.itpx.mybatis.pojo.User">
<!-- selectKey:用于配置主键返回
keyProperty:要绑定的pojo属性
resultType:属性数据类型
order:指定什么时候执行,BEFORE之前
-->
<selectKey keyProperty="uuid2" resultType="string" order="BEFORE">
SELECT UUID()
</selectKey>
INSERT INTO USER
(`username`,
`birthday`,
`sex`,
`address`,
`uuid2`)
VALUES (#{username},
#{birthday},
#{sex},
#{address},
#{uuid2});
</insert>
修改用户
<update id="updateUser" parameterType="com.itpx.mybatis.pojo.User">
UPDATE USER SET username = #{username} WHERE id = #{id}
</update>
删除用户
<delete id="deleteUser" parameterType="int">
DELETE FROM `user` WHERE `id` = #{id1}
</delete>
Mybatis架构图
Mybatis Dao开发方式
Dao需求
- 根据用户ID查询用户信息
- 根据用户名查找用户列表
- 添加用户
配置映射文件按照上面配置即可
新建UserDao接口
public interface UserDao {
/**根据用户ID查询用户信息
* @param id
* @return
*/
User getUserById(Integer id);
/**
* 根据用户名查找用户列表
* @param name
* @return
*/
List<User> getUserByUserName(String name);
/**
* 添加用户
* @param user
*/
void insertUser(User user);
}
新建UserDaoImpl接口实现类
public class UserDaoImpl implements UserDao {
@Override
public User getUserById(Integer id) {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
User user = sqlSession.selectOne("user.getUserById", id);
sqlSession.close();
return user;
}
@Override
public List<User> getUserByUserName(String name) {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
List<User> list = sqlSession.selectList("user.getUserByName", name);
sqlSession.close();
return list;
}
@Override
public void insertUser(User user) {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
sqlSession.insert("user.insertUser", user);
sqlSession.commit();
sqlSession.close();
}
}
单元测试
public class UserDaoTest {
@Test
public void testGetUserById() {
UserDao userDao = new UserDaoImpl();
User user = userDao.getUserById(30);
System.out.println(user);
}
@Test
public void testGetUserByUserName() {
UserDao userDao = new UserDaoImpl();
List<User> list = userDao.getUserByUserName("张");
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testInsertUser() {
UserDao userDao = new UserDaoImpl();
User user = new User();
user.setUsername("张飞3");
user.setAddress("深圳市");
user.setBirthday(new Date());
user.setSex("1");
userDao.insertUser(user);
}
}
官方推荐,接口动态代理
动态代理dao开发规则
- namespace必需是接口的全路径名
- 接口的方法名必需与映射文件的sql id一致
- 接口的输入参数必需与映射文件的parameterType类型一致
- 接口的返回类型必须与映射文件的resultType类型一致
动态代理dao开发步骤
创建UserMapper.xml映射文件(按照上面配置即可)
创建UserMapper接口(把原来的UserDao.java复制按开发规则要求修改一下)
加载UserMapper.xml
单元测试
public class UserMapperTest {
@Test
public void testGetUserById() {
// 加载配置得到SqlSession
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
// 获取代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 查询数据
User user = userMapper.getUserById(30);
System.out.println(user);
// 关闭资源
sqlSession.close();
}
@Test
public void testGetUserByUserName() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
// 获取代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 查询数据
List<User> list = userMapper.getUserByName("张");
for (User user : list) {
System.out.println(user);
}
// 关闭资源
sqlSession.close();
}
@Test
public void testInsertUser() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("张飞飞");
user.setAddress("深圳市");
user.setBirthday(new Date());
user.setSex("1");
userMapper.insertUser(user);
// 提交事务
sqlSession.commit();
// 关闭资源
sqlSession.close();
}
}
SqlMapConf.xml配置
配置内容和顺序
properties
属性核心文件配置
<!-- 加载规则,首先加载标签内部属性,再加载外部文件,名称相同时,会替换相同名称的内容 -->
<properties resource="jdbc.properties">
<property name="jdbc.username" value="root1"/>
<property name="jdbc.password" value="root"/>
</properties>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
typeAliases
mybatis默认支持java基本数据类型的别名识别
自定义别名
<typeAliases>
<!-- 单个别名定义 -->
<!-- <typeAlias type="com.itpx.mybatis.pojo.User" alias="user"/> -->
<!-- 别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名为类名,不区分大小写-->
<package name="com.itpx.mybatis.pojo"/>
</typeAliases>
mappers
<mappers>
<!-- 第一种方式,加载 resource-->
<mapper resource="mapper/user.xml"/>
<!-- <mapper resource="mapper/UserMapper.xml"/> -->
<!-- 第二种方式,class扫描器要求:
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<!-- <mapper class="com.itpx.mybatis.mapper.UserMapper"/> -->
<!-- 第三种方式,包扫描器要求(推荐使用此方式):
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<package name="com.itpx.mybatis.mapper"/>
</mappers>