SSM框架之Mybatis

springmvc+spring+mybatis  56课时  24k商城

ssm、maven、通用mapper、shiro(了解)、vue.js(掌握)


防止sql注入

mybatis

1.传统的jdbc

加载驱动

获取链接connection

获取预处理对象statement

设置sql(采用占位符,防止sql注入)

给占位符设置值

执行获取结果集

对结果集进行封装

释放资源

问题:

1.频繁的创建链接,释放资源  造成了系统资源浪费。----->数据库连接池

2.sql语句在java代码中,造成后期维护不易

3.占位符设置值,存在硬编码,where语句里 条件不固定,造成维护不易

4.对结果集的解析封装存在硬编码,

2.ORM简介

Object Relational Mapping :对象关系映射

简单的理解为:ORM是通过 使用描述对象和数据库库之间的映射关系的元数据,将程序中的 对象自动的持久化到关系型数据库中。

hibernate、mybatis

3.mybatis架构

mybatis是一个ORM框架,是一个基于java的持久层框架

mybatis会对jdbc的操作过程进行封装,使得开发者只需要关注SQL本身,而无需去花费精力去处理 注册驱动、获取链接、设置参数、结果集分析、释放资源等工作,可以简化jdbc开发成本。

mybatis.xml(全局配置文件,名字是不固定的)

作用:配置mybatis的运行环境,数据源/事物

mapper.xml:映射文件。sql语句 需要在全局配置文件中加载

sqlSessionFactory:会化工厂。根据全局配置文件来创建工厂,创建工厂

作用:创建会话的

sqlSession:会话。作用:操作数据库的

Executor(执行器):会话是通过执行器来操作数据库的

mapped statement :底层封装对象

作用:对操作数据库的过程进行封装,包括sql、输入参数、结果集

mysql数据库

输入参数类型:

java简单类型

pojo自定义对象

hashmap

输出结果类型:

java简单类型

pojo自定义对象

hashmap

 

4.mybatis环境搭建

  1. 新建java项目,导入jar包 mybatis-3.2.7.jar junit
  2. 配置log4j.properties打印日志
  3. 配置mybatis全局配置文件
	<!-- 运行环境:与spring整合后就不需要了 
	default="" 运行哪个环境,里面是id
	-->
	<environments default="mysql">
		<environment id="mysql">
			<!-- 事务管理 -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- 数据源 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf-8"/>
				<property name="username" value="root"/>
				<property name="password" value="111111"/>
			</dataSource>
		</environment>
	</environments>
	<!-- 加载映射文件 -->
	<mappers>
		<mapper resource="UserMapper.xml"/>
	</mappers>

5.入门案例

  1. pojo对象
  2. 映射文件mapper.xml
    <?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=""作用: 分割sql -->
    <mapper namespace="UserMapper">
    	<!-- 入门程序:根据id查询用户信息 
    		id:唯一的(本namespace下唯一),用于标识映射文件的sql,称为statment的id
    		paramentType:输入参数类型; 支持的类型包括java基本类型、pojo对象、hashmap
    		resultType:输出结果类型; 指定的为单条记录的类型
    		#{}:占位符    注意:如果输入参数类型是基本类型,则#{}里面可以是任意参数。或者是#{value}
    	-->
    	<select id="selectById" parameterType="int" resultType="com.cbb.pojo.User">
    		select * from user where id = #{id}
    	</select>
    </mapper>
  3. 测试用例
    	//1.加载mybatis的运行环境  io流的方法去读取全局配置文件
    	InputStream is =Resources.getResourceAsStream("mybatis.xml");
    	//2.创建会化工厂
    	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    	//3.获取会话
    	SqlSession sqlSession = sqlSessionFactory.openSession();					
    	//4.操作数据库
    	//第一个参数:statement的id  具体执行的sql  写法是:namespace.id
    	//第二个参数:值
    	User user = sqlSession.selectOne("UserMapper.selectById",1);
    	System.out.println(user);
    	sqlSession.close();//释放资源

