欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mybatis

程序员文章站 2022-05-02 07:53:06
...

一、工作原理

1)核心

Mybatis

原理详解:

        MyBatis应用程序根据XML配置文件创建SqlSessionFactory,SqlSessionFactory在根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解,获取一个SqlSession。SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,完成对数据的增删改查和事务提交等,用完之后关闭SqlSession。

2)执行流程图

Mybatis

加载sqlmapconfig.xml,通过sqlsessionfactorybuilder,构建sqlsesionfactroy对象.由它构建sqlsession提供增删改查等操作数据库的方法.

1.sqlMapConfig.xml:mybatis全局配置文件,配置了数据源,事务等mybatis的运行环境,与spring整合后由spring的配置文件接管。mapper.xml映射文件(配置sql语句等)

2.sqlSessionFactory(会话工厂):创建sqlSession(根据配置文件创建)。

3.sqlSession:操作数据库(crud):是一个面向用户的接口

4.Executor(执行器):SqlSession内部通过该执行器操做数据库(是一个接口:分为基本执行器和缓存执行器)

5.mapped Statement:(底层封装对象):对操作数据库存储封装:包括sql语句,输入参数,输出结果类型进行封装。

mapped Statement的主要成员

StatementHandler 封装了JDBC Statement操作,负责对JDBCstatement 的操作,如设置参数等

ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所对应的数据类型

ResultSetHandler  负责将JDBC返回的ResultSet结果集对象转换成List类型的集合

TypeHandler         负责java数据类型和jdbc数据类型(也可以说是数据表列类型)之间的映射和转换

MappedStatement MappedStatement维护一条<select|update|delete|insert>节点的封装

以上主要成员在一次数据库操作中基本都会涉及,在SQL操作中重点需要关注的是SQL参数什么时候被设置和结果集怎么转换为JavaBean对象的,这两个过程正好对应StatementHandler和ResultSetHandler类中的处理逻辑。

Mybatis

3)优缺点

优点:

1、灵活

2、解除sql与程序代码的耦合

3、提供映射标签,支持对象与数据库的orm字段关系映射

4、提供对象关系映射标签

5、提供xml标签,支持编写动态sql。

缺点:

1、编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。

2、SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。

3、二级缓存机制不佳

使用jdbc开发时,和mybatis相比的不足

1,数据库连接,使用时就创建,不使用就释放,对数据库进行频繁连接开关和关闭,造成数据库资源浪费,影响数据库的性能

解决:使用数据库连接池管理数据库的连接

2,sql语句使用硬编码在java程序中,修改sql语句,就需要重新编译java代码,不利于系统维护

解决:把sql语句放在xml配置文件中,修改sql语句也不需要重新编译java代码

3,向预编译语句PreparedStatement中设置参数,对占位符位置和设置参数值,硬编码,修改sql语句也不需要重新编译java代码

解决:把sql语句和占位符设置参数值放在xml配置文件中

4,从result中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码

解决:将查询的结果集,自动映射成 java对象

和jdbc比较:

mybatis抽离出数据库的连接,关闭的操作.抽离了sql语句,并且可以自动的进行参数的设置,封装结果集.

2.mybatis跟hibante的比较, 优缺点.

1.hibernate是全自动,而mybatis是半自动。
hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。
而mybatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写sql来实现和管理。
2. hibernate数据库移植性远大于mybatis。
hibernate通过它强大的映射结构和hql语言,大大降低了对象与数据库(Oracle、MySQL等)的耦合性,而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性而用了很多某数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。
3. mybatis相比hibernate需要关心很多细节
hibernate配置要比mybatis复杂的多,学习成本也比mybatis高。
4. sql直接优化上,mybatis要比hibernate方便很多
由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。
而hibernate的sql很多都是自动生成的,无法直接维护sql;
虽有hql,但功能还是不及sql强大,见到报表等变态需求时,hql也歇菜,也就是说hql是有局限的;
hibernate虽然也支持原生sql,但开发模式上却与orm不同,需要转换思维,因此使用上不是非常方便。
总之写sql的灵活度上hibernate不及mybatis。

