Spring整合Mybatis-----Aop事务

Spring整合Mybatis-----Aop事务

 

首先对于Spring整合Mybatis有两种方式那就是使用sql绝对定位以及使用Mapper代理来进行开发,本篇博文先来介绍第一种。

 

       所谓的Sql绝对定位就是namespace+id得方式来进行定位;

首先对于Mybatis得介绍后面会有博文详细介绍,简单的说Mybatis得核心配置文件完成得就两个功能,一就是数据源得设置,而就是实体得注册(mapper层映射得注册);

接下来就开始创建项目:

1首先创建Maven项目,导入依赖

需要得包有Mybatis核心包,Spring,Mysql,log4j,dbcp

此外还需要generator.xml,log4j.properties得两个资源文件,前着是用自动生成pojo,mapper,Dao层得一个插件,后者主要是用来产生日志得;

建好了项目以后则通过这个插件来生成相应得类和文件,但是在此处我们不生产Dao及其接口,一步一步来,否则一下生成了我们也就不用干什么了,而且这样分开写便于理解,最主要得原因就是,底层完成得操做是增删改查,但是查是不需要事务的,所以这样我们可以提前对查进行测试;

不生成Dao接口及其实现类,只需要将这里的Dao接口生成的位置删除即可;

2.接下来我们就来创建Dao及其实现类

首先编写Dao接口,里面喜丧基本的增删改查,

注意的地方就是:方法名要和自动生成的Mapper文件的id一致,而其参数也要一致这样才能通过namespace+id来绝对定位到sql语句上,从而操作数据库;

     再就是编写其实现类,但是这里为例方便操作,就不用以前的QuerruRunner了,这里Dao接口的实现类,再来继承一个类就是SqlsessionDaosupport,因为这个类会提供Sqlsession这个对象,但前提是我们要进行注入;

分析:小编通过源码得是SqlsessionDaosupport这个类得内部是:

this.sqlsession=newsqlsessionTemplate(sqlsessionFactory)

所以在注入得时候,我们应该注入得就是工厂,根据注入得工厂来得到sqlsesion对象。

那么sqlsession这个对象有什么用呢?

我们看一个添加用户得底层代码:

@Override
public void insert(User user) {
    this.getSqlSession().insert("com.qf.mapper.UserMapper.insert",user);
}

很显然,代码得简洁性一目了然,对于用户得田间一句话搞定;

那么我们来解释一下这条语句:

1首先因为我们注入了SqlsessionFactory,SqlsessionDaosupport这个类得内部对他进行了赋值,所以我们可以通过getSqlSession()来得到这个对象,在调用增删改查得方法;

2com.qf.mapper.UserMapper.insert这就花就是我们所谓得nameSpace+id通过这条语句我们就可以来定位到,生成得mapper映射文件中得某个具体id方法,从而对数据库进行操作;

 

再接下来对删,改查的方法进行重写即可;

@Override
public void deleteByPrimaryKey(Long id) {
        this.getSqlSession().delete("com.qf.mapper.UserMapper.insert.deleteByPrimaryKey",id);
}

@Override
public void updateByPrimaryKey(User user) {
        this.getSqlSession().update("com.qf.mapper.UserMapper.insert.updateByPrimaryKey",user);
}

@Override
public User selectByPrimaryKey(Long id) {
    User user=this.getSqlSession().selectOne("com.qf.mapper.UserMapper.insert.selectByPrimaryKey",id);
    return user;
}

 

通过以上的操所我们以及完成了Dad层的创建

3 整合持久层

1) 首先我们要做的就是数据源的配置,

这个大家都比较熟悉了,再这里就不过多的赘述,就是url Driver username password 着写数据

2) 我们来创建sqlsession对象

同时为其关联数据源依据前面提到的注入;

因为第层的增删改都是通过sqlsession来实现的所以得到的Sqlsession对象应该关联数据库;

下面就是具体的代码

创建Sqlsession对象

<bean id="SqlSessionFactoryBean"class="org.mybatis.spring.SqlSessionFactoryBean">

关联数据源
   <property name="dataSource"value="datasource"></property>

注册实体相当于mybatis当中的注册映射
    <propertyname="mapperLocations" >
        <array>
           <value>com/qf/mapper/UserMapper.xml</value>
        </array>
    </property>
</bean>

此处工厂用到的就是: SqlSessionFactoryBean

3)接下来我们就应该船舰UserDao对象

<bean name="UserDao"class="com.qf.Dao.UserDaoImpl">

