MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
一、首先建立项目的整体效果图:
以下是MyBatis单表的增删改:
二、项目代码:
1)实体类:News中:
public class News { private Integer id; private String title; private String content; private Date pubDate; private Integer typeId; private String photo; private String tname; //get,set方式省去
2)dao层借口层的INewsDAO:
import java.util.List; import java.util.Map; import org.liky.vo.News; public interface INewsDAO { public void doCreate(News news) throws Exception; public void doUpdate(News news) throws Exception; public void doRemove(int id) throws Exception; public List<News> findAll() throws Exception; public News findById(int id) throws Exception; public List<News> findAllSplit(Map<String, Object> map) throws Exception; public int getAllCount(Map<String, Object> map) throws Exception; }
3)dao层的实现,INewDAO.xml,正常不是myBatis,这里是写dao层的实现类的:myBatis的优势也是在这里,将sql语句抽调出来单独写入到一个xml中,便于管理数据库。它是更接近于jdbc的,所以处理的速度很快,它是外网项目中需要用到框架。
<mapper namespace="org.liky.dao.INewsDAO"> <resultMap type="News" id="NewsResult"> <id column="id" property="id" /> <result column="title" property="title" /> <result column="content" property="content" /> <result column="pub_date" property="pubDate" /> <result column="type_id" property="typeId" /> <result column="photo" property="photo" /> </resultMap> <insert id="doCreate" parameterType="News"> INSERT INTO news (id,title,content,pub_date,type_id,photo) VALUES (news_seq.nextVal,#{title},#{content},#{pubDate},#{typeId},#{photo}) </insert> <update id="doUpdate" parameterType="News"> UPDATE news SET title = #{title},content=#{content},pub_date = #{pubDate},type_id = #{typeId},photo=#{photo} WHERE id = #{id} </update> <delete id="doRemove" parameterType="java.lang.Integer"> DELETE FROM news WHERE id = #{id} </delete> <select id="findAll" resultMap="NewsResult"> SELECT * FROM news </select> <select id="findById" resultType="News" parameterType="java.lang.Integer"> SELECT id,title,content,pub_date AS pubDate,type_id AS typeId,photo,tname FROM news n,news_type nt WHERE id = #{id} AND n.type_id = nt.tid </select> <select id="findAllSplit" resultType="News" parameterType="java.util.Map"> SELECT temp.* FROM (SELECT id,title,content,pub_date AS pubDate,type_id AS typeId,photo,ROWNUM rn FROM news WHERE ${column} LIKE #{keyword} AND ROWNUM <= #{endNumber}) temp WHERE temp.rn > #{startNumber} </select> <select id="getAllCount" resultType="int" parameterType="java.util.Map"> SELECT COUNT(*) FROM news WHERE ${column} LIKE #{keyword} </select> </mapper>
4)这一步可以写mybatis的总配置文件,初始加载连接数据库。
<configuration> <typeAliases> <package name="org.liky.vo" /> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL" /> <property name="username" value="sunxun" /> <property name="password" value="123" /> </dataSource> </environment> </environments> <mappers> <mapper resource="org/liky/dao/INewsDAO.xml" /> </mappers> </configuration>
5)建立MyBATISSqlSessionFactory类:
import java.io.InputStream; 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 MyBATISSqlSessionFactory { // 配置文件的所在位置和名称 private static String CONFIG_FILE_LOCATION = "mybatis-config.xml"; // 用来实现连接池的,该类类似Map集合。 private static final ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>(); // Hibernate用来读取配置文件的类 private static InputStream is; // 用来建立连接的,该类就是连接池,使用单例设计模式 private static SqlSessionFactory sqlsessionFactory; // 备用的配置文件位置 private static String configFile = CONFIG_FILE_LOCATION; // 静态块,类加载时最先执行 static { try { // 加载配置文件到内存中 is = Resources.getResourceAsStream(configFile); // 建立连接池以及里面的连接 sqlsessionFactory = new SqlSessionFactoryBuilder().build(is); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } private MyBATISSqlSessionFactory() { } /** * 取得数据库连接对象 * * @return Session * @throws HibernateException */ public static SqlSession getSession() { // 先从ThreadLocal中取得连接。 SqlSession session = (SqlSession) threadLocal.get(); // 如果手头没有连接,则取得一个新的连接 if (session == null) { session = sqlsessionFactory.openSession(); // 把取得出的连接记录到ThreadLocal中,以便下次使用。 threadLocal.set(session); } return session; } /** * 连接关闭的方法 * * @throws HibernateException */ public static void closeSession() { SqlSession session = (SqlSession) threadLocal.get(); // 将ThreadLocal清空,表示当前线程已经没有连接。 threadLocal.set(null); // 连接放回到连接池 if (session != null) { session.close(); } } }
6)写service层实现的借口:
import java.util.List; import java.util.Map; import org.liky.vo.News; public interface INewsService { public void insert(News news) throws Exception; public News findById(int id) throws Exception; public List<News> findAll() throws Exception; public Map<String, Object> list(int pageNo, int pageSize, String column, String keyword) throws Exception; }
7)解耦合,写service的工厂:
import org.liky.service.INewsService; import org.liky.service.impl.NewsServiceImpl; public class ServiceFactory { public static INewsService getINewsServiceInstance() { return new NewsServiceImpl(); } }
8)service的实现类:
import java.util.HashMap; import java.util.List; import java.util.Map; import org.liky.dao.INewsDAO; import org.liky.dbc.MyBATISSqlSessionFactory; import org.liky.service.INewsService; import org.liky.vo.News; public class NewsServiceImpl implements INewsService { public List<News> findAll() throws Exception { List<News> all = null; try { all = MyBATISSqlSessionFactory.getSession().getMapper( INewsDAO.class).findAll(); } catch (Exception e) { e.printStackTrace(); throw e; } finally { MyBATISSqlSessionFactory.closeSession(); } return all; } public News findById(int id) throws Exception { News news = null; try { news = MyBATISSqlSessionFactory.getSession().getMapper( INewsDAO.class).findById(id); } catch (Exception e) { e.printStackTrace(); throw e; } finally { MyBATISSqlSessionFactory.closeSession(); } return news; } public void insert(News news) throws Exception { try { MyBATISSqlSessionFactory.getSession().getMapper(INewsDAO.class) .doCreate(news); MyBATISSqlSessionFactory.getSession().commit(); } catch (Exception e) { e.printStackTrace(); MyBATISSqlSessionFactory.getSession().rollback(); throw e; } finally { MyBATISSqlSessionFactory.closeSession(); } } public Map<String, Object> list(int pageNo, int pageSize, String column, String keyword) throws Exception { Map<String, Object> map = new HashMap<String, Object>(); // 设置要向DAO中传递的参数 Map<String, Object> params = new HashMap<String, Object>(); params.put("column", column); params.put("keyword", "%" + keyword + "%"); params.put("endNumber", pageNo * pageSize); params.put("startNumber", (pageNo - 1) * pageSize); try { map.put("allNews", MyBATISSqlSessionFactory.getSession().getMapper( INewsDAO.class).findAllSplit(params)); map.put("count", MyBATISSqlSessionFactory.getSession().getMapper( INewsDAO.class).getAllCount(params)); } catch (Exception e) { e.printStackTrace(); } finally { MyBATISSqlSessionFactory.closeSession(); } return map; } }
9)测试类NewsServiceImplTest:
import java.util.Date; import java.util.UUID; import org.junit.Test; import org.liky.factory.ServiceFactory; import org.liky.vo.News; public class NewsServiceImplTest { @Test public void testFindAll() throws Exception { System.out.println(ServiceFactory.getINewsServiceInstance().findAll()); } @Test public void testFindById() throws Exception { System.out.println(ServiceFactory.getINewsServiceInstance() .findById(61).getTname()); } @Test public void testInsert() throws Exception { News news = new News(); news.setTitle("MyBATIS测试"); news.setContent("MyBATIS添加测试"); news.setTypeId(3); news.setPubDate(new Date()); news.setPhoto(UUID.randomUUID().toString() + ".jpg"); ServiceFactory.getINewsServiceInstance().insert(news); } @Test public void testListSplit() throws Exception { System.out.println(ServiceFactory.getINewsServiceInstance().list(1, 5, "title", "")); } }