j二期专题详解05课my及spring讲义_第1页
j二期专题详解05课my及spring讲义_第2页
j二期专题详解05课my及spring讲义_第3页
j二期专题详解05课my及spring讲义_第4页
j二期专题详解05课my及spring讲义_第5页
已阅读5页,还剩97页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1 Mybatis 需要关注的文件l POJO 类(DTO、VO、PO 等)l Mapper 接口(就是 dao 接口)l Mapper文件(重点)l 全局配置文件2 框架概述什么是框架为什么使用框架* 因为软件系统发展到今天已经很复杂了,特别是服务器端软件,涉及到的知识,内容,问题太多。* 在某些方面使用别人成框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。* 而且框架一般是成熟,稳健的,它可以处理系统很多细节问题,比如,事务处理,安全性, 数据流等问题。* 还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级协作构件之间的依赖、责

2、任分配和流程,表现为一组抽象类以及其实例之间协作的,它为构件复用提供了上下文(Context)。因此构件库的大规模重用也需要框架。可以说,一个框架是一个可复用的设计构件,它规定了应用的体系结构,阐明了整个设计、软件开发的三层结构我们用三层结构主要是使项目结构更清楚,分工更明确,有利于后期的维护和升级三层结构包含:表现层,业务层,持久层3 Mybatis什么是 mybatismybatis 参考:l Mybatis 是什么?* MyBatis 是一个优秀的持久层框架,它是一个半自动化的 ORM 框架的,你可以直接享受别人升级代码带来的好处。l Mybatis 的由来?l Mybatis 在哪写

3、SQL 语句?如何设置 SQL 参数和结果?JDBC 示例代码public class JDBCTest public static void main(String args) Connection connection = null;PreparedStatement preparedStatement = null; ResultSet resultSet = null;try / 加载数据库驱动Class.forName("com.mysql.jdbc.Driver");preparedStatemnt、CallableStatement)配置起来。* 并通过 ja

4、va 对象和 statement 中的 sql 进行生成最终执行的 sql 语句,最后由mybatis 框架执行 sql 并将结果成 java 对象并返回。* Mybatis 通过 XML 或注解的方式,将要执行的各种 statement(statement、* MyBatis 本是 apache 的一个开源项目 iBatis* 2010 年这个项目由 apache software foundation 迁移到了code,并且改名为MyBatis 。* 2013 年 11 月迁移到。* 它对使用 JDBC 操作数据库的过程进行,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如驱动

5、、创建 connection、创建 statement、手动设置参数、结果集检索等 jdbc 繁杂的过程代码。/ 通过驱动管理类获取数据库connection = DriverManagerconnection = DriverManager.getConnection("jdbc:mysql:/localhost:3306/mybatis?characterEncoding=utf-8", "root","root");/ 定义sql 语句 ?表示占位String sql = "select * from user whe

6、re username = ?"/ 获取预处理 statementpreparedStatement = connection.prepareStatement(sql);/ 设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的preparedStatement.setString(1, "");/ 向数据库发出 sql 执行,出结果集resultSet = preparedStatement.executeQuery();/ 遍历结果集while (resultSet.next() System.out.println(resul

7、tSet.getString("id")+ " " +resultSet.getString("username"); catch (Exception e) e.printStackTrace(); finally /if (resultSet != null) try resultSet.close(); catch (SQLException e) e.printStackTrace();if (preparedStatement != null) try preparedStatement.close(); catch (SQ

8、LException e) e.printStackTrace();if (connection != null) try Mybatis 如何解决 JDBC 代码中的问题1、 创建数据库连接相关操作,硬编码a)解决方案:通过 Mybatis 全局配置文件,对数据库连接进行配置2、 statement 相关操作,硬编码a)解决方案:通过 Mapper文件,对 statement 相关处理进行配置。3、 频繁开启数据库连接,会降低数据库处理性能。a)解决方案:通过 Mybatis 全局配置文件,配置连接池。Mybatis 架构原理我们要找出的就是:从 XML 配置文件到数据库的距离有多长?con

9、nection.close(); catch (SQLException e) / TODO Auto-generated catch block e.printStackTrace();MyBatis配置文件数据库说明:1、 mybatis 配置文件a)SqlMapConfig.xml,此文件作为 mybatis 的全局配置文件,配置了 mybatis 的运行环境等信息。b)Mapper.xml,此文件作为 mybatis 的 sql文件,文件中配置了操作数据库的sql 语句。此文件需要在 SqlMapConfig.xml 中加载。2、 SqlSessionFactory通过 mybatis

