一、Mybatis架构
JAR包下载地址
1、 mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
二、入门程序
1.classPath下进行sqlMapConfig.xml文件的配置(SqlMapConfig.xml是mybatis核心配置文件)
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 7 <!-- 加载属性文件 --> 8 <properties resource="db.properties"> 9 <!-- properties中还可以配置一些属性名和属性值 --> 10 <!-- <property name="jdbc.driver" value=""/> --> 11 </properties> 12 <!-- 全局配置参数,需要时再设置 --> 13 <settings> 14 <!-- 打开延迟加载 的开关 --> 15 <setting name="lazyLoadingEnabled" value="true" /> 16 <!-- 将积极加载改为消极加载即按需要加载 --> 17 <setting name="aggressiveLazyLoading" value="false" /> 18 </settings> 19 20 <!-- 别名定义 --> 21 <typeAliases> 22 <!-- 针对单个别名定义 type:类型的路径 alias:别名 --> 23 <!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> --> 24 <!-- 批量别名定义 指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以) --> 25 <!-- 这样在配置mapper的时候就不需要写pojo的全限定名了 --> 26 <package name="cn.itcast.mybatis.po" /> 27 </typeAliases> 28 29 <!-- 和spring整合后 environments配置将废除 --> 30 <environments default="development"> 31 <environment id="development"> 32 <!-- 使用jdbc事务管理,事务控制由mybatis --> 33 <transactionManager type="JDBC" /> 34 <!-- 数据库连接池,由mybatis管理 --> 35 <dataSource type="POOLED"> 36 <property name="driver" value="${jdbc.driver}" /> 37 <property name="url" value="${jdbc.url}" /> 38 <property name="username" value="${jdbc.username}" /> 39 <property name="password" value="${jdbc.password}" /> 40 </dataSource> 41 </environment> 42 </environments> 43 <!-- 加载 映射文件 --> 44 <mappers> 45 <mapper resource="sqlmap/User.xml" /> 46 <!-- <mapper resource="mapper/UserMapper.xml"/> --> 47 <!--通过resource方法一次加载一个映射文件 --> 48 <!-- <mapper resource="mapper/UserMapper.xml"/> --> 49 50 <!-- 通过mapper接口加载单个 映射文件 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 51 中 上边规范的前提是:使用的是mapper代理方法 --> 52 <!-- <mapper class="cn.itcast.mybatis.mapper.UserMapper"/> --> 53 54 <!-- 批量加载mapper 建议使用该种方法 指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 55 中 上边规范的前提是:使用的是mapper代理方法 --> 56 <package name="cn.itcast.mybatis.mapper" /> 57 58 </mappers> 59 60 </configuration>
2.定义po类(User.java)
1 package cn.itcast.mybatis.po; 2 3 import java.util.Date; 4 import java.util.List; 5 6 public class User { 7 8 //属性名和数据库表的字段对应 9 private int id; 10 private String username;// 用户姓名 11 private String sex;// 性别 12 private Date birthday;// 生日 13 private String address;// 地址 14 //用户创建的订单列表 15 private List<Orders> ordersList; 16 17 public List<Orders> getOrdersList() { 18 return ordersList; 19 } 20 public void setOrdersList(List<Orders> ordersList) { 21 this.ordersList = ordersList; 22 } 23 public int getId() { 24 return id; 25 } 26 public void setId(int id) { 27 this.id = id; 28 } 29 public String getUsername() { 30 return username; 31 } 32 public void setUsername(String username) { 33 this.username = username; 34 } 35 public String getSex() { 36 return sex; 37 } 38 public void setSex(String sex) { 39 this.sex = sex; 40 } 41 public Date getBirthday() { 42 return birthday; 43 } 44 public void setBirthday(Date birthday) { 45 this.birthday = birthday; 46 } 47 public String getAddress() { 48 return address; 49 } 50 public void setAddress(String address) { 51 this.address = address; 52 } 53 @Override 54 public String toString() { 55 return "User [id=" + id + ", username=" + username + ", sex=" + sex 56 + ", birthday=" + birthday + ", address=" + address + "]"; 57 } 58 59 60 }
3.创建mapper映射文件(User.xml)
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 6 <!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用 --> 7 <mapper namespace="test"> 8 9 <!-- 在 映射文件中配置很多sql语句 --> 10 <!-- 需求:通过id查询用户表的记录 --> 11 <!-- 通过 select执行数据库查询 id:标识 映射文件中的 sql 将sql语句封装到mappedStatement对象中,所以将id称为statement的id 12 parameterType:指定输入 参数的类型,这里指定int型 #{}表示一个占位符号 #{id}:其中的id表示接收输入 的参数,参数名称就是id,如果输入 13 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称 resultType:指定sql输出结果 的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象。 --> 14 <select id="findUserById" parameterType="int" 15 resultType="cn.itcast.mybatis.po.User"> 16 select * from user where id=#{id} 17 </select> 18 19 <!-- 根据用户名称模糊查询用户信息,可能返回多条 resultType:指定就是单条记录所映射的java对象 类型 ${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。 20 使用${}拼接sql,引起 sql注入 ${value}:接收输入 参数的内容,如果传入类型是简单类型,${}中只能使用value --> 21 <select id="findUserByName" parameterType="java.lang.String" 22 resultType="cn.itcast.mybatis.po.User"> 23 select * from user where username like '%${value}%' 24 </select> 25 <!-- 添加用户 parameterType:指定输入 参数类型是pojo(包括 用户信息) #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值 --> 26 <insert id="insertUser" 27 parameterType="cn.itcast.mybatis.po.User"> 28 <!-- 将插入数据的主键返回,返回到user对象中 SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用与自增主键 29 keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性 order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序 30 resultType:指定SELECT LAST_INSERT_ID()的结果类型 --> 31 <selectKey keyProperty="id" order="AFTER" 32 resultType="java.lang.Integer"> 33 SELECT LAST_INSERT_ID() 34 </selectKey> 35 insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address}) 36 </insert> 37 38 <delete id="deleteUser" parameterType="int"> 39 delete from user where id=#{id} 40 </delete> 41 42 <update id="updateUser" parameterType="cn.itcast.mybatis.po.User"> 43 update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id = #{id} 44 </update> 45 </mapper>
4.在sqlMapConfig.xml加载映射文件,前面xml文件中已经加载
5.测试程序
1 package cn.itcast.mybatis.first; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Date; 6 7 import org.apache.ibatis.io.Resources; 8 import org.apache.ibatis.session.SqlSession; 9 import org.apache.ibatis.session.SqlSessionFactory; 10 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 11 12 import cn.itcast.mybatis.po.User; 13 14 public class MybatisFirst { 15 public static void main(String[] args) throws IOException { 16 // mybatis配置文件 17 String resource = "sqlMapConfig.xml"; 18 // 得到配置文件流 19 InputStream inputStream = Resources.getResourceAsStream(resource); 20 // 创建会话工厂,传入mybatis文件的配置信息 21 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 22 // 通过工厂得到Sqlsession 23 SqlSession session = sqlSessionFactory.openSession(); 24 25 // 通过sqlsession操作数据库 26 27 // 第一个参数:映射文件中statement的id,等于=namespace+"."+statement的id 28 // 第二个参数:指定和映射文件中所匹配的parameterType类型的参数 29 // sqlSession.selectOne结果 是与映射文件中所匹配的resultType类型的对象 30 // selectOne查询出一条记录 31 32 /* 33 * User user = session.selectOne("test.findUserById", 10); 34 * System.out.println(user); 35 * 36 * List<User> userList = session.selectList("test.findUserByName", "张"); 37 * System.out.println(userList); 38 */ 39 40 User user = new User(); 41 user.setId(1); 42 user.setSex("2"); 43 user.setAddress("江苏南京"); 44 user.setUsername("王爱军"); 45 user.setBirthday(new Date()); 46 session.update("test.updateUser", user); 47 session.commit(); 48 // 释放资源 49 session.close(); 50 // System.out.println(user.getId()); 51 52 } 53 }
tips:
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
tips:mysql自增主键返回
1 <!--通过修改sql映射文件,可以将mysql自增主键返回:> 2 <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> 3 <!-- selectKey将主键返回,需要再返回 --> 4 <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> 5 select LAST_INSERT_ID() 6 </selectKey> 7 insert into user(username,birthday,sex,address) 8 values(#{username},#{birthday},#{sex},#{address}); 9 </insert> 10 <!--添加selectKey实现将主键返回 11 keyProperty:返回的主键存储在pojo中的哪个属性 12 order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after 13 resultType:返回的主键是什么类型 14 LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。-->