JUnit Test

	/**
	 * 在@Test方法执行前 执行,可以进行一些初始化的工作
	 */
	@Before
	public void init(){
		System.out.println("init。。。。。。。。");
	}
	
	
	/** 
	 * 方法描述:JUnit Test
	 */
	@Test
	public void name() {
		System.out.println("执行了测试方法!");
	}
	
	
	/** 
	 * 方法描述:在@Test注解方法执行后再执行
	 */
	@After
	public void after(){
		System.out.println("善后工作。。。。释放资源等等。。。。");
	}

6.会话工厂与会话

SqlSessionFactory:会话工厂。通过全局配置文件创建的,由SqlSessionFactoryBuild对象创建。

  • 作用:创建会话。
  • 特点:会化工厂一旦创建,就会在应用程序的执行期间一直存在。我们就不需要重复的来创建这个会话工厂了。
  • 所以我们应该把它的实现方式设计为  单例模式的  (而不是他自身就是单例模式的)

SqlSession:会话。作用:操作数据库。

  • 特点:线程不安全的。应该把会话声明为局部的

7.全局配置文件的其他配置

起别名:

	<!-- 起别名 -->
	<typeAliases>
		<!-- type:指的是要被定义别名的类的全限定名 
			alias:自定义的别名
		-->
		<typeAlias type="com.cbb.pojo.User" alias="user"/>
		
		<!-- 批量起别名 name:包
			会批量扫描包下所有类 然后批量的起别名。 别名为类名(首字母大写或者小写都可以,即起了两个别名)
		 -->
		<package name="com.cbb.pojo"/>
	</typeAliases>

加载外部资源:

<!-- 加载资源文件 -->
<properties resource="db.properties"></properties>
<property name="driver" value="${jdbc.driver}"/>
jdbc.driver=com.mysql.jdbc.Driver

作业-0307 我爱登录的t_user表 新增、修改、删除、 查询(根据名字模糊查询、查询出生日在2010年~2019年中间的用户,并 且2010和2019是通过占位符设置)

8.传统的dao开发方法

dao接口

daoImpl实现

映射文件 

9.动态代理实现方式

dao接口

映射文件mapper.xml

只需要程序员编写Mapper接口(相当于dao接口),和映射文件,由mybatis框架根据 接口 来创建接口的动态代理对象,来代理接口方法的实现 (类似于传统dao开发方式中 的实现类)

规范要求:

  1. mapper.xml映射文件和mapper接口的名字必须一致。
  2. mapper.xml映射文件的namespace与接口的类全路径相同
  3. mapper.xml映射文件的statement的id与接口的方法名相同
  4. mapper.xml映射文件的参数类型parameterType与接口方法的参数类型相同
  5. mapper.xml映射文件的输出结果类型与接口方法的返回类型相同
<mappers>
<!-- 批量加载包下的 -->
<package name="com.cbb.mapper"/>
</mappers>

10.servlet与mybatis的整合

public class UserServiceImpl implements UserService{
    private SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory();//获取单例模式的会话工厂
    @Override
    public User selectById(int id) {
        SqlSession session = factory.openSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);//获取代理对象
        User user = userMapper.selectById(id);//方法调用
        session.close();//是否资源 如果是新增、修改、删除,关闭前记得要 调用 commit方法
        return user;
    }
}

作业-0308 我爱登录的项目。 加入mybatis框架来完成。 需要做的功能以下: 登录、注册、列表查询(根据,名字模糊查询所有)、用户表的新增、修改和删除

11.Mapper.xml详解

11.1.parameterType(输入类型)

java简单类型  int、String   #{占位符的方式,任意字符}

pojo自定义对象   新增   #{pojo的属性名}

hashmap

	<!-- hashmap用例 
	取值方式:#{map的key}
	注意:当时用map中不存在的key取值时,取值为空null。代码此处不报错-->
	<select id="selectByMap" parameterType="map" resultType="User">
		select * from user where sex = #{sex} and address like concat("%",#{address},"%")	
	</select>

多参数的