10、 环境等配置信息构造 SqlSessionFactory,即会话工厂。3、 sqlSession通过会话工厂创建 sqlSession 即会话,程序员通过 sqlsession 会话接口对数据库进行MappedStatement输入PojoString、Integer等基础数据类型Map输出ListPojoString、Integer等基础数据类型MapExecutorSqlSessionSqlSessionFactoryMappern.xmlMapper2.xmlMapper1.xmlSqlMapConfig.xml增删改查操作。4、 Executor 执行器mybatis 底层自定义了 E

11、xecutor 执行器接口来具体操作数据库,Executor 接口有两个实现,一个是基本执行器(默认)、一个是缓存执行器,sqlsession 底层是通过executor 接口操作数据库的。5、 Mapped Statement它也是 mybatis 一个底层对象,它包装了 mybatis 配置信息及 sql信息等。mapper.xml 文件中一个 selectinsertupdatedelete对应一个 MappedStatement 对象,selectinsertupdatedelete的 id 即是 Mapped statement的 id。a)Mapped Statement 对 sq

12、l 执行输入参数进行定义,HashMap、基本类型、pojo,Executor 通过 Mapped Statement 在执行 sql 前将输入的 java对象至 sql 中,输入参数就是 jdbc 编程中对 preparedStatement设置参数。b)Mapped Statement 对 sql 执行输出结果进行定义,HashMap、基本类型、pojo,Executor 通过 Mapped Statement 在执行 sql 后将输出结果至 java 对象中,输出结果过程相当于 jdbc 编程中对结果的处理过程。4 Mybatis 入门需求1、根据用户id一个用户信息2、根据用户名称模糊

13、用户信息列表3、添加用户4、更新用户5、删除用户Mybatis 开发框架搭建l 创建 maven 工程:mybatisl POM 文件<dependencies><!- mybatis依赖 -><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency><!- mysql依赖 -><dependen

14、cy><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.35</version></dependency><!- 单元测试 -><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version&

15、gt;</dependency>l SqlMapConfig.xmll UserMapper.xmll PO 类public class User private int id;private String username; private Date birthday; private String sex; private String address;/gettersetter<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-/my

16、/DTD Mapper 3.0/EN"""><mapper namespace="test"></mapper><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//DTD Config 3.0/EN"""><configuration><properties re

17、source="perties"></properties><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver" value="$db.dr

18、iver" /><property name="url" value="$db.url" /><property name="username" value="$db.username" /><property name="password" value="$db.password" /></dataSource></environment></environments><mappe

19、rs><mapper resource="UserMapper.xml" /></mappers></configuration></dependencies>需求实现根据 id用户信息文件lparameterType:定义输入到 sql 中的类型,#id表示使用 preparedstatement 设置占位号并将输入变量 id 传到 sql。resultType:定义结果类型。#:相当于 JDBC 中的?占位l 测试代码public class MybatisFirst /会话工厂private SqlSessionF

20、actory sqlSessionFactory;Beforepublic void createSqlSessionFactory() throws IOException / 配置文件String resource = "SqlMapConfig.xml"InputStream inputStream = Resources.getResourceAsStream(resource);<!- 根据id获取用户信息 -><select id="findUserById" parameterType="int" re

21、sultType="com.kkb.mybatis.po.User"> select * from user where id = #id</select>/ 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);/ 根据 id用户信息Testpublic void testFindUserById() / 数据库会话实例SqlSession sqlSession

22、= null;try / 创建数据库会话实例sqlSessionsqlSession = sqlSessionFactory.openSession();/单个,根据用户id用户信息User user = sqlSession.selectOne("test.findUserById", 10);/ 输出用户信息System.out.println(user); catch (Exception e) e.printStackTrace(); finally if (sqlSession != null) 根据用户名模糊用户列表文件lparameterType:定义输入到

23、sql 中的类型,$value表示输入参数将$value替换,做字串的拼接。注意:如果是取简单数量类型的参数,括号中的参数名称必须为 valueresultType:定义结果类型。l 测试代码/ 根据用户名称模糊用户信息Testpublic void testFindUserByUsername() / 数据库会话实例SqlSession sqlSession = null; try <!- 自定义条件用户列表 -><select id="findUserByUsername" parameterType="java.lang.String&qu

