ssm--mybatis1

mybatis的概述:
	mybatis是一个用java编写的持久层框架,它使用了ORM思想实现了结果集的封装。
	ORM:
		Object Relational Mappging 对象关系映射
		简单的说:
			就是把数据库表字段和实体类的属性对应起来,让我们可以操作实体类就实现操作数据库表。

window下的mysql不区分大小写,linux下的mysql严格区分大小写

自定义mybatis框架:
	在ConfigurationBean中,
	private Map<String,mapper> mappers = new HashMap<String,mapper>();
	public Map<String,Mapper> setMappers(Map<String,mapper> mappers){
    	/**
    	*	此处setter方法不能用:this.mappers=mappers;
    	*	因为mappers可能会有多个,如果用this,那么后面的mappers会覆盖上一个mappers;
    	*	变量声明的时候必须new HashMap<String,mapper>(),否则第一次调用this.mappers会空指针,而且
    	*	Map是一个接口,它的putAll()方法也没有明确的方法体。
    	*/
        this.mappers.putAll(mappers);
}
	
	mappers对象的key: String key1 = namespace + "." + id ;
	mappers对象的value: mapper对象-->field: queryString(sql), resultType
最终ProxyMapper对象代理对象调用方法的时候,通过: 
	String methodName = method.getName();
	String packageName = method.getDeclaringClass().getName();
	String key2 = packageName + "." + methodName;
	Mapper mapper = mappers.get(key2);
	if(mapper!=null){"说明调用的接口方法找到了对应的映射配置文件的mapper"}

主配置文件的约束

<?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">

映射配置文件的约束

<?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">

mybatis的坐标

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.5</version>
</dependency>
//读取sqlMapConfig.xml
InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
//加载配置文件,获取SqlSessionFactory对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
//获取单个SqlSession
SqlSession sqlSession = factory.openSession();
//获取DAO层接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class)
	.....





**SqlMapConfig.xml的配置**

