- MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
Mybatis是面向sql的持久层框架,他封装了jdbc访问数据库的过程,我们开发,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。
1.需求列表
①根据用户ID查询用户信息
②根据用户名查找用户列表
③添加用户
④修改用户
⑤删除用户
2.工程搭建
1.导入依赖jar包,在课前资源中有
2.配置SqlMapConfig.xml,可参考课前资料
3.配置log4j.properties,可参考课前资料
4.在课前资料复制pojo到工程目录下
5.配置sql查询的映射文件,可参考课前资料
6.加载映射文件.
-
Mybatis访问数据库流程:
-
将sql语句配置到映射文件中
-
Mybatis的映射文件
namespace:命名空间,相当于javaclass的package,作用是对sql进行分类化管理,隔离sql语句。
映射文件配置好之后,要在全局映射文件(sqlMapConfig.xml)中添加映射文件
-
模糊查询(通过用户名称模糊查询用户信息)
-
查单条记录使用SelectOne:
//通过sqlsession操作数据库
//selectOne的第一个参数:配置文件中的namespace+statment的id
//selectOne的第二个参数:指定和映射文件锁匹配的parameterType类型的参数
//selectOne的结果是与映射文件所匹配的resultType类型的对象
//查找id为1的用户信息
User user = sqlsession.selectOne("test.findUserById",1);
//打印用户
System.out.print(user);
//关闭资源
sqlsession.close();
- 查多条记录使用selectList
SqlSession sqlsession = sqlsessionFactory.openSession();
List<User> list = sqlsession.selectList("test.findUserByName","张");
Sysout.out.pprint(list);
sqlsession.close();
- 添加用户
<!-- 添加用户,parametersType入参即用户类全路径,#{}相当于占位符?;
id可以不用写,因为数据库中id是自增
-->
<insert id="insertUser" parameterType="com.***.***.**">
INSERT INTO USER(username,birthday,sex,address)VALUE(#{username},#{birthday},#{sex},#{address});
</insert>
-
Mybatis之DAO
测试
-
MybatisDAO开发方法:
动态代理dao开发规则
1.namespace必需是接口的全路径名
2.接口的方法名必需与映射文件的sql id一致
3.接口的输入参数必需与映射文件的parameterType类型一致
4.接口的返回类型必须与映射文件的resultType类型一致
动态代理dao开发步骤
1.创建UserMapper.xml映射文件(把原来的user.xml复制按开发规则要求修改一下)
2.创建UserMapper接口(把原来的UserDao.java复制按开发规则要求修改一下)
3.加载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();
}
}
-
sqlMapConfig.xml配置文件如何配置?
-
属性核心文件配置
<!-- 加载规则,首先加载标签内部属性,再加载外部文件,名称相同时,会替换相同名称的内容 -->
<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>
<!-- 单个别名定义 -->
<!-- <typeAlias type="com.itheima.mybatis.pojo.User" alias="user"/> -->
<!-- 别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名为类名,不区分大小写-->
<package name="com.itheima.mybatis.pojo"/>
</typeAliases>
- mappers
<mappers>
<!-- 第一种方式,加载 resource-->
<mapper resource="mapper/user.xml"/>
<!-- <mapper resource="mapper/UserMapper.xml"/> -->
<!-- 第二种方式,class扫描器要求:
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<!-- <mapper class="com.itheima.mybatis.mapper.UserMapper"/> -->
<!-- 第三种方式,包扫描器要求(推荐使用此方式):
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<package name="com.itheima.mybatis.mapper"/>
</mappers>
- 输入映射:传递简单类型,使用#{}占位符,或者${}进行SQL语句的拼接;传递pojo对象,使用ognl表达式解析对象字段的值,#{}或 ${}括号中的值为pojo属性名称。
- 包装的pojo对象(对象里面有对象)
- 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">
<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用 -->
<mapper namespace="cn.edu.hpu.mybatis.mapper.UserMapper">
<!-- 在映射文件中配置很多sql语句 -->
<!-- 需求:通过id查询用户表的记录 -->
<!-- 通过select执行数据库查询,
id:标示映射文件中的sql,成为Statement的id
将sql语句封装到mappedStatement对象中,所以将id称为statement的id,
parameterType:指定输入参数的类型,
#{}标示一个占位符,
#{id}其中id表示接收输入参数的名称,如果输入参数是简单类型,那么#{}中的值可以任意(如value)。
resultType:指定sql输出结果的映射的java对象类型,
select指定resultType表示将单条记录映射成java对象-->
<select id="findUserById" parameterType="int" resultType="cn.edu.hpu.mybatis.PO.User">
SELECT * FROM USER WHERE id=#{id}
</select>
<!-- ${}:表示拼接sql串,将接收到的参数内容不加任何修饰拼接在sql中。
使用${}拼接sql,引起sql注入。
${}中只能使用value-->
<select id="findUserByUserName" parameterType="java.lang.String"
resultType="cn.edu.hpu.mybatis.PO.User">
select * from user where username like '%${value}%'
</select>
<!-- 添加用户
parameterType:指定输入参数类型是pojo(包括用户信息)
#{}中指定POJO的属性名,接收到POJO对象的属性值,mybatis通过OGNL获取对象的属性
-->
<insert id="insertUser" parameterType="cn.edu.hpu.mybatis.PO.User">
<!-- 将插入数据的主键返回,返回到user对象中。
SELECT_INSERT_ID():得到刚insert进去的主键值,只适用于自增主键
KeyProperty:将查询到主键值设置到parameterType指定对象的哪个属性。
order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
<!-- 使用MySql的UUID来生成主键
执行过程:
首先通过uuid()得到主键,将主键设置到user对象的id属性中
其次在insert执行时,从user对象中取出id属性值
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT uuid()
</selectKey>
insert into user(id,birthday,sex,address) value(#{id},#{birthday,jdbcType=DATE},#{sex},#{address})-->
insert into user(username,birthday,sex,address) value(#{username},#{birthday,jdbcType=DATE},#{sex},#{address})
</insert>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
<!-- 更新用户
分析:
需要传入用户的id,需要传入用户的更新信息.
parameterType指定user对象,包括id和更新信息(注意:id必须存在)
#{id}:从输入user对象中获取id属性值-->
<update id="updateUser" parameterType="cn.edu.hpu.mybatis.PO.User">
update user set username=#{username},birthday=#{birthday,jdbcType=DATE},sex=#{sex},address=#{address}
where id=#{id}
</update>
</mapper>