和hibernate比较:

- 性能:mybatis较hibernate高

- sql灵活性:mybatis较hibernate高

- 配置文件:mybatis较hibernate多(维护困难)

- 数据库的无关性:mybatis较hibernate低

4)编程步骤

1、加入jar包

2、创建conf.xml

3、创建xxxMapper.xml,要在conf.xml注册

4、建包bean,Mapper

5、测试

public staticvoid main(String[] args) throws IOException {

Stringresource = "conf.xml";

//加载mybatis 的配置文件(它也加载关联的映射文件)

Reader reader= Resources.getResourceAsReader(resource);

//构建sqlSession 的工厂

SqlSessionFactorysessionFactory = new SqlSessionFactoryBuilder().build(reader);

//创建能执行映射文件中sql 的sqlSession

SqlSessionsession = sessionFactory.openSession();

//映射sql 的标识字符串

Stringstatement = "com.atguigu.mybatis.bean.userMapper"+".selectUser";

//执行查询返回一个唯一user 对象的sql

User user =session.selectOne(statement, 1);

System.out.println(user);

}

CUD操作:

① 创建SqlSessionFactory

② 通过SqlSessionFactory创建SqlSession

③ 通过sqlsession执行数据库操作

④ 调用session.commit()提交事务

⑤ 调用session.close()关闭会话

二、sqlMapConfig.xml

SqlMapConfig,xml解析

文件中的配置项是有顺序的,按照官方图来配.

configuration

- properties

- settings

- typeAliases

- typeHandlers

- objectFactory

- plugins

- environments

* envioronment

* transactionManager

* dataSource

- databaseIdProvider

- mappers

 1.properties标签:

        可以引用一些properties的资源文件。注意:不建议在properties标签里添加属性,可能会覆盖掉其他相同名称的属性值。

2.Setting标签:

          配置全局参数:主要是跟Mybaties运行相关的一些参数

3.typeAliases

           别名定义。在mybatis中的resultType和parameterType的类型有可能是自定义的pojo类型,地址很长,不利于开发,可以使用别名定义。

           批量别名定义:在其中使用package标签,name为表名,别名为类名,首字母不区分大小写。

4.类型处理器

            jdbc类型与Java类型之间的相互转换,mybatis提供了许多转换类型,因此一般不需要我们手动配置。

5.mapper

            class属性加载的是通过mapper接口加载映射文件,但需要遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称一致,且在同一个目录当中。

            mapper批量加载:遵循上述规范,用package标签

<!-- resource:表示从classpath下加载 -->

   <properties resource="db.properties">

       <property name="jdbc.driver"value="com.mysql.jdbc.Driver"/>

   </properties>

settings: 全局参数设置

设置延迟加载:

   <settings>

       <!-- 开启延迟加载,默认值为true-->

        <settingname="lazyLoadingEnabled" value="true" />

       <!--设置积极的懒加载,默认值是true-->

       <setting name="aggressiveLazyLoading"value="false" />

   <settings>

typeAliases:类型别名

<!-- 自定义别名 -->

<typeAliases>

   <!-- type:指定java对象类型 -->

   <!-- alias:给java对象取得别名,对大小写不敏感-->

   <typeAlias type="com.aric.mybatis.po.User"alias="user"/>

   <!-- 扫描包的方式,别名就是包下类的类名,不区分大小写-->

   <package name="com.aric.mybatis.po"/>

</typeAliases>

<typeAliases>

       <typeAlias alias="Song" type="com.yrw.crawler.model.Song"/>

   </typeAliases>

<plugins>

           <plugininterceptor="com.github.pagehelper.PageHelper">

           <propertyname="dialect" value="mysql"/>

           </plugin>

</plugins>

<environmentsdefault="development">

        <environmentid="development">

            <transactionManagertype="JDBC" />

            <dataSourcetype="POOLED">

                <propertyname="driver" value="com.mysql.jdbc.Driver" />

                <propertyname="url" value="jdbc:mysql://localhost:3306/mybatis"/>

                <propertyname="username" value="root" />

                <propertyname="password" value="" />

            </dataSource>

        </environment>

    </environments>

