Java EE学习笔记(七)

MyBatis的核心配置

1、MyBatis的核心对象

1)、SqlSessionFactory是MyBatis框架中十分重要的对象,它是单个数据库映射关系经过编译后内存镜像,其主要作用是创建SqlSession

2)、SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来构建,而SqlSessionFactoryBuilder则可以通过XML配置文件一个预先定义好的Configuration实例构建出SqlSessionFactory的实例

3)、构建SqlSessionFactory

a)、通过XML配置文件构建出的SqlSessionFactory实例现代码如下:

InputStream inputStream = Resources.getResourceAsStream("配置文件位置");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 根据配置文件构建SqlSessionFactory

b)、SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用执行期间都会存在。如果我们多次的创建同一个数据库的SqlSessionFactory,那么此数据库的资源将很容易被耗尽。为此,通常每一个数据库都会只对应一个SqlSessionFactory,所以在构建SqlSessionFactory实例时,建议使用单列模式

d)、单例模式:是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的一个类只有一个实例。即一个类只有一个对象实例

4)、SqlSession是MyBatis框架中另一个重要的对象,它是应用程序持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作。SqlSessionu对象包含了数据库中所有执行SQL操作的方法,由于底层封装了JDBC连接,所以可以直接使用其实例来执行已映射的SQL语句

Java EE学习笔记(七)_第1张图片

5)、每一个线程都应该有一个自己的SqlSession实例,并且该实例是不能被共享的。同时,SqlSession实例也是线程不安全的,因此其使用范围最好在一次请求或一个方法中,绝不能将其放在一个类的静态字段实例字段任何类型的管理范围(如Servlet的HttpSession)中使用。

使用完SqlSession对象后要及时关闭,通常可以将其放在finally块中关闭。
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
       // 此处执行持久化操作
} finally {
      sqlSession.close();
}

6)、SqlSession中的方法:

查询方法:
T selectOne(String statement);
T selectOne(String statement, Object parameter);
List selectList(String statement);
List selectList(String statement, Object parameter);
List selectList(String statement, Object parameter, RowBounds rowBounds);
void select(String statement, Object parameter, ResultHandler handler);

插入、更新和删除方法:(返回值为执行SQL语句所影响的行数)
int insert(String statement);
int insert(String statement, Object parameter);
int update(String statement);
int update(String statement, Object parameter);
int delete(String statement);
int delete(String statement, Object parameter);

其他方法:
void commit(); 提交事务的方法。
void rollback(); 回滚事务的方法。
void close(); 关闭SqlSession对象。
T getMapper(Class type); 返回Mapper接口的代理对象。
Connection getConnection(); 获取JDBC数据库连接对象的方法。

 7)、为了简化开发,通常在实际项目中都会使用工具类来创建SqlSession。

a)、src->MybatisUtils.java

 1 package com.itheima.utils;
 2 import java.io.Reader;
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7 /**
 8  * 工具类,简化代码
 9  */
10 public class MybatisUtils {
11     
12     private static SqlSessionFactory sqlSessionFactory = null;
13     
14     // 1、初始化SqlSessionFactory对象工厂(只创建了一个)
15     static {
16         try {
17             
18             // 2、使用MyBatis提供的Resources类加载MyBatis的配置文件
19             Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
20             
21             // 3、构建SqlSessionFactory工厂
22             sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
23             
24         } catch (Exception e) {
25             e.printStackTrace();
26         }
27     }
28     
29     // 4、通过getSession()方法获取SqlSession对象的静态方法
30     public static SqlSession getSession() {
31         return sqlSessionFactory.openSession();
32     }
33 }

Java EE学习笔记(七)_第2张图片

2、配置文件

1)、主要元素:在MyBatis框架的核心配置文件中,元素是配置文件的根元素,其他元素都要在元素内配置

 Java EE学习笔记(七)_第3张图片

注意:这些子元素必须按照由上到下的顺序进行配置,否则MyBatis在解析XML配置文件的时候会报错。

2)、元素 

a)、是一个配置属性的元素,该元素通常用来将内部的配置外在化,即通过外部的配置来动态的替换内部定义的属性。例如,数据库的连接等属性,就可以通过典型的Java属性文件中的配置来替换,具体方式如下:

b)、src->db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=******

#密码自己设置

c)、在MyBatis配置文件mybatis-config.xml中配置元素:(相当于C语言的宏定义)

