MyBatis概述 原始JDBC开发存在的问题
数据库的连接创建,释放频繁造成系统资源浪费从而影响系统性能
sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变java代码。(sql语句与Java代码耦合死)
查询操作时,需要手动将结果集中的数据手动封装到实体中。插入操作时,需要手动将实体的数据设置到sql语句的占位符位置
解决方案
池化思想:使用数据库连接池初始化连接资源
配置文件:将sql语句抽取到xml配置文件中
使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射
MyBatis简介
MyBatis 是一款优秀的持久层 框架,它内部封装了JDBC,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO映射成数据库中的记录。
mybatis通过xml或注解的方式将要执行的各种 statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句。
最后mybatis框架执行sql并将结果映射为java对象并返回。采用ORM思想(Object Relational Mapping:对象关系映射)解决了实体和数据库映射的问题,对jdbc 进行了封装,屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,就可以完成对数据库的持久化操作。
MyBatis快速开发步骤 添加MyBatis坐标 1 2 3 4 5 <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.4.0</version > </dependency >
创建User数据表
创建User实体类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class User { private Long id; private String username; private String password; public Long getId () { return id; } public void setId (Long id) { this .id = id; } public String getUsername () { return username; } public void setUsername (String username) { this .username = username; } public String getPassword () { return password; } public void setPassword (String password) { this .password = password; } @Override public String toString () { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}' ; } }
编写映射文件UserMapper.xml 1 2 3 4 5 6 7 8 9 10 11 12 <?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 ="userMapper" > <select id ="findAll" resultType ="cn.ywrby.domain.User" > select * from user </select > </mapper >
编写核心文件SqlMapConfig.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?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" > <environment id ="development" > <transactionManager type ="JDBC" > </transactionManager > <dataSource type ="POOLED" > <property name ="driver" value ="com.mysql.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:hj/jdbcTest" /> <property name ="username" value ="root" /> <property name ="password" value ="rlm214" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="cn\ywrby\mapper\UserMapper.xml" /> </mappers > </configuration >
编写测试类并执行测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Test public void test () throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml" ); SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = factory.openSession(); List<User> userList=sqlSession.selectList("userMapper.findAll" ); System.out.println(userList); sqlSession.close(); }
MyBatis的数据库操作(增删改查) 配置映射文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <insert id ="save" parameterType ="cn.ywrby.domain.User" > insert into user values (#{id},#{username},#{password}) </insert > <update id ="update" parameterType ="cn.ywrby.domain.User" > update user set username=#{username},password=#{password} where id=#{id} </update > <delete id ="delete" parameterType ="java.lang.Integer" > delete from user where id=#{id} </delete >
测试用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @Test public void test () throws IOException { User user=new User(); user.setId((long ) 3 ); user.setUsername("Lily" ); user.setPassword("5667" ); InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml" ); SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = factory.openSession(); sqlSession.selectList("userMapper.save" ,user); sqlSession.commit(); sqlSession.close(); }
MyBatis核心配置文件概述 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?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" > <environment id ="development" > <transactionManager type ="JDBC" > </transactionManager > <dataSource type ="POOLED" > <property name ="driver" value ="com.mysql.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:10056/jdbcTest" /> <property name ="username" value ="root" /> <property name ="password" value ="renboyu010214" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="cn\ywrby\mapper\UserMapper.xml" /> </mappers > </configuration >
事务管理器(transactionManager)类型有两种:
JDBC:直接使用JDBC的提交与回滚,依赖于从数据源处得来的连接来管理事务作用域
MANAGED:这个配置几乎不进行操作,不提交或回滚任何一个连接,而是让容器来管理整个事务的生命周期
数据源(datasource)类型有三种:
UNPOOLED:每次被请求时打开或关闭连接
POOLED:该数据源利用池的概念将JDBC连接对象组织起来
JNDI
mapper标签 mapper标签的作用是加载映射文件,其加载文件的方式有多种:
使用相对于类的路径的资源引用的方式(一般情况下均使用该方式):<mapper resource="cn\ywrby\mapper\UserMapper.xml"/>
使用完全限定资源定位符URL:<mapper url="file:///var/mappers/xxx.xml"/>
使用映射器接口实现类的完全限定名(结合注解方式使用):<mapper class="cn.ywrby.builder.AuthorMapper"/>
将包内的映射器接口实现全部注册为映射器(类似于对该包进行扫描,将所有映射器接口实现类注册为映射器):<package name="cn.ywrby.mapper"/>
properties标签 properties标签用于加载外部properties文件,可以使各文件分工更加明确(如加载jdbc.properties)
typeAliases标签 typeAliases标签用于自定义别名,定义别名可以简化我们代码输入,type属性用于表示定义别名的实体类名,alias是自定义的别名
1 2 3 4 <typeAliases > <typeAlias type ="cn.ywrby.domain.User" alias ="user" /> </typeAliases >
在UserMapper.xml中使用,parameterType和resultType都可以使用别名替换,另外MyBatis也为一些基本类提前定义了别名
1 2 3 4 5 6 7 8 9 10 11 <mapper namespace ="userMapper" > <select id ="findAll" resultType ="user" > select * from user </select > <insert id ="save" parameterType ="user" > insert into user values (#{id},#{username},#{password}) </insert > <delete id ="delete" parameterType ="int" > delete from user where id=#{id} </delete > </mapper >
默认的别名
别名
数据类型
String
java.lang.String
long
java.lang.Long
int
java.lang.Integer
double
java.lang.Double
boolean
java.lang.Boolean
MyBatis的DAO层实现 MyBatis的传统实现方式就是通过上文测试类中的一般方法,在每次的使用过程中,都需要加载核心配置文件,初始化会话工程,执行事务提交等繁琐操作, 所以一般情况下,在开发过程中不会采用传统的实现方式
接口代理方式实现 接口代理开发方式只需要我们实现Mapper接口(就是之前编写的DAO层接口),然后由MyBatis根据接口的定义(根据方法名,返回值,参数值等)创建接口的动态代理对象
Mapper接口的开发需要遵循以下的规范
Mapper.xml文件中的namespace是接口的全限定名
Mapper接口的方法名和Mapper.xml中定义的statement的ID值相同
Mapper接口方法的输入参数和Mapper.xml中定义的sql语句的parameterType的类型相同
Mapper接口方法的输出参数和Mapper.xml中定义的sql语句的resultType的类型相同
修改后的UserMapper.xml配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <mapper namespace ="cn.ywrby.mapper.UserMapper" > <select id ="findAll" resultType ="user" > select * from user </select > <insert id ="save" parameterType ="user" > insert into user values (#{id},#{username},#{password}) </insert > <update id ="update" parameterType ="user" > update user set username=#{username},password=#{password} where id=#{id} </update > <delete id ="delete" parameterType ="java.lang.Long" > delete from user where id=#{id} </delete > </mapper >
接口实现
1 2 3 4 5 6 7 public interface UserMapper { public List<User> findAll () ; public void save (User user) ; public void update (User user) ; public void delete (Long id) ; }
测试用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Test public void test () throws IOException { User user=new User(); user.setId((long ) 4 ); user.setUsername("lily" ); user.setPassword("1234" ); InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml" ); SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = factory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.update(user); sqlSession.commit(); sqlSession.close(); }