1.实现类的简化
昨天学习的实现类中,有大部分代码是不用修改的,且重复的比较多,所以对其进行简化,首先在实现文件包(cn.jbit.mybatisdemo.dao.impl)下创建一个文件,该文件之间拷过去就可以了。
MyBatisUtil.java
package cn.jbit.mybatisdemo.dao.impl;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
private MyBatisUtil(){
}
private static final String RESOURCE = "mybatis-config.xml";
private static SqlSessionFactory sqlSessionFactory = null;
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
static {
Reader reader = null;
try {
reader = Resources.getResourceAsReader(RESOURCE);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
sqlSessionFactory = builder.build(reader);
} catch (Exception e1) {
e1.printStackTrace();
throw new ExceptionInInitializerError("加载MyBatis失败,请检测配置文件或数据库");
}
}
public static SqlSessionFactory getSqlSessionFactory(){
return sqlSessionFactory;
}
public static SqlSession getSession(){
SqlSession session = threadLocal.get();
if (session == null){
session = (sqlSessionFactory !=null) ?sqlSessionFactory.openSession():null;
threadLocal.set(session); // 5
}
return session;
}
public static void closeSession(){
SqlSession session = (SqlSession) threadLocal.get(); // 2
threadLocal.set(null);
if (session !=null){
session.close();
}
}
}
在实现类StuDaoImpl.java中,只需要调用上述代码中的方法即可,简化前后的对比,黄色区域简化成粉色区域部分,代码清爽很多
简化前
@Override
public List<Stu> selectAll() {
String resource = "mybatis-config.xml";
Reader reader = null;
SqlSessionFactory factory = null;
SqlSession session = null;
List<Stu> list = new ArrayList<Stu>();//创建范式list,这是返回的数据
try {
reader = Resources.getResourceAsReader(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(reader);
session = factory.openSession();
//这句话是重点
list = session.selectList("cn.jbit.mybatisdemo.dao.IStuDao.selectAll");//选到接口文件下的接口selectAll
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}finally {
session.close();
}
return list;//返回范式list
}
简化以后
@Override
public List<Stu> selectAll() {
SqlSession session = MyBatisUtil.getSession();
List<Stu> list = new ArrayList<Stu>();
try {
list = session.selectList("cn.jbit.mybatisdemo.dao.IStuDao.selectAll");
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}finally {
MyBatisUtil.closeSession();
}
return list;
}
2.映射文件的简化
映射文件中的resultType是cn.jbit.mybatisdemo.entity.Stu,写多个查询语句的话都要写着个路径比较麻烦,可以在配置文件mybatis-config中对路径进行配置一下,简化后可以不用写那么长的路径
在mybatis-config添加配置语句
<mappers>
<mapper resource="cn/jbit/mybatisdemo/dao/StuDaoMapper.xml"/>
</mappers>
简化前
<?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">
<mapper namespace="cn.jbit.mybatisdemo.dao.IStuDao">
<select id="selectAll" resultType="cn.jbit.mybatisdemo.entity.Stu">
select * from stu
</select>
</mapper>
简化后
<?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">
<mapper namespace="cn.jbit.mybatisdemo.dao.IStuDao">
<select id="selectAll" resultType="Stu">
select * from stu
</select>
</mapper>
3.结果映射
如果实体类中的变量名称和数据库中的名称不一致的话,查询结果会为空,在映射文件StuDaoMapper.xml中增加结果映射,可以解决这个问题
<!--结果映射 -->
<resultMap id="stuResultMap" type="Stu">
<id property="sid" column="sid" />
<result property="sname" column="sname"/>
<result property="sage" column="age"/>
<result property="sgender" column="gender"/>
</resultMap>
在以后的查询语句中,用到的变量名称,就可以在便签里加上resultMap="stuResultMap",只要映射语句中的id一致即可,如:
<!--查询全部 -->
<select id="selectAll" resultType="Stu" resultMap="stuResultMap">
select * from stu
</select>
4.增删改查
1.查找一个,查找一个的时候要指明参数的类型,用#号获取参数变量,注意这里对照的是实体类里的变量
<select id="selectBysid" resultType="Stu"
parameterType="String" resultMap="stuResultMap">
select * from stu where sid=#{sid}
</select>
2.增添数据,增添数据用到的标签是insert,也需要指明参数的类型,因为要传参数进来,
<insert id="insertStu" parameterType="Stu">
insert into stu(sid,sname,gender) values(#{sid},#{sname},#{sgender})
</insert>
第二种增添数据是主键设置成自增模式,插入一条数据之后,还可以获取增加后的主键的值
<insert id="insertStu" parameterType="Stu"
useGeneratedKeys="true" keyProperty="sage">
insert into stu(sid,sname,gender) values(#{sid},#{sname},#{sgender})
</insert>
3.删除数据,删除数据用到的标签是delete,也需要指明参数类型,因为要传递参数进来
<delete id="deleteSid"
parameterType="int">
delete from stu where sid=#{sid}
</delete>
4.更改数据,更改数据用到的标签是update,也需要指明参数类型,因为要传递参数进来
<update id="updateStu" parameterType="Stu">
update stu set sname=#{sname},age=#{sage},gender=#{sgender} where sid=#{sid}
</update>
5.最后一个是动态查询,动态查询要指明返回值类型,因为要把查询结果返回来给我们,还有指明映射
a.如果没有1=1 且第一个判断是正确的语句就变成select * from stu where and....从而导致错误
b.like是模糊查询,注意用法
<select id="findStuByIf" parameterType="Stu" resultType="Stu" resultMap="stuResultMap">
select * from stu where 1=1
<if test = "sgender != null">
and gender = #{sgender}
</if>
<if test = "sname != null">
and sname like '%${sname}%'
</if>
</select>