mappers:

<mappers>

   <!-- resource:从classpath下加载sql映射文件-->

   <!-- <mapper resource="sqlmap/User.xml"/>

   <mapper resource="mapper/User.xml"/> -->

   <!-- 指定mapper接口的类路径 -->

   <!-- 要求:1.mapper接口 和sql的映射文件在同一个目录下,2.mapper接口的类名和映射文件的名称要一致-->

   <!-- <mapper class="com.aric.mybatis.mapper.UserMappser"/> -->

   <!--包扫描-->

   <package name="com.aric.mybatis.mapper" />

</mappers>

三、映射文件

mapper代理的方式(对原始dao的优化), 基于注解或者基于xml文档mapper,只需要写接口,不需要写实现类,实现类由mybatis框架自动创建.

使用步骤:

1.程序员需要编写mapper.xml文件

2.编写mapper接口需要依据规范:

                1. sql的映射文件中的namespace要和Mapper接口中的类路径(全限定名)一致

                2. sql的映射文件中的sql的id要和mapper接口中的方法的名称一致

                3. sql的映射文件中的parameterType要和mapper接口中的方法的参数类型一致

                4. sql的映射文件中的resultType要和mapper接口中的方法的返回值数据类型一致

3.获取自动生成的实现类对象

  sqlSession.getMapper(接口名.class);

<!-- namespace:命令空间,类似包-->

<mappernamespace="test">

   <!-- 添加用户 -->

   <!-- parameterType指定java对象,获取值时#{}中必须是java对象中的属性名 -->

       <!-- keyProperty:查询到的主键,放入到User对象中的id属性 -->

insert操作时,要注意主键 主键生成策略,要设置useGeneraterKey= true,和 keyProperty="id",指定哪个是主键

<insert id="addUser" parameterType="User" 
        useGeneratedKeys="true" keyProperty="id"> 
        insert into user(userName,userAge,userAddress)  
             values(#{userName},#{userAge},#{userAddress})  
    </insert>
 

   <!-- 删除用户 -->

   <delete id="deleteUserById"parameterType="int">

        delete from user where id = #{id}

   </delete>

   <!-- 更新用户 -->

   <update id="updateUserById"parameterType="user">

       update user set birthday=#{birthday},sex=#{sex},address=#{address} whereid=#{id}

</update>

<!-- id:代表sql语句的唯一标识-->

   <!-- resultType:查询结果集的类型 -->

   <!-- parameterType:输入参数的数据类型,通过parameterType接收参数,进行动态sql生成。运用ognl表达式-->

   <!-- #{id}:用于接收数据,代表一个占位符,表示将外部传递过来的数据映射到sql语句中 -->

   <!-- #{}中的变量可以是任意的(前提条件是:输入参数的数据类型是简单的类型) -->

   <select id="getUserById" parameterType="int"resultType="com.aric.mybatis.po.User" >

       select * from user where id=#{idd}

   </select>

   <!-- 如果查询的结果是列表,那么resultType只需指定列表中元素的类型 -->

   <select id="getUserByUsername"parameterType="String"resultType="com.aric.mybatis.po.User">

       <!-- ${value}表示sql串的拼接,${value}中变量必须是value(如果输入的是简单类型)

注意点

#{xxx}表示一个占位符,jdbc中的?通过#{xxx} 可以将外部传递过来映射到sql语句中,可以有效的防止sql注入.

xxx表示一个sql串的拼接,不可以有效防止sql注入.如果是{xxx},输入的参数类型是简单类型,那么${xxx}中的xxx必须是value.

-->

       select * from user where username like "%${value}%"

   </select>

<select id="selectUserOrders_details_items" resultMap="resultMap_user_orders_details_items">
    SELECT
        u.id AS user_id,
        u.username,
        ord.id AS order_id,
        ord.number,
        de.id AS detail_id,
        i.id AS item_id,
        i. NAME
    FROM
        USER u
    LEFT JOIN orders ord ON u.id = ord.user_id
    LEFT JOIN orderdetail de ON de.orders_id = ord.id
    LEFT JOIN items i ON de.items_id = i.id
</select>
</mapper>

输入映射

            自定义包装类型,可以将很多pojo类以及扩展类定义在包装类型中,根据需求而定

输出映射

  1.resultType

                ①:使用该属性映射,只有查询出来的列名与pojo属性名一致,才可以映射成功

                ②:如果查询出来的列名与pojo属性名全都不一致,则不会创建映射的pojo对象,但只要有一个列与pojo属性名称一致,就会创建pojo对象

 2.resultMap

          如果查询出来的列名与pojo属性名不一致却还要与pojo映射,可以使用resultMap

           首先要定义resultMap与pojo属性的对应关系

orm格式转换:通过设置resultMap和ResultType,将数据库中的记录转换为代码的bean对象。得到list或者对象。返回list,必须要配置resultMAp.

resultMap做复杂的映射配置(多表查询).

解决字段名与实体类属性名不相同的冲突

通过<resultMap>

<select id="selectOrderResultMap"parameterType="int" resultMap="orderResultMap">

select * from orders where order_id=#{id}

</select>

<resultMap type="_Order"id="orderResultMap">

<id property="id" column="order_id"/>

<result property="orderNo"column="order_no"/>

<result property="price"column="order_price"/>

</resultMap>

一对一查询

        使用association标签将关联的信息映射到单个Java对象中,使用collection将关联信息映射到对象的集合当中。

<!--

方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集

封装联表查询的数据(去除重复的数据)

select * from class c, teacher t wherec.teacher_id=t.t_id and c.c_id=1

-->

<select id="getClass"parameterType="int" resultMap="ClassResultMap">

select * fromclass c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}