<properties resource="db.properties" />

d)、修改配置文件中数据库连接的信息dataSource中连接数据库的4个属性(driver,url、username和password)值将会由db.properties文件中对应的值来动态替换。

<dataSource type="POOLED">
    
    <property name="driver" value="${jdbc.driver}" />

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

3)、元素

a)、元素主要用于改变MyBatis运行时的行为,例如开启二级缓存、开启延迟加载等。 

b)、元素中的常见配置在配置文件中的使用方式如下:









...

c)、元素用于为配置文件中的Java类型设置一个简短的名字,即设置别名。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余(含有绝对路径的名称)。 

d)、使用元素配置别名的方法如下:

  
  

e)、当POJO类过多时,可以通过自动扫描包的形式自定义别名,具体如下:(注意别名不区分大小写,会导致重复定义覆盖问题

  
  

注意:上述方式的别名只适用于没有使用注解的情况。如果在程序中使用了注解,则别名为其注解的值

f)、MyBatis框架默认为许多常见的Java类型提供了相应的类型别名,如下表所示。

Java EE学习笔记(七)_第4张图片

4)、元素

a)、typeHandler的作用就是将预处理语句中传入的参数javaType(Java类型)转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。 

b)、元素可以在配置文件中注册自定义的类型处理器,它的使用方式有两种。

①注册一个类的类型处理器

  
  

②注册一个包中所有的类型处理器

  
  

 5)、元素

a)、MyBatis框架每次创建结果对象的新实例时,都会使用一个对象工厂(ObjectFactory)的实例来完成。MyBatis中默认的ObjectFactory的作用实例化目标类,它既可以通过默认构造方法实例化,也可以在参数映射存在的时候通过参数构造方法来实例化。通常使用默认的ObjectFactory即可。

b)、大部分场景下都不用配置和修改默认的ObjectFactory ,如果想覆盖ObjectFactory的默认行为,可以通过自定义ObjectFactory来实现,具体如下:

 1 package com.itheima.factory;
 2 import java.util.Collection;
 3 import java.util.List;
 4 import java.util.Properties;
 5 
 6 import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
 7 
 8 //自定义工厂类
 9 public class MyObjectFactory extends DefaultObjectFactory {
10     private static final long serialVersionUID = -4114845625429965832L;
11     public  T create(Class type) {
12         return super.create(type);
13     }
14     public  T create(Class type, List> constructorArgTypes, List constructorArgs) {
15         return super.create(type, constructorArgTypes, constructorArgs);
16     }
17     public void setProperties(Properties properties) {
18         super.setProperties(properties);
19     }
20     public  boolean isCollection(Class type) {
21         return Collection.class.isAssignableFrom(type);
22     }
23 } 
    
   

c)、在配置文件中使用元素配置自定义的ObjectFactory,配置如下:

<objectFactory type="com.itheima.factory.MyObjectFactory">
     <property name="name" value="MyObjectFactory"/>
objectFactory>

6)、元素

MyBatis允许在已映射语句执行过程中的某一点进行拦截调用,这种拦截调用是通过插件来实现的。元素的作用就是配置用户所开发的插件

7)、元素

a)、元素用于对环境进行配置。MyBatis的环境配置实际上就是数据源的配置,我们可以通过元素配置多种数据源,即配置多种数据库

b)、使用元素进行环境配置的示例如下:

 1 <environments default="development">
 2     
10     <environment id="development">
11         
12         <transactionManager type="JDBC" />
13         
14         <dataSource type="POOLED">
15             <property name="driver" value="${jdbc.driver}" />
16             <property name="url" value="${jdbc.url}" />
17             <property name="username" value="${jdbc.username}" />
18             <property name="password" value="${jdbc.password}" />
19         dataSource>
20     environment>
21     ...
22 environments>

c)、在MyBatis中,可以配置两种类型的事务管理器,分别是JDBCMANAGED。关于这两个事务管理器的描述如下:

JDBC:此配置直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务的作用域
MANAGED:此配置从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。默认情况下,它会关闭连接,但一些容器并不希望这样,为此可以将closeConnection属性设置为false来阻止它默认的关闭行为

注意:如果项目中使用的是Spring+ MyBatis,则没有必要在MyBatis中配置事务管理器,因为实际开发中,会使用Spring自带的管理器来实现事务管理

d)、数据源的配置:

