1.回顾jdbc开发 orm概述
orm是一种解决持久层对象关系映射的规则,而不是一种具体技术。jdbc/dbutils/springdao,hibernate/springorm,mybaits同属于ORM解决方案之一。
2.mybaits
mybatis基于jdbc,兼顾难易度和速度。
3.mybatis快速入门
导入lib包
在src目录下配置mybatis.cfg.xml
<?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"> <configuration> <!--加载类路径下的属性文件--> <properties resource="db.properties"> </properties> <!--设置类型别名--> <typeAliases> <typeAlias type="app04.Student" alias="student"/> </typeAliases> <!--设置默认连接环境信息--> <environments default="oracle_developer"> <!--连接环境信息,取一个唯一的名字--> <environment id="mysql_developer"> <!--事务管理方式--> <transactionManager type="jdbc"></transactionManager> <!--使用连接池获取--> <dataSource type="pooled"> <!--配置与数据库交互的4个必要属性--> <property name="driver" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </dataSource> </environment> <environment id="oracle_developer"> <!--事务管理方式--> <transactionManager type="jdbc"></transactionManager> <!--使用连接池获取--> <dataSource type="pooled"> <!--配置与数据库交互的4个必要属性--> <property name="driver" value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/> <property name="username" value="scott"/> <property name="password" value="tiger"/> </dataSource> </environment> </environments> <!--加载映射文件--> <mappers> <mapper resource="app04/StudentMapper.xml"/> <mapper resource="app09/StudentMapper.xml"/> <mapper resource="app10/StudentMapper.xml"/> <mapper resource="app11/StudentMapper.xml"/> </mappers> </configuration>
实体类
配置映射文件StudentMapper.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"> <mapper namespace="studentNamespace"> <!--映射实体与表--> <!--type表示实体的全路径名 id为实体与表的映射取一个唯一的编号--> <resultMap id="studentMap" type="app04.Student"> <!--id标签映射主键属性,result标签映射非主键属性 property表示实体的属性名 column表示表的字段名--> <id property="id" column="id"/> <result property="name" column="name"/> <result property="sal" column="sal"/> </resultMap> <!--insert属性:要书写insert语句 id表示为insert语句取一个唯一编号 parameterType表示要执行的dao中的方法的参数,如果是类的话,必须使用全路径名--> <insert id="add1"> INSERT INTO students(id,name,sal) values(1,"haha",7000) </insert> <insert id="add2" parameterType="student"> INSERT INTO students(id,name,sal) values(#{id},#{name},#{sal}) </insert> </mapper>
获取连接
public class MybatisUtil { private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>(); private static SqlSessionFactory sqlSessionFactory; //加载位于mybatis.xml配置文件 static{ try { Reader reader = Resources.getResourceAsReader("mybatis.cfg.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (IOException e) { throw new RuntimeException(e); } } public static SqlSession getSqlSession(){ SqlSession sqlSession = threadLocal.get(); if(sqlSession == null){ sqlSession = sqlSessionFactory.openSession(); //将session与当前线程绑定在一起 threadLocal.set(sqlSession); } return sqlSession; } //关闭当前sqlsession,与当前线程分离 public static void closeSqlSession(){ SqlSession sqlSession = threadLocal.get(); if(sqlSession!=null){ sqlSession.close(); //分离,目的是为了尽早垃圾回收 threadLocal.remove(); } } }
dao
public void add1() throws Exception{ SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); //默认事务开始,读取StudentMapper.xml映射文件中的sql语句 int i = sqlSession.insert("studentNamespace.add1"); sqlSession.commit(); System.out.println("本次操作影响了"+i+"行"); }catch (Exception e){ sqlSession.rollback(); throw e; }finally { MybatisUtil.closeSqlSession(); } } public void add2(Student student) throws Exception{ SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); //默认事务开始,读取StudentMapper.xml映射文件中的sql语句 sqlSession.insert("studentNamespace.add2",student); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw e; }finally { MybatisUtil.closeSqlSession(); } }
4.mybatis工作流程
1)通过Reader对象读取src目录下的mybatis.cfg.xml配置文件(该文本的位置和名字可任意)
2)通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象
3)从当前线程中获取SqlSession对象
4)事务开始,在mybatis中默认
5)通过SqlSession对象读取StudentMapper.xml映射文件中的操作编号,从而读取sql语句
6)事务提交,必写
7)关闭SqlSession对象,并且分开当前线程与SqlSession对象,让GC尽早回收
5基于MybatisUtil工具类,完成CURD操作
映射配置文件
<?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="app09.Student"> <resultMap id="studentMap" type="app09.Student"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="sal" column="sal"/> </resultMap> <insert id="add" parameterType="app09.Student"> INSERT INTO students(id,name, sal) VALUES(#{id},#{name},#{sal}) </insert> <!--如果参数不是实体,只是普通变量,#中的参数名可以随便写--> <select id="findById" parameterType="int" resultType="app09.Student"> SELECT ID,NAME,SAL FROM students WHERE id = #{xxx} </select> <select id="findAll" resultType="app09.Student"> SELECT ID,NAME,SAL FROM students </select> <update id="update" parameterType="app09.Student"> UPDATE students SET name=#{name},sal=#{sal} WHERE id=#{id} </update> <delete id="delete" parameterType="app09.Student"> DELETE FROM students WHERE ID=#{id} </delete> </mapper>
dao
public void add(Student student) throws Exception{ SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); sqlSession.insert(Student.class.getName()+".add",student); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw e; }finally { MybatisUtil.closeSqlSession(); } } private Student findById(int id) { Student student= null; SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); student = sqlSession.selectOne(Student.class.getName() + ".findById", id); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw e; }finally { MybatisUtil.closeSqlSession(); } return student; } private List<Student> findAll() { List<Student> students = new ArrayList<>(); SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); students = sqlSession.selectList(Student.class.getName() + ".findAll"); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw e; }finally { MybatisUtil.closeSqlSession(); } return students; } private void update(Student student) { SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); sqlSession.update(Student.class.getName()+".update",student); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw e; }finally { MybatisUtil.closeSqlSession(); } } private void delete(Student student) { SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); sqlSession.delete(Student.class.getName()+".delete",student); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw e; }finally { MybatisUtil.closeSqlSession(); } }
6.分页查询(mysql,oracle)
映射配置文件
mysql
<select id="findAllWithFy" parameterType="map" resultMap="studentMap"> SELECT id,name,sal FROM students LIMIT #{start},#{size} </select>
oracle
<select id="findAllWithFyByOracle" parameterType="map" resultMap="studentMap"> SELECT ID,NAME,SAL FROM (SELECT ROWNUM IDS,ID,NAME,SAL FROM STUDENTS WHERE ROWNUM < #{end}) WHERE IDS > #{start} </select>
dao
public List<Student> findAllWithFy(int start,int size){ List<Student> students = new ArrayList<>(); SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); Map<String, Object> map = new LinkedHashMap<>(); map.put("start",start); map.put("size",size); students = sqlSession.selectList(Student.class.getName()+".findAllWithFy",map); sqlSession.commit(); return students; }catch (Exception e){ sqlSession.rollback(); throw e; }finally { MybatisUtil.closeSqlSession(); } }
7.动态SQL操作之查询
映射配置文件
<select id="findAll" parameterType="map" resultMap="studentMap"> SELECT ID,NAME,SAL FROM STUDENTS <where> <if test="pid!=null"> and ID = #{pid} </if> <if test="pname!=null"> and NAME = #{pname} </if> <if test="psal != null"> AND SAL < #{psal} </if> </where> </select>
dao
public List<Student> findAll(Integer id ,String name,Double sal){ List<Student> students = new ArrayList<>(); SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); Map<String, Object> map = new LinkedHashMap<>(); map.put("pid",id); map.put("pname",name); map.put("psal",sal); students = sqlSession.selectList(Student.class.getName()+".findAll",map); sqlSession.commit(); return students; }catch (Exception e){ sqlSession.rollback(); throw new RuntimeException(e); }finally { MybatisUtil.closeSqlSession(); } }
8.动态SQL操作之更新
映射配置文件
<update id="update" parameterType="map"> UPDATE STUDENTS <set> <if test="pname!=null"> name = #{pname}, </if> <if test="psal != null"> sal = #{psal}, </if> </set> WHERE id = #{pid} </update>
dao
public void update(Student student){ SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); Map<String, Object> map = new LinkedHashMap<>(); map.put("pid",student.getId()); map.put("pname",student.getName()); map.put("psal",student.getSal()); sqlSession.update(Student.class.getName()+".update",map); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw new RuntimeException(e); }finally { MybatisUtil.closeSqlSession(); } }
9.动态SQL操作之删除
映射配置文件
<delete id="deleteAll" > DELETE FROM students WHERE ID IN <foreach collection="array" open="(" close=")" separator="," item="ids"> #{ids} </foreach> </delete>
dao
public void deleteAll(int... ids)throws Exception{ SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); sqlSession.delete(Student.class.getName()+".deleteAll",ids); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw new RuntimeException(e); }finally { MybatisUtil.closeSqlSession(); } }
10.动态SQL操作之插入
映射配置文件
<!--sql片段--> <sql id="key"> <trim suffixOverrides=","> <if test="id != null"> id, </if> <if test="name != null"> name, </if> <if test="sal != null"> sal, </if> </trim> </sql> <sql id="value"> <trim suffixOverrides=","> <if test="id != null"> #{id}, </if> <if test="name != null"> #{name}, </if> <if test="sal != null"> #{sal}, </if> </trim> </sql> <insert id="insert" parameterType="app11.Student"> INSERT INTO students(<include refid="key"/>) values (<include refid="value"/>) </insert>
dao
public void deleteList(List<Integer> ids)throws Exception{ SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); sqlSession.delete(Student.class.getName()+".deleteList",ids); sqlSession.commit(); }catch (Exception e){ sqlSession.rollback(); throw new RuntimeException(e); }finally { MybatisUtil.closeSqlSession(); } }