历时一个星期的mybatis 才学了一半,不过没有关系慢慢来,先来总结下,然后学习下一阶段的mybatis
1.mybatis 介绍
mybatis 是对jdbc的操作数据库的过程进行封装,使开发者只需关注SQL本身,不需要花费精力去处理注册驱动、创建statement,设置参数等jDBC中重复的操作。
2.mybatis入门
(1)、创建工程、加入jar包
(2)、创建SqlMapConfig.xml,
SqlMapConfig.xml是mybatis核心配置文件,配置内容为数据源、事务管理。当然名字也可以不为SQLMapconfig.xml
<configuration> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="mysql" /> </dataSource> </environment> </environments> </configuration>
(3)、创建Po类(作为mybatis进行映射使用)
(4)、创建mapper.xml映射,加载mapper.xml到sqlMapconfig.xml上
其中mapper.xml的格式
<mapper namespace ="mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="mybatis.po.User">
select * from user where id=#{id}
</select>
<select id="findUserByName" parameterType="java.lang.String" resultType="User">
select * from user where username like '%${value}%'
</select>
<select id="findUserByNameMap" parameterType="java.lang.String" resultMap="userResultMap">
select id id_,username username_ from user where username like '%${value}%'
</select>
</mapper>
其中mapper的namespace 一般用作sql隔离,如果用mapper映射来实现dao接口,则namespace 一般写作dao接口的路径
parameterType、resultType一般有三种类型:基本数据类型,pojo类型,hashMap
#{}表示一个占位符,自动将javal类型和jdbc类型转换,可以接收简单类型和pojo属性值 ,可以防止sql注入,如果parameterType传输的是个简单类型,#{}可以是value和其他名称
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
(5)创建测试程序
selectOne查询一条记录,selectList 查询出多条记录
3.dao的开发方式
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。
(1)Dao 的原始开发方法
Public class UserDaoImpl implements UserDao {
//注入SqlSessionFactory
public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
this.setSqlSessionFactory(sqlSessionFactory);
}
private SqlSessionFactory sqlSessionFactory;
@Override
public User getUserById(int id) throws Exception {
SqlSession session = sqlSessionFactory.openSession();
User user = null;
try {
//通过sqlsession调用selectOne方法获取一条结果集
//参数1:指定定义的statement的id,参数2:指定向statement中传递的参数
user = session.selectOne("test.findUserById", 1);
System.out.println(user);
} finally{
session.close();
}
return user;
}
直接通过selectOne方法映射参数和对应的statementID
(2)Mapper动态代理方式
必须遵循的规范
1、Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
public interface UserMapper {
public User findUserById(int id);
public List<User> findUserByName(String name);
public void InsertUser(User user);
public void deleteById(int id);
public void updateUser(User user);
public List<UserCustom> findUserList(UserVo userVo);
public List<User> findUserByNameMap(String name);
}
<mapper namespace ="mybatis.mapper.UserMapper">
<!-- 在映射文件中配置很多sql语句 -->
<!--通过select执行数据库查询
id:标识映射文件中的sql,将sql语句封装到mappedstatement对象中
#{id}其中的id表示接入输入的参数,参数名称就是id,如果输入参数是简单类型,#{}的参数名可以任意,可以value
或其他名称
resultType:指定sql输出结果的所映射的java对象类型,select指定resultType表示将单条记录映射成
java对象
通过${}符号只能用value 表示自动拼接
-->
<!-- type 表示map最终映射的java对象类型,可以使用别名
id,对result Map的唯一标识
-->
<sql id="query_user_nameorsex">
<if test="userCustom!=null and userCustom!=''">
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
<if test="userCustom.sex!=null and userCustom.sex!=''" >
and sex = #{userCustom.sex}
</if>
<if test="lds!=null and lds!=''">
<foreach collection="lds" item="user_id" open="and (" close=")" separator="or">
id = #{user_id}
</foreach>
</if>
</if>
</sql>
<resultMap type="user" id="userResultMap">
<id column="id_" property="id"/>
<result column="username_" property="username"/>
</resultMap>
<select id="findUserList" parameterType="userVo" resultType="userCustom">
select * from user
<where>
<include refid="query_user_nameorsex"></include>
</where>
</select>
<select id="findUserById" parameterType="int" resultType="mybatis.po.User">
select * from user where id=#{id}
</select>
<select id="findUserByName" parameterType="java.lang.String" resultType="User">
select * from user where username like '%${value}%'
</select>
<select id="findUserByNameMap" parameterType="java.lang.String" resultMap="userResultMap">
select id id_,username username_ from user where username like '%${value}%'
</select>
<insert id="InsertUser" parameterType="mybatis.po.User">
<!--
将出入数据的主键返回,返回到user对象中
select Last_insert_ID():得到刚insert进去的主键值,值使用与自增长
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select Last_insert_id()
</selectKey>
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
<delete id="deleteById" parameterType="int">
delete from user where id=#{id}
</delete>
<update id="updateUser" parameterType="mybatis.po.User" >
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>
</mapper>
@Test public void deleteUserByIdtest() { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.deleteById(30); sqlSession.commit(); }
4.SqlMapConfig.xml配置文件
(1)、properties
SqlMapConfig.xml可以引用java属性文件中的配置信息。
创建一个db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=mysql
将文件引入,通过${}获取参数
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
parameterType传递的属性具有最高优先级,resource或 url 加载的属性次之,最低优先级的是 properties 元素体内定义的属性。
5.自定义别名
可以定义整个包,也可以定义一个类
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="cn.itcast.mybatis.po.User"/>
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="cn.itcast.mybatis.po"/>
<package name="其它包"/>
</typeAliases>
6.mapper配置的方式
(1)相对于类路径的资源 <mapper resource="sqlmap/User.xml" />
(2)完全限定路径 <mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />
(3)使用mapper接口类路径 <mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
(4)指定包下的所有mapper接口 <package name="cn.itcast.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
6.动态sql
(1)where 和 if (where 默认第一个不封装and)
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
(2)foreach
<if test="ids!=null and ids.size>0">
<foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >
#{id}
</foreach>
</if>
open 表示开头一段是什么 close 表示连接一段是什么 separator表示每个间隔是什么
(3)sql片段
将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的
<sql id="query_user_nameorsex">
<if test="userCustom!=null and userCustom!=''">
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
<if test="userCustom.sex!=null and userCustom.sex!=''" >
and sex = #{userCustom.sex}
</if>
<if test="lds!=null and lds!=''">
<foreach collection="lds" item="user_id" open="and (" close=")" separator="or">
id = #{user_id}
</foreach>
</if>
</if>
</sql>
<select id="findUserList" parameterType="userVo" resultType="userCustom"> select * from user <where> <include refid="query_user_nameorsex"></include> </where>