前言
学习了一段时间的 mybatis,写此文章用于查漏补缺,整理该框架的使用流程。mybatis 原名iBatis,是一个持久层(dao)框架,提供了简便的操作数据库的功能(CRUD)。是对原生JDBC操作的封装,用来替换原生JDBC访问数据库。
相关依赖、配置文件、工具类
有关 jar 包我已经上传到 CSDN 的资源里(免费):mybatis 依赖,其中也包含一个log4j的配置文件,直接复制粘贴到src目录即可。
mybatis-config.xml 的详细解释
这是mybatis 中最重要的一个配置文件,内含很多标签:
<?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> <properties resource="db.properties"></properties> <settings> <setting name="cacheEnabled" value="true"/> </settings> <!--typeAliases type :指明实体类 alias :给实体类起的别名 批量起别名:package name="实体类包" ,别名自动为短类名 com.xx.entity.Xxx = Xxx --> <typeAliases> <package name="com.qj.entity"/> </typeAliases> <!-- 配置数据库连接参数集 default:指定当前使用的数据库连接 --> <environments default="e1"> <!-- 配置一个数据库连接 id:值 自定义 给当前数据库连接起名字 --> <environment id="e1"> <!-- 指定事务提交的方式 type :JDBC 使用默认的数据库事务操作 MANGED 使用第三方所编写的事务操作 --> <transactionManager type="JDBC"></transactionManager> <!--配置数据库连接具体信息 type: POOLED 使用数据库连接池 UNPOOLED 不使用连接池 --> <dataSource type="POOLED"> <property name="driver" value="${driverClassName}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <!--配置XXX_mapper.xml使用--> <!--<mapper resource="com/qj/mapper/BookDAOMapper.xml"/>--> <!--批量扫描,注册mapper.xml 写到包名即可--> <package name="com.qj.mapper"/> </mappers> </configuration>
1.所有的标签需要写在 configuration 之内,这是配置文件的范围。
2.properties 标签里引入的是有关数据库连接的资源文件,其位置在最上面。
资源文件展示:
3.settings 用来开启二级缓存,这个会在缓存的知识中解释,位置在typeAliases与properties之间
4.typeAliases 用来给实体类起别名,原来的名字默认为长名字,即 com.xx.包名.类名
建议直接使用批量起别名的方法:package name = “实体类包”,别名自动为短类名
5.environments 标签用来配置数据库连接参数集,default 指定当前的数据库连接
注意:&是关键字,不能在 xml 文件直接使用(用&代替)
其余子标签我都加了注释,作用都很清晰
6.mappers 用来注册XXXMapper.xml使用,两种配置方式,推荐批量扫描方式
工具类 MybatisUtil
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; public class MybatisUtil { private static SqlSessionFactory ssf; // 静态代码块在类加载的时候只执行一次 static { try { // 1.获取配置文件 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); // 2.创建sqlSessionFactory利用build方法加载资源 ssf = new SqlSessionFactoryBuilder().build(is); } catch (IOException e) { throw new RuntimeException("读取配置文件异常:" + e); } } // 获取sqlSession public static SqlSession getSqlSession() { // 获取sqlSession SqlSession sqlSession = ssf.openSession(); return sqlSession; } // 释放资源 public static void closeSqlSession(SqlSession sqlSession) { sqlSession.close(); } }
SqlSession 为mybatis中的数据库连接,需要通过工厂类SqlSessionFactory获取。需要加载一次,因此将其放入静态代码块中,同时静态成员函数才能访问静态变量,所以 ssf 要被static 修饰。
增删改查操作
dao 包变为 mapper ,接口的实现类也变为相应的 xml 文件,并且在xml文件的作用域中写上对应的mapper接口类。
根据 id 查询所有
mapper 中写接口:
对应xml文件写 sql:
这里的t_book_column是自己定义的一个 sql 标签的键,内容如下:
这样写与 select * 效果一样,但是在运行时显然是前者更高效。
查询的返回值是Book 类型,使用resultMap来接收:
resultMap 常用来映射数据库字段与实体类属性,其妙用在一对一,一对多关系中更能体现。
#{} 用来读取参数,大括号里填写mapper接口中函数的参数。
接下来测试是否能够查询成功,编写 BookMapperTest:
public class BookMapperTest { @Test public void selectById() { SqlSession sqlSession = MybatisUtil.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); Book book = mapper.selectById(12); System.out.println(book); } }
数据库连接为 sqlSession,通过获取接口的代理类对象来得到mapper 从而调用接口中的方法:
根据书名和价格查书
接口中的方法:
Book selectByNameAndPrice(@Param("name") String name, @Param("price") double price);
xml 中的 sql :
<select id="selectByNameAndPrice" resultMap="bookMap"> <include refid="t_book_column"/> from t_book where book_name = #{name} and book_price = #{price} </select>
参数多的情况下需要使用注解来绑定参数,只有一个参数时可以在{}中随便写,但是习惯上和接口中的参数保持一致。
插入操作
接口中的方法:
void insert(Book book);
xml 中的 sql :
<insert id="insert"> insert into t_book values (null, #{bookName}, #{bookPrice}, #{bookDesc}) </insert>
插入和修改操作类似,传入的是一个类对象,参数直接写属性即可。
一旦给对象参数加上了注解,那就需要用这样的形式:“键.属性”
#{} 与 ${}的区别
#{}本质上是占位符,而${}本质上是字符串拼接,二者区别:
?占位符可以防止 sql注入攻击,但是只能绑定数据,不能绑定关键字
字符串拼接容易被sql注入,但是可以绑定关键字等
总结
使用 sql 标签代替 select * 提高运行效率
查询结果无论是实体类还是实体类集合,都要写配置好的resultMap
除了 查找 操作,增、删、改需要自己提交事务,mybatis 并不会自动提交
函数中的参数多的时候使用注解,类对象加上注解后不能直接写属性
这部分为mybatis的基础部分,掌握简单的增删改查以及配置文件的配置即可。表连接、动态sql与缓存等内容下篇文章总结,需要的小伙伴可以订阅专栏。