Mybatis入门
一、对原生jdbc编程中的问题分析
1、频繁的进行数据库连接的打开和关闭,将造成数据库的资源浪费,降低数据库的性能。
2、将sql语句硬编码到代码中,每次修改后,需要重新编译,不利于系统维护。
3、向PreparedStatemen 中设置参数,需要将占位符和参数硬编码到代码中
string sql = "select * from user where username = ?"; PreparedStatement preparedStatement = conn.PreparedStatement(sql); preparedStatement.setString(1,"zhangsan");
4、遍历ResultSet结果集,遍历数据表中的字段,也存在硬编码现象。
ResultSet rs = preparedstement.executeNonQuery(); while(rs.next()){ rs.getString("id") + rs.getString("name"); }
设想:为了解决上面的问题,可以通过配置文件解决,利用连接池解决频繁的打开和关闭数据库,将查询返回的结果集直接映射成java对象。
二、MyBatis框架原理
Mybatis可以自动将sql语句中的参数自动映射,将查询到的结果集自动映射为java对象。
三、MyBatis入门程序
- 在IDE环境中配置Mybatis环境
1、导入jar包:mybatis.jar包、mysql驱动包
2、建立配置文件目录:log4j.properties、sqlMapXml.config(全局文件)、mapper.xml(映射文件)
-
<mapper namespace="test"> <!--
1、通过select执行查询,id标识sql映射,封装到mapperStatement对象中,所以又称为statementId
2、#{}标识占位符
3、#{id}其中id表示输入的参数,如果接收输入的参数是简单类型,参数名可任意输入value或其他等等。
4、resultType表示单条记录映射为java对象输出的类型,
--> <select id="findUserById" parameterType="int" resultType="com.packageName.User"> select * from user where id = #{id} </select>
<!-- 下面返回多条记录,应该是个结果集,但是resultType应该是单条记录映射的类型
1、${}表示拼接sql串,所接收的参数的内容不加任何修饰(比如:自动拼接' 、 ')拼接在sql中
2、使用${}可能引起sql注入
3、如果输入的参数是简单类型,${}里的参数只能用value
--><select id="findUserById" parameterType="int" resultType="com.packageName.User"> select * from user where name like '%${value}%' </select>
</mapper>
3、在sqlMapXml.config中添加map.xml映射文件。
4、创建SqlSessionFacotry,建立sqlSession会话
- 添加用户
- 在Mapper.xml添加配置statementId,如下:
<insert id="insertUser" parameterType="com.PackageName.User"> <!-- 将插入的数据主键返回到user对象中
keyProperty:将查询到的id放到parameterType指定的属性中
order:相对于insert的执行顺序
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user (id,username) values (#{id},#{username}) </insert>
2、自增主键返回,在上面的<insert>节点中添加<selectKey>
3、非自增主键返回
<insert id="insertUser" parameterType="com.PackageName.User"> <!-- 将插入的数据主键返回到user对象中 keyProperty:将查询到的id放到parameterType指定的属性中 --> <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> select uuid() </selectKey> insert into user (id,username) values (#{id},#{username}) </insert>
- MyBatis和Hibernate的区别和应用场景
- Hibernate不要写sql,自动生成sql语句,但优化、修改比较困难,适用于中心型项目,需求变化不大的项目。
- mybatis需要developer自己编写sql语句,优化、修改容易,可以实现映射,适用于大型项目,需求变化大的项目。
四、MyBatis开发DAO方法
- 原生dao开发
- 1、创建dao接口和dao接口实现类
- 2、在dao接口实现类的构造方法中注入SqlSessionFactory,用于创建sqlSession。
- 使用Mapper代理开发
- 开发规范
1、在Mapper.xml中,namespace值Mapper接口的全限定名。
<mapper namespace="cn.com.pakageName.IntefaceName"></mapper>
2、接口中的方法名和mapper.xml文件中的statementId一致。
3、接口中的方法输入参数类型和mapper.xml文件中的parameterType一致。
4、接口中的方法返回类型和mapper.xml文件中的resultType一致。
//创建UserMapper接口对象,调用接口中的方法
string path = "mapper.xml"; SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().bulder(Resources.getResourceAsStream(path)); SqlSession sqlSession = SqlSessionFactory.openSession(); UserMapper userDao = sqlSession.getMapper(UserMapper.class);
//在sqlMapConfig文件中加载映射文件
<mapper resource="sqlMap/UserMapper.xml"/>
五、sqlMapperXml配置文件属性扩展
- Properties属性
-
db.properties jdbc.url=jdbc:mysql://localhost:3306/dbname ... ... ... sqlMapConfig.xml 在全局配置文件中,加载属性配置文件 <properties resource="db.properties"/> ,通过${jdbc.url}配置属性值。
- Settings 全局参数配置
-
比如开启二级缓存,延迟加载等,这些参数的配置可能影响到Mybatis运行
-
- typeAliases (别名配置)
- 系统本身别名对照表
2、自定义别名
<typeAliases> <!-- 针对单个别名定义 type:类型的路径 alias:别名 --> <typeAliase type="" alias="" /> <!-- 针对批量别名定义 指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大小写都可以) --> <package name="com.packageName"> <package name="com.packageName"> </typeAliases>
- typeHandlers
-
完成jdbc类型和java类型的转换,比如“1” 和 1 转换。
-
- Mapper 映射加载配置
1、通过Resource加载单个映射文件,与前面代码一样。
2、通过Mapper接口加载,但必须遵循如下规范:
-
- mapper接口的类别和映射文件名必须保持一致,并且在同一目录
- 上面规范的前提是必须用的是mapper代理方法。
-
<!-- 加载单个 -->
<mapper class="com.packageName.InterfaceName" />
<!-- 批量加载多个-->
<mapper class="com.packageName" />
- resultMap 处理结果集高级映射,解决一对一,一对多,多对多的映射
<!-- 如果有多个Mapper文件,resultMap在其他文件中,前面要添加namespace的名字 -->
<select id="" parameterType="" resultMap="userResultMap">
select id id_,username username_from user
</select>
<!--
type:resultMap最终映射的java类型 id:唯一标示
--> <resultMap type="user" id="userResultMap"> <!-- column:查询结果集中唯一标识id result:结果集映射一对一关系 --> <id column="id_" property="id"></id> <result column="username_" property="username"></result> </resultMap>
六、动态sql
七、sql片段
抽取出共同的sql语句作为sql片段,经验:1、sql片段一般是基于单表创建的,这样可以提供重用率;2、片段中不要包含where片段。
1、创建sql片段,如下图:
2、引用sql片段
<!--引用方法如下-->
<include refid="query_user_where">
3、foreach
八、高级映射
1、针对一对一查询,resultType和resultMap查询总结
①对于查询结果,如果没有特殊要求,resultType比resultMap合适。
②resultMap具有延迟加载的功能,resultType没有。
2、一对多查询,使用collection
九、Spring和Mybatis整合
1、整合思路:
①需要spring 通过单例模式管理SqlSessionFactory.
②Spring和mybatis整合生成代理对象(Spring自动完成,不需要用户操作)
③使用SqlSessionFactory创建SqlSession对象。(Spring自动完成,不需要用户操作)
④Spring管理持久层的Mapper接口。
2、准备工作:
①导包:Mybatis的包、Spring的包、spring-mybatis整合包、spring-webmvc整合包
②建立配置文件目录结构:
Spring目录(配置spring环境的配置文件applicationContext.xml)、
Mybatis目录(存放mybatis的全局配置文件sqlMapConfig.xml)、
sqlMap目录(存放和Mapper接口相关的UserMap.xml文件,用于原生DAO开发,这里因为采用原生开发,xml文件和UserMapper接口不在同一目录);
③建立实体pojo目录、mapper接口目录
- 第一步配置SqlSessionFactory,具体步骤如下:
- 在applicationContext.xml中配置sqlsessionfactory,sqlsessionfactory在spring和mybatis 的整合包中。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载mybatis配置文件 -->
<property name="configLocation" value="sqlmap/sqlMapConfig.xml"></property>
<property name="datasource" ref="dataSource"></property>
</bean>
2、配置数据源
- 原生DAO开发,整合需要做的事
1、在sqlMapConfig中加载****mapper.xml文件
测试类
- Mapper代理开发
十、逆向工程自动生成代码
下载逆向工具项目文件,修改配置文件的路径,添加表的名字,运行项目即可。