like操作
like操作有两种写法,一种是在参数中将%号拼装上,类似:
List<Person> personList = mapper.getPersonListLike("%李%");
另一种则是在配置文件中提前加好%号,但这种容易引起sql注入:
select * from person where username like "%"#{value}"%"
这里我们采取第一种写法。
1 调整PersonDao接口定义
首先我们可以在PersonDao接口中增加一个方法getPersonListLike用来模糊获取记录:
package com.example.MyBatis.dao.mapper; import com.example.MyBatis.dao.model.Person; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; public interface PersonDao { List<Person> getPersonList(); Person getPersonByUsername(@Param("username")String username, @Param("password")String password); Person getPersonByMap(Map<String,Object> map); int addPerson(Person person); int updatePerson(Person person); int deletePerson(@Param("id")int id); List<Person> getPersonListLike(@Param("username")String username); }
2 编写personMapper.xml
其次依据PersonDao接口中增加的方法我们可以在personMapper中进行sql语句编写来实现:
<?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"> <!--namespace=绑定一个指定的Dao/Mapper接口--> <mapper namespace="com.example.MyBatis.dao.mapper.PersonDao"> <select id="getPersonList" resultType="com.example.MyBatis.dao.model.Person"> select * from person </select> <select id="getPersonByUsername" resultType="com.example.MyBatis.dao.model.Person" > select * from person where password=#{password} and username = #{username} </select> <select id="getPersonByMap" resultType="com.example.MyBatis.dao.model.Person" parameterType="map"> select * from person where password=#{password} and username = #{username} </select> <insert id="addPerson" parameterType="com.example.MyBatis.dao.model.Person" > insert into person (id,username,password,age,phone,email) values (#{id},#{username},#{password},#{age},#{phone},#{email}) </insert> <update id="updatePerson" parameterType="com.example.MyBatis.dao.model.Person" > update person set username=#{username},phone=#{phone} where id=#{id} </update> <delete id="deletePerson" parameterType="int" > delete from person where id = #{id} </delete> <select id="getPersonListLike" resultType="com.example.MyBatis.dao.model.Person" > select * from person where username like "%"#{username}"%" </select> </mapper>
3 编写单元测试实现
最后我们编写单元测试查看实现效果:
@Test public void testGetPersonListLike(){ //1.获取SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); //2.执行SQL PersonDao personDao = sqlSession.getMapper(PersonDao.class); List<Person> personList = personDao.getPersonListLike("tm"); for (Person person : personList) { System.out.println(person); } //关闭sqlSession sqlSession.close(); }
可以看到模糊查询到了一条记录:
核心配置解析
其实我们在上述操作中默认了一个前提,就是personMapper.xml
文件已经注册到了mybatis-config.xml
配置文件中,我们还有个大前提的核心配置文件:
<?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核心配置文件--> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mappers/personMapper.xml"/> </mappers> </configuration>
其实我们远远没有使用完配置文件的属性,我们可以通过其定义一窥配置中的可配置项:
//configuration(配置) <!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)> //databaseIdProvider(数据库厂商标识) <!ELEMENT databaseIdProvider (property*)> <!ATTLIST databaseIdProvider type CDATA #REQUIRED > //properties(属性) <!ELEMENT properties (property*)> <!ATTLIST properties resource CDATA #IMPLIED url CDATA #IMPLIED > <!ELEMENT property EMPTY> <!ATTLIST property name CDATA #REQUIRED value CDATA #REQUIRED > //settings(设置) <!ELEMENT settings (setting+)> <!ELEMENT setting EMPTY> <!ATTLIST setting name CDATA #REQUIRED value CDATA #REQUIRED > //typeAliases(类型别名) <!ELEMENT typeAliases (typeAlias*,package*)> <!ELEMENT typeAlias EMPTY> <!ATTLIST typeAlias type CDATA #REQUIRED alias CDATA #IMPLIED > //typeHandlers(类型处理器) <!ELEMENT typeHandlers (typeHandler*,package*)> <!ELEMENT typeHandler EMPTY> <!ATTLIST typeHandler javaType CDATA #IMPLIED jdbcType CDATA #IMPLIED handler CDATA #REQUIRED > //objectFactory(对象工厂) <!ELEMENT objectFactory (property*)> <!ATTLIST objectFactory type CDATA #REQUIRED > <!ELEMENT objectWrapperFactory EMPTY> <!ATTLIST objectWrapperFactory type CDATA #REQUIRED > <!ELEMENT reflectorFactory EMPTY> <!ATTLIST reflectorFactory type CDATA #REQUIRED > //plugins(插件) <!ELEMENT plugins (plugin+)> <!ELEMENT plugin (property*)> <!ATTLIST plugin interceptor CDATA #REQUIRED > //environments(环境配置) <!ELEMENT environments (environment+)> <!ATTLIST environments default CDATA #REQUIRED > <!ELEMENT environment (transactionManager,dataSource)> <!ATTLIST environment id CDATA #REQUIRED > //transactionManager(事务管理器) <!ELEMENT transactionManager (property*)> <!ATTLIST transactionManager type CDATA #REQUIRED > //dataSource(数据源) <!ELEMENT dataSource (property*)> <!ATTLIST dataSource type CDATA #REQUIRED > //mappers(映射器) <!ELEMENT mappers (mapper*,package*)> <!ELEMENT mapper EMPTY> <!ATTLIST mapper resource CDATA #IMPLIED url CDATA #IMPLIED class CDATA #IMPLIED > <!ELEMENT package EMPTY> <!ATTLIST package name CDATA #REQUIRED >
层级关系如下:
configuration(配置) properties(属性) settings(设置) typeAliases(类型别名) typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件) environments(环境配置) environment(环境变量) transactionManager(事务管理器) dataSource(数据源) databaseIdProvider(数据库厂商标识) mappers(映射器)
environments元素
用于配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,必须指定其中一个为默认运行环境(通过default指定)
<environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments>
子元素节点:environment下的元素说明
- dataSource 元素,使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源,数据源是必须配置的。有三种内建的数据源类型
[UNPOOLED|POOLED|JNDI]
- UNPOOLED:这个数据源的实现是每次被请求时打开和关闭连接。
- POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
- JNDI:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
- transactionManager 元素,指定事务的管理方式,我们这里使用JDBC
以上就是environment元素的常用配置
mappers元素
mappers元素用来进行mapper文件的映射:
<mappers> <mapper resource="mappers/personMapper.xml"/> </mappers>
当然还有其它方式可以引入,但是我们这里推荐使用资源文件的方式引入,其它的就不赘述了。
Properties优化
数据库这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。
新建db.properties文件
创建一个properties文件,用于进一步将核心配置抽象解耦:
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/test?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username=root password=root
导入db.properties 文件
在核心配置文件中导入db.properties文件并读取其参数:
<?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核心配置文件--> <configuration> <!--导入properties文件--> <properties resource="properties/db.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mappers/personMapper.xml"/> </mappers> </configuration>
总结一下
其实通过实践就可以看的出来一些mybatis的限制,例如id不能重复,也就是DAO接口不能定义重载方法。同时我们也通过配置文件大概了解了MyBatis的一些使用方式,总体而言,更加加深了这样一个认知:Mybatis代码量大而灵活,具体的操作可以自己定义和实现,相比Hibernate,从操作层面上做到了更细粒度的解耦,也可以理解为封装性低,这也许是其半自动化ORM框架的由来吧,配置的更深入理解就有赖于框架的更深入学习吧。