方案一:使用絕對定位SQL的方式
手動編寫DAO接口和實現(xiàn)類
namespace+id定位動態(tài)SQL
第一步:創(chuàng)建項目斟冕,導入依賴 mysql,mybatis,log4j,Spring
<meta charset="utf-8">
dbcp連接池依賴:
Mybatis的插件望忆,資源拷貝,指定編譯版本暖眼。
第二步:插件生成表對應的實體類和mapper映射文件
注意:mybatis的核心配置文件卫枝,可以整合到?jīng)]有
注意:
不生成DAO接口(非Mapper代理方式)
不生成Example
需要手動編寫DAO接口和實現(xiàn)類。
generatorConfig.xml 代碼如下 :
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration >
<classPathEntry location="D:\Program Files\repository\mysql\mysql-connector-java\5.1.34\mysql-connector-java-5.1.34.jar" ></classPathEntry>
<context id="context1" >
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/testmybatis01?characterEncoding=utf-8" userId="root" password="zyh" />
<javaModelGenerator targetPackage="com.zyh.pojo" targetProject="src/main/java" />
<sqlMapGenerator targetPackage="com.zyh.mapper" targetProject="src/main/java" />
<table tableName="t_user_info" domainObjectName="UserInfo"
enableCountByExample="false"
enableUpdateByExample="false"
enableSelectByExample="false"
enableDeleteByExample="false">
</table>
</context>
</generatorConfiguration>
生成:只能點擊一次。 使用mybatis 自動生成插件
注意:需要注意的地方如上配置文件所示: 取到了自動生成 dao 以及 不自動生成模板 example 矗烛。
第三步:開發(fā)DAO接口和實現(xiàn)類
需要繼承整合類:extends org.mybatis.spring.support.SqlSessionDaoSupport
它可以幫助我們直接得到SqlSession
得到 SqlSession的方式,調(diào)用父類的方法getSqlSession()
this.getSqlSession()【需要注入: sqlSessionFactory】
不需要手動關閉,容器管理
注意:事務不要用SqlSession直接提交瞭吃。
Dao 如下所示 :
public interface UserInfoDao {
void addUserInfo(UserInfo userInfo);
void deleteUserinfo(Long aLong);
void updateUserInfo(UserInfo userInfo);
UserInfo queryUserInfoById(Long aLong);
List<UserInfo> queryUserInfoAll();
}
DaoImpl如下所示:
public class UserInfoDaoImpl extends SqlSessionDaoSupport implements UserInfoDao {
@Override
public void addUserInfo(UserInfo userInfo) {
getSqlSession().insert("com.zyh.mapper.UserInfoMapper.insert",userInfo);
}
@Override
public void deleteUserinfo(Long aLong) {
getSqlSession().delete("com.zyh.mapper.UserInfoMapper.deleteByPrimaryKey",aLong);
}
@Override
public void updateUserInfo(UserInfo userInfo) {
getSqlSession().update("com.zyh.mapper.UserInfoMapper.updateByPrimaryKeySelective",userInfo);
}
@Override
public UserInfo queryUserInfoById(Long aLong) {
return getSqlSession().selectOne("com.zyh.mapper.UserInfoMapper.selectByPrimaryKey",aLong);
}
@Override
public List<UserInfo> queryUserInfoAll() {
return getSqlSession().selectList("com.zyh.mapper.UserInfoMapper.selectUserInfoAll");
}
}
通過源碼分析:可以只需要注入 SqlSessionFactory ,就可以得到SqlSession
第四步:配置整合持久層
使用Spring的核心配置文件替換Mybatis的核心配置文件碌嘀。
同時由Spring來提供SqlSessionFactory
部分配置文件如下所示:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.gjt.mm.mysql.Driver"></property>
<property name="url" value="jdbc:mysql:///testmybatis01?characterEncoding=utf-8"></property>
<property name="username" value="root"></property>
<property name="password" value="zyh"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:com/zyh/mapper/*Mapper.xml"></property>
</bean>
<bean id="userInfoDao" class="com.zyh.dao.UserInfoDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
配置整合:
1)連接池
org.gjt.mm.mysql.Driver
jdbc:mysql:///testmybatis01?characterEncoding=utf-8
-
創(chuàng)建SqlSessionFactory(由Spring提供)
工廠org.mybatis.spring.SqlSessionFactoryBean
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:com/zyh/mapper/*Mapper.xml"></property>
</bean>
含有注冊實體
源碼確認:這個工廠 Bean返回的對象是:SqlSessionFactory
-
把工廠注入給DAO(讓DAO具備得到SqlSession的能力)
<bean id="userInfoDao" class="com.zyh.dao.UserInfoDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
image.png
第五步 : 測試 :
增刪改查如下所示: 都是成功的 輸出結(jié)果就不給大家截圖了。
public class testUserInfoDao {
@Test
public void testUserInfoDaoAdd(){
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDao userInfoDao = (UserInfoDao) classPathXmlApplicationContext.getBean("userInfoDao");
UserInfo userInfo=new UserInfo();
userInfo.setuName("張穎豪8/16");
userInfo.setuPass("魏雪8/16");
userInfoDao.addUserInfo(userInfo);
}
@Test
public void testUserInfoDaoUpdate(){
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDao userInfoDao = (UserInfoDao) classPathXmlApplicationContext.getBean("userInfoDao");
UserInfo userInfo=new UserInfo();
userInfo.setuId(138l);
userInfo.setuName("張穎豪xxx8/16");
userInfo.setuPass("魏雪xxx8/16");
userInfoDao.updateUserInfo(userInfo);
}
@Test
public void testFindUserInfoDao(){
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDao userInfoDao = (UserInfoDao) classPathXmlApplicationContext.getBean("userInfoDao");
UserInfo userInfo = userInfoDao.queryUserInfoById(138l);
Log.info(userInfo);
}
@Test
public void testUserInfoDaoDelete(){
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDao userInfoDao = (UserInfoDao) classPathXmlApplicationContext.getBean("userInfoDao");
userInfoDao.deleteUserinfo(138l);
}
@Test
public void testQueryAll(){
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDao userInfoDao = (UserInfoDao) classPathXmlApplicationContext.getBean("userInfoDao");
List<UserInfo> userInfos = userInfoDao.queryUserInfoAll();
Log.info(userInfos);
}
}
AOP事務(由Spring提供)
不用自己編寫事務通知類
一般是在服務層加AOP事務歪架。不是在持久層加股冗。
優(yōu)化:
添加服務層,在服務層加AOP事務和蚪。
事務傳遞到持久層
使用Spring事務通知類整合
聲明式事務
事務管理
傳統(tǒng)方式:手動編碼在業(yè)務邏輯層控制事務
采取AOP的方式實現(xiàn)聲明式事務
頂級接口:(事務通知類)
org.springframework.transaction.PlatformTransactionManager
Mybatis操作數(shù)據(jù)庫事務止状,使用Spring 的JDBC事務控制類。
實現(xiàn)類:
org.springframework.jdbc.datasource.DataSourceTransactionManager
第六步:開發(fā)服務層接口和實現(xiàn)類
public interface UserService {
void addUserInfo(UserInfo userInfo);
void deleteUserinfo(Long aLong);
void updateUserInfo(UserInfo userInfo);
UserInfo queryUserInfoById(Long aLong);
List<UserInfo> queryUserInfoAll();
void updateAll(UserInfo addUserInfo,UserInfo updateInfo);
}
實現(xiàn)類如下所示:
public class UserServiceImpl implements UserService {
private UserInfoDaoImpl userInfoDao;
public void setUserInfoDao(UserInfoDaoImpl userInfoDao) {
this.userInfoDao = userInfoDao;
}
@Override
public void addUserInfo(UserInfo userInfo) {
userInfoDao.addUserInfo(userInfo);
}
@Override
public void deleteUserinfo(Long aLong) {
userInfoDao.deleteUserinfo(aLong);
}
@Override
public void updateUserInfo(UserInfo userInfo) {
userInfoDao.updateUserInfo(userInfo);
}
@Override
public UserInfo queryUserInfoById(Long aLong) {
return userInfoDao.queryUserInfoById(aLong);
}
@Override
public List<UserInfo> queryUserInfoAll() {
return userInfoDao.queryUserInfoAll();
}
@Override
public void updateAll(UserInfo addUserInfo,UserInfo updateInfo){
userInfoDao.addUserInfo(addUserInfo);
userInfoDao.updateUserInfo(updateInfo);
}
}
第七步:配置整合AOP事務
思路:事務管理器->事務通知切面->通知者
事務頂級接口:
總的配置文件如下所示:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.gjt.mm.mysql.Driver"></property>
<property name="url" value="jdbc:mysql:///testmybatis01?characterEncoding=utf-8"></property>
<property name="username" value="root"></property>
<property name="password" value="zyh"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:com/zyh/mapper/*Mapper.xml"></property>
</bean>
<bean id="userInfoDao" class="com.zyh.dao.UserInfoDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<!-- 4,創(chuàng)建服務層對象攒霹,注入DAO 目標類對象-->
<bean id="userInfoService" class="com.zyh.service.UserServiceImpl">
<property name="userInfoDao" ref="userInfoDao"></property>
</bean>
<!-- 5,創(chuàng)建事務管理通知類對象-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入數(shù)據(jù)源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 6,定義事務通知切面怯疤,讓事務應用到具體的方法 -->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="query*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 7,AOP編程:讓切入點和通知關聯(lián)形成切面 -->
<aop:config>
<aop:pointcut id="myPoint" expression="execution(* com.zyh.service.*.*(..))"></aop:pointcut>
<aop:advisor advice-ref="myAdvice" pointcut-ref="myPoint"></aop:advisor>
</aop:config>
aop全自動編程:tx:method指向服務層的方法。
Mybatis有的版本底層可以自動提交事務催束,從服務層的角度集峦,必須加上AOP事務配置】俅蹋【我們這個版本沒有這個問題】
第八步:測試
測試方法如下所示:
public class testUserInfoTransaction {
@Test
public void testtransaction(){
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userInfoService = (UserService) classPathXmlApplicationContext.getBean("userInfoService");
UserInfo addUserInfo=new UserInfo();
addUserInfo.setuName("我是新添加的用戶名");
addUserInfo.setuPass("我是新添加的密碼");
UserInfo updateUserInfo=new UserInfo();
updateUserInfo.setuId(12l);
updateUserInfo.setuName("事物增加");
updateUserInfo.setuPass("事物增加");
userInfoService.updateAll(addUserInfo,updateUserInfo);
}
}
在實現(xiàn)類中的方法如下所示: 可以看到 第一條和第二條語句中間有個異常產(chǎn)生
當我們沒有做事物處理的前后 得出的結(jié)果是完全不一致的塔淤。
@Override
public void updateAll(UserInfo addUserInfo,UserInfo updateInfo){
userInfoDao.addUserInfo(addUserInfo);
int i=1/0;
userInfoDao.updateUserInfo(updateInfo);
}