MyBatis概述
jdbc问题
代码冗余,操作复杂
需要执行指定的sql,传入执行的参数即可。
mybatis的作用:简化我们操作数据库的代码
什么是框架
框架: 其实就是对java代码的一些封装 (骨架-人家已经写好一部分代码)
所谓的框架, 百分之九十基本都是 半成品框架( 拿到框架的代码 不能直接使用 还需要自己做简单的修改 )
SSM: spring springmvc mybatis 非常重要(开发要用的东西)
ORM映射
ORM :对象关系映射
对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。
满足ORM 的技术: hibernate(老技术 ,效率问题 , 完全不需要写sql语句 sql自动生成 只需要操作对象即可 )
我们现在所学的mybatis , 半ORM半自动的框架 , sql语句自己写(提高效率)
MyBatis入门
开发步骤
1.导入jar包:mybatis的jar包,mysql的驱动包
2.准备实体类和数据库
实体类
public class TUser {
//属性名和数据库的字段名可以不一致
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
3.使用xml的配置方式描述ORM的映射关系
主配置文件(一个):描述的是操作的数据库是哪里的
映射文件(多个):每一个映射文件,描述的是一个表和实体类的关系。
4.编写代码
对象概述
java中的对象:
- 属性私有化
- 提供get/set方法
- 提供无参构造(前提是我们手动加了有参构造的时候) :为了底层准备 Class.forName(“全限定类名”).newInta…
- 对象应该实现序列化接口(不是必须的) : 对象需要保存到本地 或者 通过数据传输过程 必须实现序列化接口
- 属性的定义尽量使用包装类(不是必须的) : int (默认值为0 ) Integer (默认值为null) 数据库int的默认值 是null而不是0
dao层:
//保存user
public void save(TUser tUser) throws Exception {
//1.加载主配置文件 -> 得到了 数据源对象
InputStream is = Resources.getResourceAsStream("SqlSessionConfiguration.xml");
//2.创建解析主配置文件的对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.解析主配置文件 得到sqlSessionFactory对象 -> 得到了 数据源对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//4.通过sqlSessionFactory对象 拿到sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//5.操作对象 sqlSession 保存到数据库---------核心要点
//参数1: 映射文件中的namespace+id 找到sql语句 参数2: 需要添加到数据库中对象
sqlSession.insert("abcd.saveUser" , tUser);
//6.提交事务
sqlSession.commit();
//7.释放资源
sqlSession.close();
}
SqlSessionConfiguration.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>
<!--建议从官方网站抄-->
<!--environments :环境 default="development 开发环境" 使用的是哪个开发环境-->
<environments default="development">
<!--<environment id=""> 环境的id -->
<environment id="development">
<!--transactionManager 事务的配置 使用jdbc的事务-->
<transactionManager type="JDBC"></transactionManager>
<!--数据源配置 POOLED : 使用mybatis默认数据源 UNPOOLED :没有数据源 JNDI : 以后再提 -->
<dataSource type="POOLED">
<!--基本四项-->
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///day07"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<!--将映射文件同时加载到程序中-->
<mappers>
<!--加载映射文件-->
<mapper resource="com/llz/dao/UserDaoMapper.xml"></mapper>
</mappers>
</configuration>
UserDaoMapper.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">
<!--
mapper 映射配置
namespace="" 目前随意 唯一即可
-->
<mapper namespace="abcd">
<!--
insert 表示增加 update 表示修改 select 表示查询 delete删除
id : 在整个映射文件中唯一 , 能够找到这个配置即可
parameterType="" : 传入的实体类的全限定类名
标签体的内部写sql语句
特殊语法: #{实体类对象中的get方法 去掉get首字母小写的过程 不是属性名称}
-->
<insert id="saveUser" parameterType="com.llz.domain.TUser">
insert into user values(null , #{username} , #{birthday} , #{sex} , #{address})
</insert>
</mapper>
小技巧-配置模板
添加组:
添加模板:
动态代理方式实现CURD(特别重要)
mybatis提供两种方式操作数据库
1.原生方式(需编写大量代码)
2.不需要编写复杂代码,代码都是mybatis底层动态生成——>底层使用的是传统方式代码。
开发步骤
- 导入jar
- 创建实体类
- 创建测试类
- 创建dao的接口层 由mybatis提供实现类
- 主配置文件 (在src下创建)
- 映射文件(在跟dao同包下创建)
dao层接口:
public interface UserDao {
//增
public void save(TUser tUser);
//修改
public void updateUser(TUser tUser);
//删除
public void deleteById(int id);
//查询
public List<TUser> findAll();
}
映射配置文件:
<?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:不要随便乱写
上面是传统方式 : 只要能锁定方法即可
现在代理接口的方式: 需要给接口提供实现子类
Proxy.newInstance( 类加载器, 接口的class对象数组 , 处理接口类 )
-->
<mapper namespace="com.llz.dao.UserDao">
<!--
select 表示查询
id : 接口中的方法名称
resultType : 接口中方法的返回值
-->
<select id="findAll" resultType="com.llz.domain.TUser">
select * from user
</select>
<!--
增
id:找方法名称
parameterType : 参数的全限定类名
类型为:对象的时候 #{对象中的get方法名称}
对象里100个属性
参数有且仅有一个的情况(基本类型) 使用 #{任意值}
resultType : 接口中方法的返回值
insert into user values(null , #{username} ,#{birthday} , #{sex} , #{address})
insert into user values(#{id} , #{username} ,#{birthday} , #{sex} , #{address})
-->
<insert id="save" parameterType="com.llz.domain.TUser">
insert into user values(#{id} , #{username} ,#{birthday} , #{sex} , #{address})
</insert>
<!--删-->
<delete id="deleteById" parameterType="int">
delete from user where id = #{随便写}
</delete>
<!--改-->
<update id="updateUser" parameterType="com.llz.domain.TUser" >
update user set username = #{username},sex=#{sex},address=#{address} where id =#{id}
</update>
</mapper>
测试类:
public class TestDemo {
//查
@Test
public void select() throws Exception {
//获得工厂对象
SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
//获得sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//sqlSession.getMapper(接口的.class) -> 给接口 创建一个动态代理的实现子类
//UserDao userDao = new 实现子类() mybatis 自动产生
UserDao userDao = sqlSession.getMapper(UserDao.class);
//查询所有user
List<TUser> userList = userDao.findAll();
System.out.println(userList);
MyBatisUtils.commitAndClose(sqlSession);
}
//增
@Test
public void saveUser() throws Exception {
//获得工厂对象
SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
//获得sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建dao对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//创建对象
TUser tUser = new TUser();
//tUser.setId(123); -> private Integer id; 默认值null
tUser.setUsername("jack");
tUser.setSex("女");
tUser.setAddress("北京");
tUser.setBirthday(new Date());
//保存user
userDao.save(tUser);
MyBatisUtils.commitAndClose(sqlSession);
}
//改
@Test
public void update() throws Exception {
//获得工厂对象
SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
//获得sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建dao对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//创建对象
TUser tUser = new TUser();
tUser.setId(55);
tUser.setUsername("关德赟");
tUser.setSex("未知");
tUser.setAddress("昆明");
tUser.setBirthday(new Date());
//保存user
userDao.updateUser(tUser);
MyBatisUtils.commitAndClose(sqlSession);
}
//删
@Test
public void delete() throws Exception {
//获得工厂对象
SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
//获得sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建dao对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//保存user
userDao.deleteById(55);
MyBatisUtils.commitAndClose(sqlSession);
}
}
总结:
- 配置文件的位置 跟接口的位置保持一致(因为好找)
- namespace 跟 接口的全限定类名一致
- 配置文件中的属性id 跟 接口中的方法名一致
- 配置文件中属性返回值 跟接口方法返回值一致
- 配置文件中的属性参数传递 跟 接口中方法参数一致