UNPOOLED:配置此数据源类型后,在每次被请求时会打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。在使用时,需要配置5种属性。

Java EE学习笔记(七)_第5张图片

POOLED:此数据源利用“池”的概念将JDBC连接对象组织起来,避免了在创建新的连接实例时所需要初始化和认证的时间。POOLED数据源可额外配置的属性。

Java EE学习笔记(七)_第6张图片

③JNDI:可以在EJB或应用服务器等容器中使用。容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。在使用时,需要配置2个属性

Java EE学习笔记(七)_第7张图片

8)、元素

a)、元素用于指定MyBatis映射文件的位置,一般可以使用以下4种方法引入映射器文件,具体如下。

①使用类路径引入(name)


  

②使用本地文件路径引入(url)


  

③使用接口类引入(class)


  

3、映射文件

1)、在映射文件中,元素是映射文件的根元素其他元素都是它的子元素,映射文件的主要元素如下: 

Java EE学习笔记(七)_第8张图片

2)、元素用来映射查询语句,它可以帮助我们从数据库中读取出数据,并组装数据给业务开发人员,使用元素的常用属性:

Java EE学习笔记(七)_第9张图片

c)、元素,配置如下:

<insert id="addCustomer" 
        parameterType="com.itheima.po.Customer"
          flushCache="true"
          statementType="PREPARED" 
      insert into t_customer(username,jobs,phone)
      values(#{username},#{jobs},#{phone})
insert>

①客户持久化类:Customer.java

 1 package com.itheima.po;
 2 /**
 3  * 客户持久化类
 4  */
 5 public class Customer {
 6     
 7     private Integer id;       // 主键id
 8     private String username; // 客户名称
 9     private String jobs;      // 职业
10     private String phone;     // 电话
11     
12     public Integer getId() {
13         return id;
14     }
15     
16     public void setId(Integer id) {
17         this.id = id;
18     }
19     
20     public String getUsername() {
21         return username;
22     }
23     
24     public void setUsername(String username) {
25         this.username = username;
26     }
27     
28     public String getJobs() {
29         return jobs;
30     }
31     public void setJobs(String jobs) {
32         this.jobs = jobs;
33     }
34     
35     public String getPhone() {
36         return phone;
37     }
38     
39     public void setPhone(String phone) {
40         this.phone = phone;
41     }
42     @Override
43     public String toString() {
44         return "Customer [id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]";
45     }
46 }

②客户映射文件:CustomerMapper.xml

 1 xml version="1.0" encoding="UTF-8"?>
 2 DOCTYPE mapper
 3    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5     
 6 <mapper namespace="com.itheima.mapper.CustomerMapper">
 7 
 8     
 9 
10 
11 
12 
13 
14     
15     <select id="findCustomerByName" parameterType="String"
16         resultType="com.itheima.po.Customer">
17         select * from t_customer where username like '%${value}%'
18     select>
19 
20     
24     <insert id="addCustomer" parameterType="com.itheima.po.Customer" 
25             keyProperty="id" useGeneratedKeys="true">            
26         insert into t_customer(username,jobs,phone)
27         values(#{username},#{jobs},#{phone})
28     insert>
29 
30     
37     <insert id="insertCustomer" parameterType="com.itheima.po.Customer">
38         <selectKey keyProperty="id" resultType="Integer" order="BEFORE">
39         select if(max(id) is null, 1, max(id) +1) as newId from t_customer
40         selectKey>            
41         insert into t_customer(id,username,jobs,phone)
42         values(#{id},#{username},#{jobs},#{phone})
43     insert>
44 
45     
46     <update id="updateCustomer" parameterType="com.itheima.po.Customer">
47         update t_customer 
48         set username=#{username},jobs=#{jobs},phone=#{phone}
49         where id=#{id}
50     update>
51 
52     
53     <delete id="deleteCustomer" parameterType="Integer">
54         delete from t_customer where id=#{id}
55     delete>
56 
57     
58 
59 
60 
61 
62 
63 
64 
65 
66     
67     <sql id="tablename">
68         ${prefix}customer
69     sql>
70 
71     
72     <sql id="someinclude">
73         from
74         <include refid="${include_target}" />        
75     sql>
76 
77     
78     <sql id="customerColumns">
79        id,username,jobs,phone
80     sql>
81 
82     
83     <select id="findCustomerById" parameterType="Integer" 
84             resultType="com.itheima.po.Customer">
85         select 
86         <include refid="customerColumns"/> 
87         <include refid="someinclude"> 
88             <property name="prefix" value="t_" />  
89             <property name="include_target" value="tablename" /> 
90         include>
91         where id = #{id}
92     select>
93 
94 mapper>

③配置文件:mybatis-config.xml

 1 xml version="1.0" encoding="UTF-8" ?>
 2 DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 3                           "http://mybatis.org/dtd/mybatis-3-config.dtd">
 4   
 5 <configuration>
 6 
 7     <properties resource="db.properties" />
 8     
 9     
10     
14 
15     
16     
19 
20     
21     <environments default="mysql">
22     
23         
24         <environment id="mysql">
25         
26             
27             <transactionManager type="JDBC" />
28             
29             
30             <dataSource type="POOLED">
31             
32                 
33                 <property name="driver" value="${jdbc.driver}" />
34                 
35                 
36                 <property name="url" value="${jdbc.url}" />
37                 
38                 
39                 <property name="username" value="${jdbc.username}" />
40                 
41                 
42                 <property name="password" value="${jdbc.password}" />
43                 
44             dataSource>
45         environment>
46     environments>
47 
48     
49     <mappers>
50         <mapper resource="com/itheima/mapper/CustomerMapper.xml" />
51         <mapper resource="com/itheima/mapper/UserMapper.xml" />
52     mappers>
53 configuration>

④测试单元:

 1     @Test
 2     public void addCustomerTest(){
 3         
 4         // 通过工具类获取SqlSession
 5         SqlSession sqlSession = MybatisUtils.getSession();
 6         Customer customer = new Customer();
 7         customer.setUsername("NOOo");
 8         customer.setJobs("programmer");
 9         customer.setPhone("22525323392");
10         
11         // 使用主键自助增长的添加方法
12         int rows = sqlSession.insert("com.itheima.mapper.CustomerMapper.addCustomer", customer);
13         
14 //         使用自定义主键值的添加方法
15 //        int rows = sqlSession.insert("com.itheima.mapper.CustomerMapper.insertCustomer", customer);
16         
17         // 输出插入数据的主键id值
18         System.out.println(customer.getId());        
19         if(rows > 0){
20             System.out.println("您成功插入了"+rows+"条数据!");
21         }else{
22             System.out.println("执行插入操作失败!!!");
23         }
24         
25         sqlSession.commit();
26         sqlSession.close();
27     }

g)、运行结果:

Java EE学习笔记(七)_第11张图片

Java EE学习笔记(七)_第12张图片

h)、对于不支持主键自助增长的数据库(如Oracle),可以通过如下配置实现:

<insert id="insertCustomer" parameterType="com.itheima.po.Customer">
      <selectKey keyProperty="id" resultType="Integer" order="BEFORE">
      
            select if(max(id) is null, 1, max(id) +1) as newId from t_customer
      selectKey>            
      insert into t_customer(id,username,jobs,phone)
      values(#{id},#{username},#{jobs},#{phone})
insert>

j)、运行结果:

Java EE学习笔记(七)_第13张图片

Java EE学习笔记(七)_第14张图片

3)、元素

