mybatis的学习笔记(一)
mybatis是面向数据库的持久层框架
一、mybatis入门工程搭建
- 导入依赖jar包
- 配置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>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql:///数据库名?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="密码" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource="mybatis/user.xml"/>
</mappers>
</configuration>
- 配置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
- 在工程下创建实体类
- 配置sql查询的映射文件
<?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是命名空间,用于隔离sql语句 -->
<mapper namespace="user">
<!-- id:sql语句的唯一标识
parameterType:入参的数据类型
resultType:返回结果的的数据类型
#{}:占位符,相当于jdbc中的?
-->
<select id="getUserById" parameterType="int" resultType="com.mybatis.pojo.User">
select `id`,
`username`,
`birthday`,
`sex`,
`address`
from `user`
where id=#{id}
</select>
</mapper>
- 加载映射文件
实现功能:根据用户id查找用户信息
- 测试程序:访问数据库
package com.mybatis.text;
import java.io.IOException;
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.mybatis.pojo.User;
import com.mybatis.utils.SqlSessionFactoryUtils;
public class MybatisTest {
@Test
public void getUserById() throws IOException{
//加载核心配置文件
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
//创建一个核心配置文件的输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过输入流创建工厂
SqlSessionFactory sqlSessionFactory = ssfb.build(inputStream);
//创建sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行查询
User user = sqlSession.selectOne("user.getUserById",10);
System.out.println(user);
sqlSession.close();
}
- 抽取SqlSessionFactoryUtils工具类,共享SqlSessionFactory创建过程
package com.mybatis.utils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
static{
//加载核心配置文件
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
try {
//创建一个核心配置文件的输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过输入流创建工厂
sqlSessionFactory = ssfb.build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取SqlSessionFactory工厂
* @return
*/
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
实现功能:添加用户
- 配置sql查询的配置文件(自增返回)
<!-- 插入用户 -->
<insert id="insertUser" parameterType="com.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!-- selectKey:主键返回
keyProperty:返回的主键属性
resultType:返回类型
order/before:指定什么时候执行selectKey
-->
<!-- <selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey> -->
insert into `user`
(`username`,
`birthday`,
`sex`,
`address`
)
values(#{username},
#{birthday},
#{sex},
#{address});
</insert>
- 测试程序
@Test
public void insertUser(){
//获取工厂
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
//创建sqlSession对象,在openSession中自动设置提交事务
SqlSession sqlSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setUsername("kaly");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("奥克兰");
sqlSession.insert("user.insertUser",user);
System.out.println(user);
//手动提交事务
//sqlSession.commit();
sqlSession.close();
}
- UUID返回主键
<!-- useGeneratedKeys:标识插入使用自增id
keyProperty:与useGeneratedKeys配套使用,用于绑定主键接收的pojo属性
-->
<insert id="insertUserUUID" parameterType="com.itheima.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>
mybatis架构图
二、动态代理dao包装
注意;动态代理dao包装,只有接口,没有实现类
- 开发规则
- namespace必需是接口的全路径名
- 接口的方法名必需与映射文件的sql id一致
- 接口的输入参数必需与映射文件的parameterType类型一致
- 接口的返回类型必须与映射文件的resultType类型一致
- 开发步骤
- 创建UserMapper.xml映射文件
<!-- 把user.xml拿过来,修改namespace即可 -->
<!-- namespace是命名空间,用于隔离sql语句 -->
<!-- 动态代理开发规则
1.namespace必须是接口的全路径名
2.接口的方法名必须与id一致
3.接口的入参必须与parameterType类型一致
4.接口的返回值必须与resultType类型一致
-->
<mapper namespace="com.mybatis.mapper.UserMapper">
- 创建UserMapper接口
package com.mybatis.mapper;
import java.util.List;
import com.mybatis.pojo.User;
/**
* 动态代理dao包装,只有接口,没有实现类
* @author lenovo
*
*/
public interface UserMapper {
/**根据用户ID查询用户信息
* @param id
* @return
*/
User getUserById(Integer id);
/**
* 根据用户名查找用户列表
* @param name
* @return
*/
List<User> getUserByUserName(String name);
/**
* 添加用户
* @param user
*/
void insertUser(User user);
}
- 加载UserMapper.xml
- 测试动态代理Dao
@Test
public void testInsertUser() {
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(true);
//获取接口的代理实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("鲁尼");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("奥克兰");
userMapper.insertUser(user);
sqlSession.close();
}
- 在SqlMapConfig.xml中添加映射文件
<!-- 加载映射文件 -->
<mappers>
<mapper resource="mybatis/user.xml"/>
<mapper resource="mybatis/UserMapper.xml"/>
</mappers>
SqlMapConfig.xml配置
- SqlMapConfig.xml中配置内容和顺序:
properties(属性), settings(全局配置参数), typeAliases(类型别名), typeHandlers(类型处理器), objectFactory(对象工厂),
objectWrapperFactory , reflectorFactory?, plugins(插件), environments(环境子属性对象), databaseIdProvider?, mappers(映射器) - properties属性核心文件配置
<!-- 加载规则,首先加载标签内部属性,再加载外部文件,名称相同时,外部文件会替换相同名称的内部属性 -->
<properties resource="jdbc.properties">
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/>
</properties>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
- typeAliases自定义别名
<typeAliases>
<!-- 单个别名定义 -->
<!-- <typeAlias type="com.itheima.mybatis.pojo.User" alias="user"/> -->
<!-- 别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名为类名,不区分大小写-->
<package name="com.mybatis.pojo"/>
</typeAliases>
映射文件中返回类型调用直接使用类名,不区分大小写
<select id="getUserById" parameterType="int" resultType="User">
- mappers映射器
<mappers>
<!-- 第一种方式,加载 resource-->
<mapper resource="mapper/user.xml"/>
<!-- <mapper resource="mapper/UserMapper.xml"/> -->
<!-- 第二种方式,class扫描器要求:
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<!-- <mapper class="com.mybatis.mapper.UserMapper"/> -->
<!-- 第三种方式,包扫描器要求(推荐使用此方式):
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<package name="com.itheima.mybatis.mapper"/>
</mappers>