本文共 14221 字,大约阅读时间需要 47 分钟。
ORM : Object RelationShip Mapping
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(sDAO)
mybaits的代码由github.com管理,下载地址:
依赖信息
org.mybatis mybatis 3.4.6
学习地址:
使用版本:3.4.6
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
MyBatis主要就完成2件事情
MyBatis的主要设计目的就是让我们对执行SQL语句时对输入输出的数据管理更加方便,所以方便地写出SQL和方便地获取SQL的执行结果才是MyBatis的核心竞争力。
mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的信息。
使用Maven创建项目,此步可以省略,详见
详见
org.mybatis mybatis 3.4.6
在resources目录中添加Mybatis的核心配置mybatis-config.xml
domain
bean
entity
pojo
在不同的场合使用的对象的分类:
po : Persistent Object (持久化对象)
vo:View Object (视图对象 ,PageBean)
dto: Data Transfer Object (数据传输对象 ,系统与系统之间传递数据)
bo : Business Object (业务对象)
什么是POJO:
POJO是Plain Old Java Objects的缩写,POJO实质上可以理解为简单的实体类,顾名思义POJO类的作用是方便程序员使用数据库中的数据表,对于广大的程序员,可以很方便的将POJO类当做对象来进行使用,当然也是可以方便的调用其get,set方法。
用户个人信息类Profile
public class User { private Integer id; //id号 private String name; //姓名 private Date birthday; //生日 private String gender; //性别 private String career; //职业 private String address; //地址 private String mobile; //手机号 private String picture; //图片链接 //getter和setter}
在resources目录下创建com.rj.mapper文件夹(注意要一个一个的创建),然后创建ProfileMapper.xml文件,注意,注解不能再sql语句标签中出现
select LAST_INSERT_ID(); insert into profile(name,birthday,gender,career,address,mobile,picture) values (#{name},#{birthday},#{gender},#{career},#{address},#{mobile},#{picture});update profile set name=#{name},birthday=#{birthday},gender=#{gender},career=#{career},address=#{address},mobile=#{mobile},picture=#{picture} where id=#{id}; delete from profile where id=#{id};
注意Resources类不要导错包【import org.apache.ibatis.io.Resources;】
public class MyBatisUtils { /** * 1.创建SqlSessionFactory,一个项目一个工厂,不能关闭 * 2.返回sqlSession的方法 */ private static SqlSessionFactory factory; static { //创建一个流读取mybatis-config.xml try { InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); factory = new SqlSessionFactoryBuilder().build(is); System.out.println("SqlSessionFactory初始化成功"); } catch (IOException e) { e.printStackTrace(); System.out.println("SqlSessionFactory初始化失败"); } } /*SqlSession全局不能唯一,线程可以唯一,而factory可以全局唯一*/ public static SqlSession openSession() { return factory.openSession(); }}
注意,增删改必须是事务处理,使用sqlSession.commit()提交才有效
/*dao接口*/public interface ProfileDao { ListfindAll(); Profile findByID(Integer id); void add(Profile profile); void update(Profile profile); void delete(Integer id); List findByName(String name);}/*dao的实现impl*/public class ProfileDaoImpl implements ProfileDao { @Override public List findAll() { SqlSession sqlSession = MyBatisUtils.openSession(); List profileList = sqlSession.selectList("test.findAll"); sqlSession.close(); return profileList; } @Override public Profile findByID(Integer id) { SqlSession sqlSession = MyBatisUtils.openSession(); Profile profile = sqlSession.selectOne("test.findById", id); sqlSession.close(); return profile; } @Override public void add(Profile profile) { SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.insert("test.add", profile); //必须提交事务 sqlSession.commit(); //这里可以直接获取自增后的id,因为myBatis中已经使用了selectKey标签 Integer id = profile.getId(); sqlSession.close(); } @Override public void update(Profile profile) { SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.update("test.update", profile); sqlSession.commit(); sqlSession.close(); } @Override public void delete(Integer id) { SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.delete("test.delete",id); sqlSession.commit(); sqlSession.close(); } @Override public List findByName(String name) { SqlSession sqlSession = MyBatisUtils.openSession(); List profile = sqlSession.selectList("test.findByName", name); sqlSession.close(); return profile; }}
public class ProfileTest { @Test public void testFindAll() { ProfileDao profileDao = new ProfileDaoImpl(); Listprofiles = profileDao.findAll(); for (Profile profile : profiles) { System.out.println(profile.toString()); } System.out.println("查询成功"); } @Test public void testFindById() { ProfileDao profileDao = new ProfileDaoImpl(); Profile profile = profileDao.findByID(2); System.out.println(profile.toString()); System.out.println("根据id查找成功"); } @Test public void testAdd() { ProfileDao profileDao = new ProfileDaoImpl(); Profile profile = new Profile(null, "龙在天", new Date(), "男", "外贸", "大明朝", "1566", null); profileDao.add(profile); System.out.println(profile.toString());//这里会打印出id号,因为在映射中获取了selectKey System.out.println("添加成功"); } @Test public void testDelete() { ProfileDao profileDao = new ProfileDaoImpl(); profileDao.delete(6); System.out.println("删除成功"); } @Test public void testUpdate() { ProfileDao profileDao = new ProfileDaoImpl(); Profile profile = new Profile(5, "不朽者", null, "未知", "机械兵种", "艾尔", "12357", null); profileDao.update(profile); System.out.println("更新成功"); } @Test public void testFindByName() { ProfileDao profileDao = new ProfileDaoImpl(); List profiles = profileDao.findByName("%张%"); for (Profile profile : profiles) { System.out.println(profile.toString()); } System.out.println("模糊查询成功"); }}
MyBatis的核心配置mybatis-config.xml中包含内容顺序如下:
properties(属性) settings(全局配置参数) typeAliases(类型别名) typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件) environments(环境集合属性对象) environment(环境子属性对象) transactionManager(事务管理) dataSource(数据源) mappers(映射器)
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/db_profile?useSSL=true&characterEncoding=utf8jdbc.username=rootjdbc.password=root
MyBatis 将按照下面的顺序来加载属性:(1)在 properties 元素体内定义的属性首先被读取。 (2)然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性
MyBatis支持的别名
别名 映射的类型_byte byte _long long _short short _int int _integer int _double double _float float _boolean boolean string String byte Byte long Long short Short int Integer integer Integer double Double float Float boolean Boolean date Date decimal BigDecimal bigdecimal BigDecimal map Map
Mapper配置的几种方法:1.使用相对于类路径的资源(现在的使用方式)如: 2. 使用mapper接口类路径如: 注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。3. 注册指定包下的所有mapper接口如: 注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
具体实现案例
开发规范:
Mapper接口开发方法只需要程序员编写Mapper接口【相当于Dao接口】,由MyBatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
路径相同,方法名相同,参数名相同,返回值相同
前面讲解的操作步骤,映射文件Mapper都是放到了java下的【resources】中,这里我们将其放到mapper包下【相当于dao层】,但是maven无法找到对应的文件,所以要在pom.xml文件中导入如下内容:
src/main/java **/*.xml false src/main/resources **/*.xml **/*.properties false
mybatis-config.xml还是在resources中
在com.rj.mapper包中添加ProfileMapper.xml文件
select LAST_INSERT_ID(); insert into profile(name,birthday,gender,career,address,mobile,picture) values (#{name},#{birthday},#{gender},#{career},#{address},#{mobile},#{picture});update profile set name=#{name},birthday=#{birthday},gender=#{gender},career=#{career},address=#{address},mobile=#{mobile},picture=#{picture} where id=#{id}; delete from profile where id=#{id};
在com.rj.mapper包中添加ProfileMapper.java接口
public interface ProfileMapper { ListfindAll(); Profile findById(Integer id); void add(Profile profile); void update(Profile profile); void delete(Integer id); List findByName(String name);}
public class ProfileMapperTest { @Test public void testFindAll() { SqlSession sqlSession = MyBatisUtils.openSession(); //获取ProfileMapper接口的代理的实现类,从而得到实现类 ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); Listprofiles = profileMapper.findAll(); for (Profile profile : profiles) { System.out.println(profile.toString()); } sqlSession.close(); System.out.println("查询成功"); } @Test public void testFindById() { SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); Profile profile = profileMapper.findById(2); System.out.println(profile.toString()); System.out.println("根据id查找成功"); } @Test public void testAdd() { SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); Profile profile = new Profile(null, "打飞机", new Date(), "男", "用品", "日本", "2020", null); profileMapper.add(profile); //必须提交,否则不能到数据库 sqlSession.commit(); //必须关闭流 sqlSession.close(); System.out.println("添加成功"); } @Test public void testDelete() { SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); profileMapper.delete(8); sqlSession.commit(); sqlSession.close(); System.out.println("删除成功"); } @Test public void testUpdate() { SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); Profile profile = new Profile(5, "不朽者", null, "未知", "机械兵种", "艾尔", "12357", null); profileMapper.update(profile); sqlSession.commit(); sqlSession.close(); System.out.println("更新成功"); } @Test public void testFindByName() { SqlSession sqlSession = MyBatisUtils.openSession(); ProfileMapper profileMapper = sqlSession.getMapper(ProfileMapper.class); List profiles = profileMapper.findByName("%张%"); for (Profile profile : profiles) { System.out.println(profile.toString()); } System.out.println("模糊查询成功"); }}
注意:
selectOne和selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。namespace
MyBatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。FreeMyBatis plugin,可以方便在mapper映射文件和接口之间进行转换和检查错误
转载地址:http://ppgzi.baihongyu.com/