</select>

<resultMap type="_Classes"id="ClassResultMap">

<idproperty="id" column="c_id"/>

<resultproperty="name" column="c_name"/>

<associationproperty="teacher" column="teacher_id"javaType="_Teacher">

<idproperty="id" column="t_id"/>

<resultproperty="name" column="t_name"/>

</association>

</resultMap>

<!--

方式二:嵌套查询:通过执行另外一个SQL 映射语句来返回预期的复杂类型

SELECT * FROM class WHERE c_id=1;

SELECT * FROM teacher WHERE t_id=1 //1 是上一个查询得到的teacher_id 的值

-->

<select id="getClass2"parameterType="int" resultMap="ClassResultMap2">

select * from class where c_id=#{id}

</select>

<resultMap type="_Classes"id="ClassResultMap2">

<idproperty="id" column="c_id"/>

<resultproperty="name" column="c_name"/>

<associationproperty="teacher" column="teacher_id"javaType="_Teacher"

select="getTeacher">

</association>

</resultMap>

<select id="getTeacher"parameterType="int" resultType="_Teacher">

SELECT t_idid, t_name name FROM teacher WHERE t_id=#{id}

</select>

Mybatis

映射一对多关系

<!--

方式一: 嵌套结果: 使用嵌套结果映射来处理重复的联合结果的子集

SELECT * FROM class c, teacher t,students WHERE c.teacher_id=t.t_id AND c.C_id=s.class_id AND c.c_id=1

-->

<select id="getClass3"parameterType="int" resultMap="ClassResultMap3">

select * fromclass c, teacher t,student s where c.teacher_id=t.t_id and c.C_id=s.class_idand c.c_id=#{id}

</select>

<resultMap type="_Classes"id="ClassResultMap3">

<idproperty="id" column="c_id"/>

<resultproperty="name" column="c_name"/>

<associationproperty="teacher" column="teacher_id"javaType="_Teacher">

<idproperty="id" column="t_id"/>

<resultproperty="name" column="t_name"/>

</association>

<!-- ofType指定students 集合中的对象类型 -->

<collectionproperty="students" ofType="_Student">

<idproperty="id" column="s_id"/>

<resultproperty="name" column="s_name"/>