<update
      id="updateCustomer" 
      flushCache="true" 
      statementType="PREPARED" 
      timeout="20"> 
<delete
      id="deleteCustomer"
      parameterType="com.itheima.po.Customer"
      flushCache="true"
      statementType="PREPARED"
      timeout="20">

a)、update和delete的配置代码如下:(注意执行完成之后会返回一个表示影响记录条数的整数

<update id="updateCustomer" parameterType="com.itheima.po.Customer">
       update t_customer 
       set username=#{username},jobs=#{jobs},phone=#{phone}
       where id=#{id}
update>
<delete id="deleteCustomer" parameterType="Integer"> delete from t_customer where id=#{id} delete>

4)、元素元素的作用就是定义可重用的SQL代码片段,然后在其他语句中引用这一代码片段

a)、定义一个包含id、username、jobs和phone字段的代码片段如下:

<sql id="customerColumns">id,username,jobs,phonesql>

b)、上述代码片段可以包含在其他语句中使用,具体如下:通过元素的refid属性引用id为someinclude的代码片段,先加入from,再通过获取元素的值来组成表名

<select id="findCustomerById" parameterType="Integer"
            resultType="com.itheima.po.Customer">
    select <include refid="customerColumns"/>
    
    from t_customer 
    where id = #{id}