在这里我们就对sqlsession对象进行了注入
    <propertyname="sqlSessionFactory" value="SqlSessionFactoryBean"></property>
</bean>

Value就来自于之前创建的sqlsession对象的id

 

这样我们就完成了初次的整合,之后进行查找的测试即可;编写测试类

 

@Test
public  void testselectByPrimaryKey(){
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    UserDao userDao=(UserDao) context.getBean("UserDao");
    user user=userDao.selectByPrimaryKey(5L);
    System.out.println(user.getUsername()+"--"+user.getPassword());
    context.close();
}
@Test这个声明是junit当中的测试注解,使用这个注解就可以对单个的方法进行测试而步骤使用main函数

以上就是对查找的测试。

4.Aop事务的整合

 首先来编写服务层及其实现类

因为以后的数据都是从View层过来的,所以才这里我们需要额外船舰Dto层,来创建和玉面保持一致的实体类,因为有些数据用户是不会提交的需要我们自己设置,从而方便数据库的管理。

编写好服务层及其实现类之后,我们就对其进行配置以及Aop编程;

1)首先来说一下ServiceImpl实现类的写法

 因为服务层接受的是页面传过来的参数,所以可能会有Dto类型,这是就牵扯到一个数据搬移的问题,我们有两种方法来解决这个问题:

   一个就是创建一个底层参数的对象,用get方法将Dto的值得到

再用set方法将这个值植入刚刚建好的对象中;

   第二个就是使用BeanUtils.copypropertise(a,b)这个方法就是将a种的的数据复制到b中,但是它有一个使用的前提就是二者的类型是一致的;

废话不多说看一段代码就明白了:

@Override
public void updataUser(UserDto dto) {

    User user=new User();
    BeanUtils.copyProperties(dto,user);
    userDao.updateByPrimaryKey(user);

}

2)就是我们应该再配置文件当中注入UserDao这样这儿才能使用userdao来调用底层的方法;

3)接下俩我们就来整合

ii)首先创建目标类对象,也就是服务层对象,代码如下

<bean id="UserService"class="com.qf.service.UserServiceImpl">

再此处对UserServiceImpl该类当中的userDao属性来注入
    <property name="userDao"value="UserDao"></property>
</bean>

III)船舰事务管理对象

因为事务是直接由Spring框架类提供的所以我们只需创建事务管理类的对象代码如下:

<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <propertyname="dataSource" value="dataSource"></property>
</bean>

Class用到的就是DataSourceTransactionManager这个管理类。从而产生对象

再这个对象的内部 关联数据源因为事务也是可以操作数据库的比如说时间等。

Iv)定义事务通知切面,让事务应用到具体的方法,代码如下:

<tx:advice id="advice" transaction-manager="transactionManager">

让具体的方法加事务:add,del,update加事务,find不加
           <tx:attributes>
                <tx:method name="add*"propagation="REQUIRED"/>
                <tx:method name="del*"propagation="REQUIRED"/>
                <tx:method name="updata*"propagation="REQUIRED"/>
                <tx:method name="find*"read-only="true"></tx:method>
            </tx:attributes>
</tx:advice>

Find设置为只读;*好表示以前面的名称开头的方法,当然事务时应用到服务层的方法,所以指的就是服务层目标类的方法;

v)最后就是Aop编程

代码如下:

<aop:config>

创建切入点,用到的就是execution表达式即切入点表达式:
    <aop:pointcut id="mypoint"expression="execution(* com.qf.service.*.*(..))"></aop:pointcut>

形成切面advice-ref关联公共类,pointcut-ref关联切点所以将通知和切入点关联就形成了切面
    <aop:advisor advice-ref="advice"pointcut-ref="mypoint"></aop:advisor>
</aop:config>

vi)最后就是对服务层编写好的方法进程测试,代码如下:

@Test
public  void testInsert(){
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService userService=(UserService) context.getBean("UserService");
    UserDto user1=new UserDto();
    user1.setUsername("傅筱");
    user1.setPassword("123456");
    userService.addUser(user1);

}
@Test
public  void test(){
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService userService=(UserService) context.getBean("UserService");
    UserDto user1=new UserDto();
    user1.setId(15L);
    user1.setUsername("傅筱");
    user1.setPassword("1111");
    userService.updateUser(user1);

}

在这只是测试了两个,其余读者自测。


版权声明:本文为博主原创文章,未经博主允许不得转载。


猜你喜欢

转载自blog.csdn.net/qq_42112846/article/details/80862101