24、ot; resultType="com.kkb.mybatis.po.User">select * from user where username like '%$value%'</select>sqlSession.close();#和$区别区别 1l#:相当于 JDBC SQL 语句中的占位? (PreparedStatement)$: 相当于 JDBC SQL 语句中的连接合 + (Statement)区别 2l#: 进行输入的时候,会对参数进行类型(如果是 String 类型,那么 SQL 语句/ 创建数据库会话实例sqlSess

25、ionsqlSession = sqlSessionFactory.openSession();/单个,根据用户id用户信息List<User> list = sqlSession.selectList("test.findUserByUsername", "小明");System.out.println(list.size(); catch (Exception e) e.printStackTrace(); finally if (sqlSession != null) sqlSession.close();会自动加上)$:进行输入的时候

26、,将参数原样输出到 SQL 语句中l 区别 3# : 如果进行简单类型(String、Date、8 种基本类型的包装类)的输入时,#中参数名称可以任意$: 如果进行简单类型(String、Date、8 种基本类型的包装类)的输入时,$中参数名称必须是 valuel$ :SQL 注入问题,使用 OR 1=1 关键字将条件忽略添加用户文件ll 测试代码/ 添加用户信息Testpublic void testInsert() / 数据库会话实例<!- 添加用户 -><insert id="insertUser" parameterType="com.k

27、kb.mybatis.po.User"> insert into user(username,birthday,sex,address) values(#username,#birthday,#sex,#address)</insert>l 主键返回SqlSession sqlSession = null; try / 创建数据库会话实例sqlSessionsqlSession = sqlSessionFactory.openSession();/ 添加用户信息User user = new User(); user.setUsername(""

28、); user.setAddress("河南郑州"); user.setSex("1"); user.setPrice(1999.9f);sqlSession.insert("test.insertUser", user);/提交事务sqlSmit(); catch (Exception e) e.printStackTrace(); finally if (sqlSession != null) sqlSession.close();<insert id="insertUser" parameterType

29、="com.kkb.mybatis.po.User"><!- selectKey将主键返回,需要再返回 -><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">select LAST_INSERT_ID()</selectKey>insert into user(username,birthday,sex,address)values(#username,#birthday,#se

30、x,#address);</insert>添加 selectKey实现主键返回。* keyProperty:指定返回的主键,在 pojo 中的哪个属性* order:selectKey中的 sql 的执行顺序,是相对与 insert 语句来说。由于 mysql 的自insert 语句之后主键生成,所以这里 selectKey 的执行顺序为after。* resultType:返回的主键对应的 JAVA 类型* LAST_INSERT_ID():是 mysql 的函数,返回 auto_increment 自增列新id 值。OGNL对象导航图语言|-User(参数值对象)|-usern

