MyBatis 是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 能夠使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。java
|mybatis| hibernate | |--|--| | 半自動ORM框架 | 全自動ORM框架 | |必須寫sql |能夠不寫sql | | 事務處理 | 事務處理 | |緩存都支持 | 緩存都支持,二級緩存比mybatis更好 |mysql
<dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.27</version> </dependency> </dependencies>
該配置文件包含了對MyBatis系統的核心設置,包含獲取數據庫鏈接實例的數據源,和決定事務做用域和控制方式的事務功能。XML配置文件的詳細內容後面在討論,這裏先給出一個簡單案例sql
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/pms?characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> </configuration>
<?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="dpb"> <insert id="addUser" parameterType="com.sxt.dao.User"> insert into t_user(name,age)values(#{name},#{age}) </insert> <delete id="deleteUserById" parameterType="java.lang.Integer"> delete from t_user where id=#{id} </delete> <update id="updateUserById" parameterType="com.sxt.dao.User"> update t_user set name = #{name} where id=#{id} </update> <select id="getUserById" parameterType="java.lang.Integer" resultType="com.sxt.dao.User"> select * from t_user where id=#{id} </select> </mapper>
@Test public void add() throws IOException { // 1.經過Resources對象加載配置文件 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); // 2.獲取SqlSessionFactory對象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream ); // 3.經過SqlSessionFactory對象獲取SQLSession對象 SqlSession session = factory.openSession(); User user = new User(); user.setName("dpb"); user.setAge(22); // dpb.addUser 是映射文件中 namespace的內容加 id的內容,定位要執行的SQL int count = session.insert("dpb.addUser", user); System.out.println("影響的行數:"+count); // 須要顯示的提交 session.commit(); session.close(); } }
public class Test02 { private SqlSession sqlSession; @Before public void before() throws IOException { // 1. 加載配置文件 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); // 2. 根據配置文件獲取一個SqlSessionFactory對象,這個對象至關於鏈接工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); // 3. 獲取一個sqlsession,sqlsession相似於以前學過的Connection sqlSession = sqlSessionFactory.openSession(); } @After public void after() { sqlSession.commit(); sqlSession.close(); } @Test public void test1() { User user = new User(); user.setId(7); user.setName("里斯1"); int update = sqlSession.update("dpb.updateUserById", user); System.out.println(update); } @Test public void test2() { int delete = sqlSession.delete("dpb.deleteUserById", 7); System.out.println(delete); } @Test public void test3() { User user = (User) sqlSession.selectOne("dpb.getUserById", 8); System.out.println(user); } }
SqlSessionFactory在一個服務中只須要有一個實例就能夠了,此時能夠經過單例的模式獲取數據庫
/** * 工具類 對外提供SqlSessionFactory的單例對象 * @author dengp * */ public class DbUtils { private static SqlSessionFactory factory ; public static SqlSessionFactory getInstace(){ if(factory ==null){ InputStream in = null; try{ in = Resources.getResourceAsStream("mybatis-config.xml"); }catch(Exception e){ e.printStackTrace(); } synchronized (DbUtils.class) { if(factory ==null){ factory = new SqlSessionFactoryBuilder().build(in); } } } return factory; } }
public interface UserMapper { public int addUser(User user); public int updateById(User user); public int deleteById(int id); public User queryById(int id); }
public class UserDao implements UserMapper { @Override public int addUser(User user) { return DBUtils.getInstall().openSession().insert("com.sxt.dao.UserMapper.addUser", user); } @Override public int updateById(User user) { // TODO Auto-generated method stub return DBUtils.getInstall().openSession().update("com.sxt.dao.UserMapper.updateById", user); } @Override public int deleteById(int id) { // TODO Auto-generated method stub return DBUtils.getInstall().openSession().delete("com.sxt.dao.UserMapper.deleteById", id); } @Override public User queryById(int id) { // TODO Auto-generated method stub return DBUtils.getInstall().openSession().selectOne("com.sxt.dao.UserMapper.queryById", id); } }
<?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="com.sxt.dao.UserMapper"> <insert id="addUser" parameterType="com.sxt.bean.User"> insert into t_user(name,age)values(#{name},#{age}) </insert> <delete id="deleteById" parameterType="java.lang.Integer"> delete from t_user where id=#{id} </delete> <update id="updateById" parameterType="com.sxt.bean.User"> update t_user set name=#{name},age=#{age} where id=#{id} </update> <select id="queryById" parameterType="java.lang.Integer" resultType="com.sxt.bean.User"> select * from t_user where id=#{id} </select> </mapper>
/** * 代理方式 */ @Test public void test(){ UserMapper mapper = (UserMapper) Proxy.newProxyInstance(UserMapper.class.getClassLoader() , new Class[]{UserMapper.class},new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(UserMapper.class.getName()+"."+method.getName()); Object id = null; for (Object object : args) { System.out.println(object); id = object; } // 實現邏輯 return DBUtils.getInstall().openSession().selectOne(UserMapper.class.getName()+"."+method.getName(), id); } } ); System.out.println(mapper.queryById(5)); }
經過前面UserDao的設計,能夠發現,UserDao中的代碼都是模板化代碼,均可以經過配置自動生成,所以,在實際開發中,Mapper能夠按照以下方式設計緩存
Mapper接口中,只須要聲明方法名,方法參數、方法返回等信息session
public interface UserMapper { public int addUser(User user); }
<?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"> <!-- 使用接口 代理的方式 namespace必須和接口的全路徑名稱一致 --> <mapper namespace="com.sxt.dao.UserMapper"> <!-- id必須和接口聲明的方法一致 --> <insert id="addUser" parameterType="com.sxt.bean.User"> insert into t_user(name,age)values(#{name},#{age}) </insert> </mapper>
@Test public void add() throws IOException { // 1.經過Resources對象加載配置文件 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); // 2.獲取SqlSessionFactory對象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream ); // 3.經過SqlSessionFactory對象獲取SQLSession對象 SqlSession session = factory.openSession(); User user = new User(); user.setName("dpb"); user.setAge(22); //經過Java動態代理自動提供了UserMapper的實現類 UserMapper mapper = session.getMapper(UserMapper.class); int count = mapper.addUser(user); System.out.println("影響的行數:"+count); session.commit(); }
注意: 使用mapper接口方式必須知足: |序號 | 注意點 | |--|--| | 1 | 映射文件的namespace的值必須是接口的全路徑名稱 好比:com.dpb.dao.UserMapper | | 2 | 接口中的方法名在映射文件中必須有一個id值與之對應。 | | 3 | 映射文件的名稱必須和接口的名稱一致 |mybatis