</collection>

</resultMap>

<!--

方式二:嵌套查询:通过执行另外一个SQL 映射语句来返回预期的复杂类型

SELECT * FROM class WHERE c_id=1;

SELECT * FROM teacher WHERE t_id=1 //1 是上一个查询得到的teacher_id 的值

SELECT * FROM student WHERE class_id=1//1 是第一个查询得到的c_id 字段的值

-->

<select id="getClass4"parameterType="int" resultMap="ClassResultMap4">

select * fromclass where c_id=#{id}

</select>

<resultMap type="_Classes"id="ClassResultMap4">

<idproperty="id" column="c_id"/>

<resultproperty="name" column="c_name"/>

<associationproperty="teacher" column="teacher_id"javaType="_Teacher"

select="getTeacher2"></association>

<collectionproperty="students" ofType="_Student"column="c_id" select="getStudent"></collection>

</resultMap>

<select id="getTeacher2"parameterType="int" resultType="_Teacher">

SELECT t_idid, t_name name FROM teacher WHERE t_id=#{id}

</select>

<select id="getStudent"parameterType="int" resultType="_Student">

SELECT s_idid, s_name name FROM student WHERE class_id=#{id}

</select>

Mybatis

多对多映射

<!-- resultMap:定义查询用户关联查询订单关联查询订单明细及商品信息 -->
<resultMap type="user" id="resultMap_user_orders_details_items">
    <id column="user_id" property="id" />
    <result column="username" property="username"/>
    <!-- 一个用户对应多个订单 -->
    <collection property="orders" ofType="com.aric.mybatis.po.Orders">
        <id column="order_id" property="id" />
        <result column="number" property="number" />
        <!-- 一个订单对应多个订单明细 -->
        <collection property="orderdetail" ofType="com.aric.mybatis.po.OrderDetail">
            <id column="detail_id" property="id" />
            <!-- 一个订单明细对应一个商品 -->
            <association property="items" javaType="com.aric.mybatis.po.Items">
                <id column="item_id" property="id" />
                <result column="name" property="name" />
            </association>
        </collection>
    </collection>
</resultMap>

四、缓存

正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持

1. 一级缓存: 基于PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session.flush 或 close 之后,该Session 中的所有 Cache 就将清空。

2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于

其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。

3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了

C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。

一级缓存:session(默认使用的)

1、同一个session,并且session没有close或者clearcache

2、查询条件一样

3、没有执行过增删改操作

二级缓存:Mapper(需要手动开启)

二级缓存的配置

1. 开启二级缓存中开关

   <!--二级缓存总开关-->

   <setting name="cacheEnabled" value="true">

2. 在mapper映射文件中开启二级缓存

<!--开启二级缓存,默认使用了PerpetualCache-->

<cache/>

<cache

eviction="FIFO" //回收策略为先进先出

flushInterval="60000" //自动刷新时间60s

size="512" //最多缓存512 个引用对象

readOnly="true"/> //只读

3. 禁止使用缓存

useCache=”false”

4. 刷新缓存

select语句默认是false,增删改语句默认是true

flushCache="true"

五、动态SQL

1.主要是where标签与if标签的综合使用,进行灵活的判断后动态拼接sql语句,where标签会自动将第一个and去掉。

2.定义sql片段:可以将相同的sql片段提取出来,这样其他的语句就可以引用该sql,在mapper.xml文件中单独使用sql标签定义。注意:相对于单表定义可重用性才高,不要在其中定义where标签。引用sql片段用include标签。

3.foreach标签可以遍历组装sql语句

collection属性为集合属性名

items为集合属性名称

open为拼接开始语句,close为拼接结束语句,separator为拼接集合属性的连接sql


MyBatis中用于实现动态SQL的元素主要有:
1、if和where
2、choose(when,otherwise)
3、trim
4、set
5、foreach
下面将逐一进行介绍。

if