/** 
	 * 方法描述:多参数用例
	 * @param sex
	 * @param address
	 * @return
	 */
	//public List<User> selectByParams(@Param("sex")String sex, @Param("address")String address);
	public List<User> selectByParams(String sex,String address);
	<!-- 多参数的用例
	parameterType 可以省略掉
	@Param:作用:把注解的对象 set放到了map中,key就是("")
	第二种取值方式:#{index},下标index 从0开始,-->
	<select id="selectByParams" resultType="User">
		<!-- select * from user where sex = #{sex} and address like concat("%",#{address},"%") -->
		select * from user where sex = #{0} and address like concat("%",#{1},"%")
	</select>

11.2resultType(输出类型)

java简单类型的

pojo自定义对象

hashmap

11.3resultMap

resultType:在指定pojo对象接受 映射的结果集时,需要将pojo对象的属性名 和数据库表的字段名要一致。

如果有不一致的,则查询的该字段为null

解决名字不一致的方法:

方案一:给sql查询的字段as别名

	<!-- 方案一:给sql查询的字段 as 别名 ,别名和pojo对象的属性名一致 -->
 	<select id="selectAll" resultType="Car">
		select carId carId,name carName,userId userId from car 
	</select> 

方案二:使用resultMap

	<!-- 
	id:唯一的
	type:把结果集映射到那个对象上
	<id/>:结果集的主键 唯一标示
	<result/>:结果集的 普通字段
	column:表的字段名
	property:pojo对象的属性名
	column和property在一起表示 之间的映射关系
	可以仅仅是写名字不一致的字段
	 -->
	<resultMap type="Car" id="CarMap">
		<id column="carId" property="carId"/>
		<result column="name" property="carName"/>
		<result column="userId" property="userId"/>
	</resultMap>

	<!--resultMap:对应自定义的哪个resultMap的id  -->
	<select id="selectAll" resultMap="CarMap">
		select * from car
	</select>

如果使用resultMap来处理这种简单的 名字不一致的问题的时候,可以在resultMap里 只去配置这个 名字不一致的字段

(<id> 或<result>),名字一致的可以省略掉。

resultMap:除了能解决上述的名字 不一致的问题外,还可以结果映射复杂的pojo问题

	<resultMap type="UserVo" id="UserVoMap">
		<id column="id" property="id"/>
		<result column="username" property="username"/>
		<result column="sex" property="sex"/>
		<result column="birthday" property="birthday"/>
		<result column="address" property="address"/>
		<!-- 一对多集合 
		ofType:集合的类型-->
		<collection property="cars" ofType="Car">
			<id column="carId" property="carId"/>
			<result column="name" property="carName"/>
			<result column="userId" property="userId"/>
		</collection>
	</resultMap>

12.动态sql

通过mybatis提供的各种标签方法实现动态拼接sql。

if用例:

	<!-- 动态sql:if用例 
	if:语句判断,<if test="">使用and进行的并
	where:去除多余的and  或者是or
	-->
	<select id="selectIf" parameterType="map" resultType="User">
		select * from user 
		<where>
			<if test="sex!=null and sex!=''">
				and sex = #{sex}
			</if>
			<if test="address!=null and address!=''">
				and address like concat("%",#{address},"%")
			</if>
		</where>
	</select>

set用例:

	<!-- set :会去除多余的逗号-->
	<update id="updateUser" parameterType="User">
		update user
		<set>
		<if test="username!=null and username!=''">
			username = #{username} ,
		</if> 
		<if test="sex!=null and sex!=''">
			sex = #{sex} ,
		</if>
		<if test="address!=null and address!=''">
			address = #{address}
		</if>
		</set>
		 where id =#{id}
	</update>

foreach遍历:

	<!-- foreach:批量删除 
	collection:集合的类型。可以是list(list集合)还可以是array(数组)还可是map还可以pojo包装类中的属性名
	item:循环中的当前对象
	open:循环的开始
	close:循环的结束
	separator:分隔符
	-->
	<delete id="deleteBatch" parameterType="int">
		delete from user where id in
		<foreach collection="list" item="id11" open="(" close=")" separator=",">
			#{id11}
		</foreach>
	</delete>

作业0311 我爱登录 1、列表查询(根据实际条件查询 )/2、批量删除(复选框 删除button)

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值