关于myBatis以前一点都没有了解,但是好多招聘上面都是要求mybatis.现在开始基础学习下:
MyBatis的前身叫iBatis,本是apache的一个开源项目, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录。
1)MyBATIS 目前提供了三种语言实现的版本,包括:Java、.NET以及Ruby。(我主要学习java,就讲java的使用)
2)它提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。
3)mybatis与hibernate的对比?
mybatis提供一种“半自动化”的ORM实现。
这里的“半自动化”,是相对Hibernate等提供了全面的数据库封装机制的“全自动化”ORM实现而言,“全自动”ORM实现了POJO和数据库表之间的映射,以及 SQL 的自动生成和执行。
而mybatis的着力点,则在于POJO与SQL之间的映射关系。
一:mybatis的project
我们先建立一个Mybatis的project,项目具体如下:
首先要导入两个包:一个是mybatis的jar包,一个是mysql的驱动包
mybatis需要jar包:mybatis-3.3.0.jar
mysql驱动jar包:mysql-connector-java-5.1.15.-bin.jar
同样的我们要创建数据库:
这个是我们整体的项目工程:
二:XML配置
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
1:添加mybatis配置文件mybatis.cfg.xml
Mybatis的全局配置文件,主要用于配置Mybatis的运行环境(事务管理器、数据源等)。具体详情可见Mybatis说明文档。
下面通过一个简单的示例,来简要说明这个配置文件。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 3 <configuration> 4 <environments default="development"> 5 <environment id="development"> 6 <transactionManager type="JDBC"> 7 </transactionManager> 8 <!-- 数据库连接配置信息 --> 9 <dataSource type="POOLED"> 10 <property name="driver" value="com.mysql.jdbc.Driver"/> 11 <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> 12 <property name="username" value="root"/> 13 <property name="password" value="root"/> 14 </dataSource> 15 </environment> 16 </environments> 17 18 <!-- 注册userMapper.xml文件 --> 19 <mappers> 20 <mapper resource = "mapper/userMapper.xml"/> 21 </mappers> 22 </configuration>
头文件(1~2行):第1行是xml声明,声明该xml文件的字符集为UTF-8;第2行是DTD文件类型声明(外部DTD),用于约束该xml文件的结构。引用的DTD约束的格式为<!DOCTYPE 根元素 SYSTEM "DTD文件路径">(本地文件),或<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文件URL">(公共文件),这里是约束configuaration元素的结构为链接中的DTD文件所约束的那样
environments元素(4~16行):用于配置要创建的SqlSessionFactory实例的环境。每个数据库对应一个SqlSessionFactory实例,每个SqlSessionFactory实例只能选择一种环境(environments元素中可以定义多个environment元素)。
- 第4行:默认的环境id。
- 第5行:定义一个environment元素,并设定环境id。
- 第6行:事务管理器的配置,可选"JDBC"或"MANAGED"。【注:Spring+Mybatis不需要配置事务管理器,因为Spring会用自带管理器覆盖这些配置】
-
- "JDBC":直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
- "MANAGED":不提交或回滚一个连接,而是让容器来管理事务的整个生命周期,默认情况下它会关闭连接
-
- 第9~14行:数据源的配置。第12行是配置数据源类型,内置了"UNPOOLED","POOLED"和"JNDI";第13~18行是设定数据源。
- "UNPOOLED":不使用数据库连接池。只有driver,url,username,password,defaultTransactionIsolationLevel五个属性,其中最后一个属性是指默认的连接事务隔离级别。
- "POOLED":使用数据库连接池。除了"UNPOOLED"中的5个属性之外,还多了一些连接池属性,比如poolMaximumActiveConnections(最大活动连接数)、poolMaximumIdleConnections(最大空闲连接数)等(详见说明文档)。
- "JNDI":为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。只需"initial_context"和"data_source"两个属性。
- 另外,也可以将type设置为一个数据源类,使用任何第三方数据源。
mappers元素(19~21行):用于设定映射文件路径。可以通过classpath相对路径、文件系统绝对路径设定映射文件,还可以通过类名、包名设定映射接口
2.userMapper.xml
sql映射文件,主要用于实现数据库操作的具体细节。此文件需要在MybatisConfig.xml中加载。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 4 <!-- 为这个mapper指定一个唯一的namespace,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证包名是惟一的 --> 5 <mapper namespace="mapper.userMapper"> 6 7 <!-- 在select标签中编写查询的sql语句,设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果类型。 8 --> 9 <!-- 对于查询单条记录,必须保证查询出来的记录只有一个,如果有多个mybatis是会报错的,而不是就取多条记录中的第一个。 --> 10 <select id="getUser" parameterType="String" resultType="beans.User"> 11 select * from users where username=#{id} 12 </select> 13 14 <insert id="insertUser" parameterType="beans.User"> 15 insert into users(username, password) value(#{username},#{password}) 16 </insert> 17 18 <update id="update" parameterType="beans.User"> 19 update users set username=#{username}, password=#{password} where id=#{id} 20 </update> 21 22 <delete id="delete" parameterType="int"> 23 delete from users where id=#{id} 24 </delete> 25 26 <!--id为该条SQL的名称,在该Mapper下不能重复 27 resultType里填写集合泛型,不论返回值是List还是单个类型,都填写泛型或者单个类型即可, 28 mybatis会自动猜测返回值是一个类型还是集合--> 29 <select id="selectAllUsers" resultType="beans.User"> 30 select * from users 31 </select> 32 33 </mapper>
- 头文件(1~2行):同上,这里是约束mapper元素的结构为链接中的DTD文件所约束的那样。
- 命名空间(5行):最基本的意义,是给这个mapper命名用于区分;更为高级的用法,则是接口绑定(面向接口编程)。namespace的命名方式分为两种:完全限定名和短名称。本例中使用的就是完全限定名。使用短名称时,必须确保这个短名称在系统中是唯一的,否则只能使用完全限定名。
- 接口绑定:将namespace设为DAO接口,将接口中的方法都通过mapper中的元素实现(元素id与接口方法一一对应),就可以不用写DAO实现类,Mybatis会通过绑定自动找到要执行的sql语句。
mapper顶级元素(4~61行):mapper中有8个顶级元素,分别是insert,delete,update,select(映射增删改查语句),sql(重用sql语句块),resultMap(描述如何从结果集中加载对象),cache(缓存配置),cache-ref(其他namespace缓存配置)。
insert、delete、update(5~23行):基本格式就是<元素名 元素属性>sql语句</元素名>。其中,元素名即为insert/delete/update中的一个,可设定的元素属性有9个,这里只列出5个,一般设定1,2即可。在sql语句中,用#{}表示占位符,执行时将#{}替换为?,然后将括号内的参数传递给?。
- id:元素标识。
- parameterType:接受的参数类型,可为完全限定名或别名。默认为unset。传入多个参数时,这个属性应忽略,在#{}中直接以各参数名表示。(如:18~23行)
- .......
下面看Java的操作:
数据库操作在代码中的实现步骤大体如下:
- 创建IO流,通过Resources类中的getResourceAsStream方法载入全局配置文件(mybatis.cfg.xml)。
- 由SqlSessionFactoryBuilder对象的build方法,创建SqlSessionFactory对象。
- 由SqlSessionFactory对象的openSession方法,创建SqlSession对象。
- 由SqlSession对象,操作数据库。
- 关闭SqlSession对象,然后关闭IO流.
下面主要讲解一下通过SqlSession对象操作数据库的内容。
1.SqlSession类中的常用方法
目前主要用到过的方法有:
- insert,delete,update:对数据库进行增/删/改操作。注意:进行了这些操作之后,必须调用commit()提交事务,否则数据库记录不会改变。
返回值:int,操作所影响的行数。
参数:("sqlID",param): - sqlID:StudentMapper.xml中对应的sql元素的id,若有多个mapper,可以通过mapper.sqlID的形式指定。
- param:若对应的接口函数只需要传入一个参数,直接将这个参数传入即可。【最好用变量的形式传入。直接传常量可能会导致类型转换异常】
若需传入多个参数,则应该用HashMap<String,Object>传入参数。其中,String是mapper.xml中的参数名(#{xx}),Object是参数值。将多个参数放入map后,将map作为参数传入即可。 - commit():刷新批处理语句并提交数据库连接。在增删改之后必须调用。
- selectOne("sqlID",param):参数意义同上。返回值:mapper.xml中规定的返回值类型。
- selectList("sqlID",param):同上。返回值:List<E>,其中E为mapper.xml中规定的返回值类型。
- close():关闭会话,释放资源。
- POJO类中的构造方法的参数类型,如果是基本数据类型,应该写成其包装类的形式(比如int写为Integer)。因为mapper.xml中的javaType会自动转为完全限定名(比如int转为java.lang.Integer)。如果在resultMap中定义了constructor元素,映射到POJO类时会是完全限定名的类型,如果构造方法中的参数类型不是包装类,就会报错(找不到参数类型为xxx的构造函数)。
- 务必在insert/delete/update之后执行commit!否则一切操作都不会在数据库中生效!
下面看一下Java类文件:
POJO类:
1 package beans; 2 3 public class User { 4 5 private int id; 6 7 private String username; 8 private String password; 9 10 11 /** 12 * @return the id 13 */ 14 public int getId() { 15 return id; 16 } 17 /** 18 * @param id the id to set 19 */ 20 public void setId(int id) { 21 this.id = id; 22 } 23 /** 24 * @return the username 25 */ 26 public String getUsername() { 27 return username; 28 } 29 /** 30 * @param username the username to set 31 */ 32 public void setUsername(String username) { 33 this.username = username; 34 } 35 /** 36 * @return the password 37 */ 38 public String getPassword() { 39 return password; 40 } 41 /** 42 * @param password the password to set 43 */ 44 public void setPassword(String password) { 45 this.password = password; 46 } 47 48 /* (non-Javadoc) 49 * @see java.lang.Object#toString() 50 */ 51 @Override 52 public String toString() { 53 return "User [id=" + id + ", username=" + username + ", password=" + password + "]"; 54 } 55 56 }
MybatisUtil工具类:
1 package utils; 2 3 import java.io.IOException; 4 import java.io.Reader; 5 6 import org.apache.ibatis.io.Resources; 7 import org.apache.ibatis.session.SqlSession; 8 import org.apache.ibatis.session.SqlSessionFactory; 9 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 10 11 public class MybatisUtil { 12 13 private static SqlSessionFactory sqlSessionFactory = null; 14 15 static{ 16 try { 17 Reader read = Resources.getResourceAsReader("mybatis.cfg.xml"); 18 sqlSessionFactory = new SqlSessionFactoryBuilder().build(read); 19 } catch (IOException e) { 20 e.printStackTrace(); 21 } 22 } 23 24 public static SqlSession getSession(){ 25 return sqlSessionFactory.openSession(true); 26 } 27 }
测试类:
1 package test; 2 3 import java.io.IOException; 4 5 import org.apache.ibatis.session.SqlSession; 6 7 import beans.User; 8 import utils.MybatisUtil; 9 10 public class Test { 11 12 public static void main(String[] args) throws IOException { 13 14 //mybatis的配置文件 15 //String resource = "mybatis.cfg.xml"; 16 17 //使用类加载器加载mybatis配置文件,它也加载关联的映射文件 18 //InputStream is = Test.class.getClassLoader().getResourceAsStream(resource); 19 20 //构建sqlSession的工厂 21 //SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is); 22 23 //使用mybatis提供的Resource类加载mybatis的配置文件(它也加载关联的映射文件) 24 //Reader read = Resources.getResourceAsReader(resource); 25 26 //构建sqlSession工厂 27 //SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(read); 28 //创建能执行映射文件中的sql的sqlSession 29 //SqlSession sqlSession = sqlSessionFactory.openSession(); 30 SqlSession sqlSession = MybatisUtil.getSession(); 31 32 //映射sql的标识字符串,mapper.userMapper是userMapper.xml文件中mapper标签的namespace属性值 33 //getUser是select标签的id属性值,通过select标签的id属性值就可以找到要执行的sql 34 String statament = "mapper.userMapper.getUser"; //映射sql的标识字符串 35 //执行查询返回一个唯一的user对象的sql 36 User user = sqlSession.selectOne(statament, "zxl"); 37 38 System.out.println(user); 39 } 40 41 }
看上面的例子可以看出,获取SqlSessionFactory一共有两种方式:
通过myBatis提供的Resources.getResourceAsReader(resource), 然后通过New SqlSessionFactoryBuilder().build()来创建SqlSessionFactory.
通过使用类加载器加载mybatis配置文件,它也加载关联的映射文件,Test.class.getClassLoader().getResourceAsStream(resource);
上面的查询结果:根据“mapper.userMapper.getUser”找到sql语句:“select * from users where username=#{id}”, 然后将参数传递进去。
一个复杂些的CRUD:
1 package test; 2 3 import java.util.HashMap; 4 import java.util.List; 5 6 import org.apache.ibatis.session.SqlSession; 7 8 import beans.User; 9 import utils.MybatisUtil; 10 11 public class TestCRUD { 12 13 public static void main(String[] args) { 14 15 //查找一个用户 16 SqlSession sqlSession = MybatisUtil.getSession(); 17 String statament = "mapper.userMapper.getUserbyMore"; 18 19 HashMap<String, Object> paras = new HashMap<String, Object>(); 20 paras.put("username", "zxl"); 21 paras.put("password", "12345"); 22 23 User user = new User(); 24 user = sqlSession.selectOne(statament, paras); //通过多个参数去查找,传入参数应该是HashMap,key是数据表中列参数 25 System.out.println("查询结果:"+ user); 26 27 //更新用户 28 statament = "mapper.userMapper.update"; 29 User userupdate = new User(); 30 userupdate.setId(2); 31 userupdate.setUsername("zxllll"); 32 userupdate.setPassword("345"); 33 int result = sqlSession.update(statament, userupdate); 34 System.out.println("update result: " + result); 35 36 //添加一个用户,前面有删去用户,添加的主键会不连续。 37 statament = "mapper.userMapper.insertUser"; 38 User useradd = new User(); 39 useradd.setUsername("zxl333"); 40 useradd.setPassword("333"); 41 result = sqlSession.insert(statament, useradd); 42 System.out.println("insert new user result: " + result); 43 44 //删去一个用户 45 statament = "mapper.userMapper.delete"; 46 result = sqlSession.delete(statament, 2); 47 System.out.println("delete user result: " + result); 48 49 //查找所有用户 50 statament = "mapper.userMapper.selectAllUsers"; 51 List<User> list = sqlSession.selectList(statament); 52 System.out.println("select all user result: " + list); 53 sqlSession.close(); 54 } 55 }
上面查找是通过username和password来查找的,所以在userMapper.xml中添加一部分如下:
1 <select id="getUserbyMore" resultType="beans.User"> 2 select * from users where username=#{username} and password=#{password} 3 </select>
如输入是多个参数,则parameterType应该是空的。并且Sql语句中where里面条件判断必须是数据表字段。
格式有点乱,后面再修改。下面是一些参考博客!
https://www.cnblogs.com/whgk/p/6692746.html----一杯凉茶
https://www.cnblogs.com/xdp-gacl/p/4261895.html
https://www.cnblogs.com/hellokitty1/p/5216025.html------学习笔记入门
https://www.cnblogs.com/mengheng/p/3739610.html
https://www.cnblogs.com/cage666/p/7359862.html-----对mybatis.cfg.xml做了详细介绍