<!-- 根据用户id和用户名称查询,需要进行判断,如果id为空,就以名称查询,如果名称为空,就以id查询,如果都为空,查询所有 -->
<select id="getUserByIdOrUsername" parameterType="user" resultType="user">
    select * from user 
    <!-- where:可以去掉多余的and,拼接where条件 -->
    <where>
        <if test="id != null">
            and id=#{id}
        </if>
        <if test="username != null and username !=''">
            and username like '%${username}%'
        </if>
    </where>
</select>

choose, when, otherwise

 <select id="findActiveBlogLike" resultType="Blog">
        SELECT * FROM BLOG WHERE state = ‘ACTIVE’
        <choose>
            <when test="title != null">
                AND title like #{title}
            </when>
            <when test="author != null and author.name != null">
                AND author_name like #{author.name}
            </when>
            <otherwise>
                AND featured = 1
            </otherwise>
        </choose>
    </select>

trim, where, set

<!-- 更新用户 -->
<update id="updateUser" parameterType="user">
    update user
    <!-- set:更新并且可以去掉多余的"," -->
    <set>
        <if test="address != null and address != ''">
            address =#{address},
        </if>
        <if test="sex != null and sex != ''">
            sex =#{sex},
        </if>
        <if test="username != null and username != '' ">
            username =#{username}
        </if>
    </set>
    where id=#{id}
</update>
 
<!--去掉多余的前缀-->
<trim prefix="WHERE" prefixOverrides="AND |OR ">
    ...
</trim>
 
<!--去掉多余的后缀-->
<trim prefix="SET" suffixOverrides=",">
    ...
</trim>

foreach

<!-- 查询id在一个范围的用户 -->
<select id="getUserListByForEach" parameterType="QueryVo" resultType="user">
    select * from user 
    <where>
        <!-- collection:queryvo中的集合属性ids -->
        <!-- open:表示开始的sql串 -->
        <!-- close:表示结束的sql串 -->
        <!-- item:要遍历的变量 -->
        <!-- separator:循环遍历时,指定分割的字符 -->
        <foreach collection="ids" open="id in(" close=")" item="id" separator=",">
            `#{id}`
        </foreach>
    </where>
</select>

六、Mybatis整合spring

1. 创建工程 
2. 加入jar spring的包 mybatis的包依赖包 数据库驱动 数据连接池 整合包 日志包 
3. mybatis配置文件

   <configuration>

       <!--全部交给spring管理,但是文件必须存在-->

   </configuration>

4. spring的配置文件

<!-- 配置db.properties数据源 -->

       <context:property-placeholderlocation="classpath:db.properties" />

       <!-- 配置数据库连接池 -->

       <bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource">

            <!-- 配置连接池属性 -->

            <propertyname="driverClassName" value="${jdbc.driver}" />

            <property name="url"value="${jdbc.url}" />

            <propertyname="username" value="${jdbc.username}" />

            <propertyname="password" value="${jdbc.password}" />

            <propertyname="maxActive" value="10" />

            <propertyname="maxIdle" value="5" />

       </bean>

 

       <!-- 配置sqlSessionFactory -->

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

            <!-- 注入mybatis配置文件-->

            <propertyname="configLocation"value="classpath:mybatis/SqlMapConfig.xml"></property>

            <!-- 注入连接池 -->

            <propertyname="dataSource" ref="dataSource"></property>

       </bean>

       <!-- mapper扫描方式生成代理对象 -->

       <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

            <!-- 指定扫描的包 :1.自动批量生成代理对象(接口的类名首字母小写) 2.加载mapper映射文件 -->

            <propertyname="basePackage"value="com.aric.mybatis.mapper"></property>

<propertyname="sqlSessionFactory" ref="sqlSessionFactory" />

       </bean>

<!-- 4. 事务管理 : DataSourceTransactionManager-->

    <beanid="txManager"

        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <propertyname="dataSource" ref="dataSource" />

    </bean>

    <!--5. 使用声明式事务 -->

    <tx:annotation-driventransaction-manager="txManager" />

</beans>

5、通过逆工程生成POJO、Mapper和xxxMapper.xml

6. 数据库、日志的配置文件 


相关标签: J2EE