```xml
<!--配置数据库连接环境-->
<!--二者选其一-->
	<!--静态配置-->
	<properties>
        <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
        <property name="jdbc.url" value="jdbc:mysql://localhost:3306/db3"/>
        <property name="jdbc.username" value="root"/>
        <property name="jdbc.password" value="root"/>
	</properties>
	<!--动态配置-->
	<properties resource="./jdbcConfig.properties"></properties>
<!--------------------------------------------------------------------------------------->
<!--配置类型别名-->
<typeAliases>
    <!--单个类型别名定义-->
    	<typeAlias alias="user" type="com.baidu.User"/>
    <!--批量类型别名定义-->
            <!--扫描整个包下的类,别名为类名(首字母大写或小写都可以-->
     	<package name="com.baidu.domain"/>
      </typeAliases>
<!--------------------------------------------------------------------------------------->
<environments>
    ...
	  <property name="driver" value="${jdbc.driver}"/>
    ...
</environments>
mappers(映射器)的配置:
	<mapper resource=""/> //使用相对于类路径的资源,相对路径,xml配置
 eg: <mapper reource="com/baidu/dao/IUserDao.xml"/>
 	<mapper class=""/> //使用mapper接口的全限定类名,全类名,注解配
 eg: <mapper class="com.baidu.dao.UserDao"/>
   	<package name=""/>  //注册指定包下的所有接口和映射配置文件,注意不要重名
 eg: <package name="com.baidu.dao"/>
        //配置映射文件的包路径必须跟接口的包路径一致,package会扫描映射文件包和接口包
        //所以使用这个配置,既支持注解配置,又支持xml配置
        //如果注解配置跟xml配置冲突了,就会报错

IUserDao.xml的配置

映射配置文件的注意事项:
	1.接口全限定名与映射文件的namespace对应
	2.接口中方法名与映射文件中sql语句的id对应
	3.接口中方法参数与parameterType对应
	4.接口中方法的返回值与resultType或者resultMap对应
<mapper namespace="com.itheima.dao.IUserDao">
	<select id="queryUserByName" parameterType="com.baidu.domain.User" resultType="Integer">
        select * from user where id = #{name};
    </select>
</mapper>
mybatis底层每次都会: connection.setAutoCommit(false);
注意:增加、删除、修改操作时,必须提交事务:sesseion.commit();
parameterType 支持赋值普通类型(17种)、pojo类型(User)、pojo包装类型(QueryVo)
	普通类型:byte/short/int/long/double/float/char/boolean,基本类型的包装类(8种),String
	pojo类型:普通的javabean
	QueryVo类型:pojo的包装类,多个pojo类型作为QueryVo的成员变量
	<select id="queryUserByName" parameterType="参数类型">
        //参数类型是普通类型
        name = #{任意变量}			  //eg:#{hello}
        //参数类型是pojo类型
        name = #{pojo的属性值}			//eg:#{name}
        //参数是QueryVo类型, ognl取值
        name = #{pojo包装对象的属性名称.pojo对象的属性值}  //eg:#{user.name}
	</select>	

    ${value}表示字符串拼接,value不能随便改,会造成sql注入问题
    传入的是普通类型:${value}        //模糊查询: '%${value}%'
    传入的是pojo类型: ${pojo对象的属性名称}   
    传入的是pojo包装类型:${pojo包装对象的属性名称.对应的属性} 	

如果一个方法中有多个参数,并且参数都是普通数据类型,可以使用@Param注解解决参数注入问题
@Insert("insert into user values(#{username},#{password})")
testAddUser(@Param("username")String username,@Param("password")String password){ ... }
如果使用的xml配置,参数是多个普通数据类型,省略掉parameterType即可
#{}和${}的区别:
	#{}是一个占位符,mybatis在处理#{}时,会将其转换成?,通过#{}可以实现PreparedStatement向占位符进行赋值,自动进行java类型和jdbc类型转换,可以有效防止sql注入问题
    ${}是字符串的替换,就是把${}替换成变量的值,通过${}可以将parameterType传入的值替换到sql中,且不进行jdbc类型转换
	jdbc类型对应的就是mysql中的数据类型,自动进行jdbc类型转换的好处,比如java:new Date()封装到mysql中,new Date()得到的是Tue Sep 18 10:56:31 CST 2018,这个明显是跟mysql的Date类型不对应的,因此需要转换成jdbc类型
resultType 支持返回普通类型(17种),pojo类型
    输出的是普通类型:resultType="int" //int本质上是输出Integer类型,如果必须要int类型,resultType="_int",基本数据类型都遵循"_基本数据类型";
    输出的是pojo类型:resultType="com.baidu.domain.User" //User
    输出的是列表:resultType="com.baidu.domain.User"  //List<User>
 实体类属性名称跟数据库的列名不匹配,如何处理?
第一种方式:
	给sql语句的字段起别名,别名跟实体类属性值对应即可
	select id as uid ,....
第二种方式:
	resultMap 建立domain实体和数据库表的对应关系
	<mapper>
	<resultMap type="com.baidu.domain.User" id="userMap">
		<id column="id" property="uid"/>
         <result column="username" property="name"/>
         <result column="age" property="uage"/>
	</resultMap>
        <select id="queryUser" resultMap="userMap">
            select * from user
        </select>
	</mapper>
type 属性:指定实体类的全限定类名
id 属性:给定一个唯一标识,是给查询 select 标签引用用的。
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称 
配置插入操作后,封装插入数据的id
	<insert id="insertUser" parameterType="com.baidu.domain.User">
        insert into user values(null,"hello",23);
        <selectKey order="AFTER" resultType="Integer" keyColumn="id" keyProperty="id">
        	select last_insert_id();	
        </selectKey>    
	</insert>
	//执行完这个标签的代码后,会将插入数据的id封装到user对象中,如果user对象原来就有id,原有的id会被替换掉
模糊查询的配置:
	<select id="findByName" parameterType="string" resultType="com.baidu.domain.User">
        第一种方式: select * from user where name like '%${value}%' ;
        第二种方式: select * from user where name like #{username};
	</select>

模糊查询的注意点:
     当在SqlMapConfig.xml中动态配置数据库连接,<properties resource="JdbcConfig.properties"></properties>时,通常我们会配置username=root,并且取值的时候也是用${username}来取;此时如果配置模糊
查询,比如username like '${username}' 由于mybatis先读取的SqlMapConfig.xml因此${username}得到的值
也只会是root;拼接到statement中就是 where username like 'root';最好解决方案就是配置JdbcConfig.properties时,都带上jdbc,比如jdbc.username

猜你喜欢

转载自blog.csdn.net/qq_42514129/article/details/84130794