31、ame-张三|-birthday|-sex-男|-dept - Department|-name|-noOGNL 表达式去获取 Department 对象的 name 属性:删除用户文件ll 测试代码/ 根据id删除用户Testpublic void testDelete() / 数据库会话实例SqlSession sqlSession = null; try / 创建数据库会话实例sqlSessionsqlSession = sqlSessionFactory.openSession();/ 删除用户sqlSession.delete("test.deleteUs

32、erById",18);/ 提交事务sqlSmit(); catch (Exception e) e.printStackTrace(); finally <!- 删除用户 -><delete id="deleteUserById" parameterType="int"> delete from user where id=#id</delete>修改用户文件ll 测试代码/ 更新用户信息Testpublic void testUpdate() / 数据库会话实例SqlSession sqlSession

33、= null; try / 创建数据库会话实例sqlSessionsqlSession = sqlSessionFactory.openSession();/ 添加用户信息User user = new User();<!- 更新用户 -><update id="updateUser" parameterType="com.kkb.mybatis.po.User"> update user setusername=#username,birthday=#birthday,sex=#sex,address=#address wher

34、e id=#id</update>if (sqlSession != null) sqlSession.close();user.setId(16);user.setUsername("");user.setAddress("河南郑州");user.setSex("1");user.setPrice(1999.9f);sqlSession.update("test.updateUser", user);/ 提交事务sqlSmit(); catch (Exception e) e.printStackTr

35、ace(); finally if (sqlSession != null) sqlSession.close();5 Mybatis 开发Dao 层原始 dao 开发方式说明:该种方式一般来说只会出现在那些从 ibatis 项目迁移过来的项目。生命周期(作用范围)l1.sqlsession:级别2.sqlsessionFactory:全局范围(应用级别)3.sqlsessionFactoryBuilder:级别dao 接口和实现类lpublic interface UserDao public User findUserById(int id) throws Exception;public

36、 void insertUser(User user) throws Exception;public class UserDaoImpl implements UserDao /注入SqlSessionFactorypublic UserDaoImpl(SqlSessionFactory sqlSessionFactory)this. sqlSessionFactory = sqlSessionFactory;private SqlSessionFactory sqlSessionFactory;Overridepublic User findUserById(int id) throws

37、Exception SqlSession session = sqlSessionFactory.openSession();User user = null;try /通过sqlsession调用selectOne获取一条结果集/参数1:指定定义的statement的id,参数2:指定向statement中传递的参数user = session.selectOne("test.findUserById", id);System.out.println(user); finallysession.close();return user;OverridePublic void

38、 insertUser(User user) throws Exception SqlSession sqlSession = sqlSessionFactory.openSession();try sqlSession.insert("insertUser", user);文件l<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//DTD Mapper 3.0/EN""">

39、;<mapper namespace="test"><!- 根据id获取用户信息 -><select id="findUserById" parameterType="int" resultType="com.kkb.mybatis.po.User">select * from user where id = #id</select><!- 添加用户 -><insert id="insertUser" parameterType=

40、"com.kkb.mybatis.po.User"><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID()sqlSmit(); finallysession.close();l 测试代码private SqlSessionFactory sqlSessionFactory;Beforepublic void init() throws Exception Sq

41、lSessionFactoryBuildersessionFactoryBuilder=newSqlSessionFactoryBuilder();InputStreaminputStream= Resources.getResourceAsStream("SqlMapConfig.xml");sqlSessionFactory = sessionFactoryBuilder.build(inputStream);Testpublic void testFindUserById() UserDao userDao = new UserDaoImpl(sqlSessionFa

42、ctory);</selectKey>insert into user(username,birthday,sex,address) values(#username,#birthday,#sex,#address)</insert></mapper>mapper开发方式(JDK 的方式)动态分为两种方式:基于 JDK 的动态-有接口的类进行动态基于 CGLIB 的动态-通过子类继承父类的方式去进行。XML 方式l 使用只需要开发 Mapper 接口(dao 接口)和 Mapper 约束文件,不需要编写实现类。l 开发规范Mapper 接口开发需要遵循以下规

43、范:1、 Mapper 接口的类路径与 Mapper.xml 文件中的 namespace 相同。2、 Mapper 接口名称和 Mapper.xml 中定义的每个 statement 的 id 相同。3、 Mapper 接 口的 输 入 参 数 类 型 和 mapper.xml 中 定 义 的 每 个 sql 的parameterType 的类型相同。4、 Mapper 接口的返回值类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同。User user = userDao.findUserById(22); System.out.println(user

44、);l mapper文件l mapper 接口l 加载文件<!- 加载文件 ->/* 用户管理mapper*/public interface UserMapper /根据用户id用户信息public User findUserById(int id) throws Exception;<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//DTD Mapper 3.0/EN""">

45、<mapper namespace="com.kkb.mybatis.mapper.UserMapper"><!- 根据id获取用户信息 -><select id="findUserById" parameterType="int" resultType="com.kkb.mybatis.po.User">select * from user where id = #id</select></mapper>l 测试代码public class UserMa

46、pperTestprivate SqlSessionFactory sqlSessionFactory;Beforepublic void setUp() throws Exception /mybatis配置文件String resource = "SqlMapConfig.xml"InputStream inputStream = Resources.getResourceAsStream(resource);/使用SqlSessionFactoryBuilder创建sessionFactorysqlSessionFactory = new SqlSessionFact

47、oryBuilder().build(inputStream);Testpublic void testFindUserById() throws Exception /获取sessionSqlSession session = sqlSessionFactory.openSession();/获取mapper接口的对象UserMapper userMapper = session.getMapper(UserMapper.class);<mappers><mapper resource="mapper/UserMapper.xml"/></m

48、appers>注解方式(后续讲解)6 全局配置文件配置内容SqlMapConfig.xml 中配置的内容和顺序如下:properties(属性)settings(全局配置参数) typeAliases(类型别名)typeHandlers(类型处理器)-Java 类型-JDBC 类型->数据库类型转换objectFactory(对象工厂)plugins(插件)-可以在 Mybatis 执行 SQL 语句的流程中,一脚去实现一些功能增/调用对象User user = userMapper.findUserById(1); System.out.println(user);/关闭sess

49、ion session.close();propertiesSqlMapConfig.xml 可以java 属性文件中的配置信息。1、在 classpath 下定义 perties 文件,2、在 SqlMapConfig.xml 文件中,perties 中的属性,具体如下:<properties resource="perties"/><environments default="development">jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdb

50、c:mysql:/localhost:3306/ssm?characterEncoding=utf-8 jdbc.username=rootjdbc.password=root强,比如 PageHelper 分页插件,就是第实现的一个插件environments(环境集合属性对象) environment(环境子属性对象)transactionManager(事务管理) dataSource(数据源)mappers(器)properties除了可以使用 resource 属性,properties 文件中的属性。还可以在properties内定义 property 子来定义属性和属性值,具体如

51、下:注意: MyBatis 将按照下面的顺序来加载属性:u properties 元素体内定义的属性。<properties><property name="driver" value="com.mysql.jdbc.Driver"/></properties><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED&quo

52、t;><property name="driver" value="$jdbc.driver"/><property name="url" value="$jdbc.url"/><property name="username" value="$jdbc.username"/><property name="password" value="$jdbc.password"/><

53、/dataSource></environment></environments>typeAlias别名的作用:就是为了简化文件中 parameterType 和 ResultType 中的 POJO 类型名称编写。默认支持别名别名的类型_bytebyte_longlong_shortshort_intint_integerint_doubledouble_floatfloat_booleanbooleanstringStringbyteBytelongLongshortShortintIntegeru properties 元素中 resource 或 url

54、加载的属性,它会覆盖已的同名属性。自定义别名在 SqlMapConfig.xml 中进行如下配置:<typeAliases><!- 单个别名定义 -><typeAlias alias="user" type="com.kkb.mybatis.po.User"/><!- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -><package name="com.kkb.mybatis.po"/></typeAliases>integerInteg

55、erdoubleDoublefloatFloatbooleanBooleandateDatedecimalBigDecimalbigdecimalBigDecimalmapMapmappers<mapper resource=""/>使用相对于类路径的如:<mapper resource="sqlmap/User.xml" /><mapper url="">使用绝对路径加载如:<mapper url="file:/d:/sqlmap/User.xml" /><m

56、apper class=""/>使用 mapper 接口类路径,加载文件。如:<mapper class="com.kkb.mybatis.mapper.UserMapper"/>注意:此种要求 mapper 接口名称和 mapper文件名称相同,且放在同一个目录中。<package name=""/>指定包下的所有 mapper 接口,来加载文件。如:<package name="com.kkb.mybatis.mapper"/>注意:此种要求 mapper 接口名称和

57、mapper文件名称相同,且放在同一个目录中。7 输入和输出parameterType(输入类型)l parameterType 属性可以的输入参数类型有:l Map 类型和POJO 类型的用法类似,本课程只讲 POJO 类型的相关配置。l List 类型在动态 SQL 部分进行讲解。传递简单类型参考入门案例中的根据用户 ID用户信息的案例。传递 pojo 对象l 参考入门案例中的添加用户的案例。传递 pojo 包装对象l 包装对象:pojo 类中包含 pojo。l #:是通过反射获取数据的-StaticSqlSourcel $ : 是通过 OGNL 表达式会随着对象的嵌套而相应的发生层级变化

58、-DynamicSqlSource简单类型、POJO 类型、Map 类型、List 类型(数组)。 需求l 在综合的场景中,需要根据不同的条件进行用户列表的。l 这些条件中,可能会用户信息中的用户名称,还可能商品信息的商品名称。 分析1、通过 mybatis 传递多个条件时,需要使用 pojo 或者 map 来传递。2、通过 pojo 传递参数的话,需要定义一个包装对象,该对象用户数据或者商品数据。 QueryVO定义包装对象 QueryVO SQL 语句SELECT * FROM user where username like '%小明%' Mapper 文件<!- 使用包装类型用户使用ognl 从对象中取属性值,如果是包装对象可以使用.操作 来取内容部的属性-><select id="findUserList" parameterType="queryVo" resultType="user">pu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论