select>

c)、定义sql片段:使用元素的refid属性引用了自定义代码片段。

 1 
 2     <sql id="tablename">
 3         ${prefix}customer
 4     sql>
 5     
 6     
 7     <sql id="someinclude">
 8         from
 9         <include refid="${include_target}" />        
10     sql>
11     
12     
13     <sql id="customerColumns">
14        id,username,jobs,phone
15     sql>
16     
17     
18     <select id="findCustomerById" parameterType="Integer" resultType="com.itheima.po.Customer">
19         select 
20         <include refid="customerColumns"/> 
21         
22         <include refid="someinclude"> 
23             <property name="prefix" value="t_" /> 
24             <property name="include_target" value="tablename" /> 
25         include>
26         where id = #{id}
27     select>

5)、元素

a)、元素表示结果映射集,是MyBatis中最重要也是最强大的元素。它的主要作用是定义映射规则、级联的更新以及定义类型转化器等

b)、元素中包含了一些子元素,它的元素结构如下所示:

 1 <resultMap type="" id="">
 2        <constructor>    
 3        
 4        
 5              <idArg/>      
 6              
 7              
 8              <arg/>          
 9              
10              
11        constructor>  
12        
13        <id/>                 
14        
15        
16        <result/>           
17        
18        
19        <association property="" />        
20        
21        
22        <collection property="" />          
23        
24        
25        <discriminator javaType="">      
26        
27        
28             <case value="" />                  
29             
30        discriminator>    
31 resultMap>

c)、在mybatis数据库中,创建t_user表:

CREATE TABLE t_user(
    t_id INT PRIMARY KEY AUTO_INCREMENT,
    t_name VARCHAR(50),
    t_age INT
);

INSERT INTO t_user(t_name, t_age) VALUES('Lucy', 25);
INSERT INTO t_user(t_name, t_age) VALUES('Lili', 20);
INSERT INTO t_user(t_name, t_age) VALUES('Jim', 20);

①创建持久化类:User.java

 1 package com.itheima.po;
 2 
 3 public class User { // POJO
 4     
 5     private Integer id;
 6     private String name;
 7     private Integer age;
 8     
 9     public Integer getId() {
10         return id;
11     }
12     
13     public void setId(Integer id) {
14         this.id = id;
15     }
16     
17     public String getName() {
18         return name;
19     }
20     
21     public void setName(String name) {
22         this.name = name;
23     }
24     
25     public Integer getAge() {
26         return age;
27     }
28     
29     public void setAge(Integer age) {
30         this.age = age;
31     }
32     
33     @Override
34     public String toString() {
35         return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
36     }    
37 }

②创建映射文件:UserMapper.xml

 1 xml version="1.0" encoding="UTF-8"?>
 2 DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3                   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4                   
 5          
 6 <mapper namespace="com.itheima.mapper.UserMapper">
 7     
 8     
12     <resultMap type="com.itheima.po.User" id="resultMapID">
13     
14     
21       <id property="id" column="t_id"/>
22       <result property="name" column="t_name"/>
23       <result property="age" column="t_age"/>    
24     resultMap>
25     
26     
27     <select id="findAllUser" resultMap="resultMapID">
28         select * from t_user    
29     select>
30 mapper>

③测试单元:

 1    @Test
 2     public void findAllUserTest() {
 3         
 4         // 通过工具类获取SqlSession
 5         SqlSession sqlSession = MybatisUtils.getSession();
 6         
 7         // SqlSession执行映射文件中定义的SQL,并返回映射结果集合
 8         List list = sqlSession.selectList("com.itheima.mapper.UserMapper.findAllUser");
 9         
10         for (User user : list) {
11             System.out.println(user);
12         }
13         
14         // 关闭SqlSession
15         sqlSession.close();
16     }

④运行结果:

Java EE学习笔记(七)_第15张图片

 个人总结:

本章主要讲mybatis的核心配置,内容比较多,需要反复看并且经常操作才能熟练运用和理解应用程序到数据库之间的映射的详细过程。总之,先把配置文件config.xml配置好,其次再创建持久化类,并编写对应的映射文件(将持久化类中属性与数据库中表的属性列对应起来),剩下的就是简单的测试了。

注意:①使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以成功映射;②若查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系

转载于:https://www.cnblogs.com/acgoto/p/10614790.html

你可能感兴趣的:(Java EE学习笔记(七))