mybatis的学习笔记

前几天学习了mybatis,今天来复习一下它的内容。

mybatis是一个基于Java的持久层框架,那就涉及到数据库的操作。首先来提出第一个问题:java有jdbc连接数据库,我们为什么还要使用框架呢?要回答这个问题,首先来看一下jdbc是怎样编程的。

 1 private static String sql = "SELECT * FROM USER WHERE username =  ?";
 2
 3     public static void main(String[] args) throws SQLException {
 4
 5         //数据库连接
 6         Connection connection = null;
 7         //预编译statement
 8         //好处:防止 sql注入,提高数据的性能
 9         PreparedStatement preparedStatement = null;
10         //结果集
11         ResultSet resultSet = null;
12
13         try {
14
15             //加载数据库驱动
16             Class.forName("com.mysql.jdbc.Driver");
17
18             //连接数据库
19             connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis", "root", "mysql");
20
21             //构造preparedStatement
22             preparedStatement = connection.prepareStatement(sql);
23             //向preparedStatement中占位符的位置设置参数
24             preparedStatement.setString(1, "张三");
25
26             //发起数据库查询请求,得到结果集
27             resultSet = preparedStatement.executeQuery();
28             //遍历查询结果
29
30             while(resultSet.next()){
31                 int id = resultSet.getInt("id");
32                 String username = resultSet.getString("username");
33                 Date birthday = resultSet.getDate("birthday");
34                 System.out.println(id+"   "+username+"    "+birthday);
35             }
36
37
38         } catch (Exception e) {
39             e.printStackTrace();
40         }finally{
41             //释放资源
42             if(resultSet!=null){
43                 resultSet.close();
44             }
45             if(preparedStatement!=null){
46                 preparedStatement.close();
47             }
48             if(connection!=null){
49                 connection.close();
50             }
51         }
52
53
54     }
55
56 }

从上面代码总结一下jdbc编程中的一些问题:

1、 将sql语句硬编码到java代码中,如果修改sql语句,需要修改java代码,重新编译。系统可维护性不高。

设想如何解决?

能否将sql单独 配置在配置文件中。

2、 数据库连接频繁开启和释放,对数据库的资源是一种浪费。

设想如何解决?

使用数据库连接池管理数据库连接。

3、 向preparedStatement中占位符的位置设置参数时,存在硬编码(占位符的位置,设置的变量值)

设想如何解决?

能否也通过配置的方式,配置设置的参数,自动进行设置参数。

4、 解析结果集时存在硬编码(表的字段名、字段的类型)

设想如何解决?

能否将查询结果集映射成java对象。

先来看看Mybatis的流程图:

以一个具体的案例来说明,先来看看表:

这张表已经被我使用过多次,插入一些数据了。

接下来,第一件事,导包。(会maven的童鞋自己去百度下pom.xml的配置,这个小案例我这里就不用maven了)

项目的整体目录是这个样子的:

先来讲config这个目录下:

全局配置文件:SqlMapConfig.xml文件内容:

数据库运行环境(和spring整合则去掉这部分)

Mapper映射文件。

实现延迟加载,打开二级缓存。

定义别名。

代码如下:

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <!-- 加载数据库连接参数配置文件 -->
 7     <properties resource="db.properties" />
 8
 9     <!-- 全局配置参数 -->
10
11         <settings>
12             <!-- 实现延迟加载 -->
13             <setting name="lazyLoadingEnabled" value="true" />
14             <setting name="aggressiveLazyLoading" value="false" />
15
16             <!-- 打开二级缓存开关       -->
17             <setting name="cacheEnabled" value="true"/>
18         </settings>
19
20
21
22     <!-- 定义别名 -->
23     <typeAliases>
24         <!-- 单个别名定义 type:pojo的路径 alias:别名的名称 -->
25         <!-- <typeAlias type="com.mybatis.po.User" alias="user"/> -->
26         <!-- 批量别名定义 name:指定包名,将包下边的所有pojo定义别名 ,别名为类名(首字母大写或小写都行) -->
27         <package name="com.mybatis.po" />
28     </typeAliases>
29
30     <!-- 和spring整合后 environments配置将废除 -->
31     <environments default="development">
32         <environment id="development">
33             <transactionManager type="JDBC" />
34             <dataSource type="POOLED">
35                 <property name="driver" value="${jdbc.driver}" />
36                 <property name="url" value="${jdbc.url}" />
37                 <property name="username" value="${jdbc.username}" />
38                 <property name="password" value="${jdbc.password}" />
39             </dataSource>
40         </environment>
41     </environments>
42
43     <!-- 配置mapper映射文件 -->
44     <mappers>
45         <!-- resource方式 在UserMapper.xml,定义namespace为mapper接口的地址,映射文件通过namespace找到对应的mapper接口文件 -->
46         <!-- <mapper resource="sqlmap/UserMapper.xml" /> -->
47         <!-- class方式 class:指定 mapper接口的地址 遵循规则:将mapper.xml和mapper.java文件放在一个目录
48             且文件名相同 -->
49         <!-- <mapper class="com.mybatis.mapper.UserMapper"/> -->
50
51
52         <!--批量mapper扫描 遵循规则:将mapper.xml和mapper.java文件放在一个目录 且文件名相同 -->
53         <package name="com.mybatis.mapper" />
54
55
56     </mappers>
57 </configuration>

db.properties

1 jdbc.driver=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/test
3 jdbc.username=root
4 jdbc.password=202011

log4j.properties:使用debug。

1 # Global logging configuration
2 log4j.rootLogger=DEBUG, stdout
3 # Console output...
4 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
5 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
6 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

po类:user.java  要存入二级缓存,所以序列化了。

 1 package com.mybatis.po;
 2
 3 import java.io.Serializable;
 4
 5
14 public class User implements Serializable{
15
16     /**
17      *
18      */
19     private static final long serialVersionUID = 1L;
20
21     private int id;
22     private String username;// 用户姓名
23
24     private String age;
25
26     private String sex;// 性别
27     private String address;// 地址
28     private String detail;// 详细信息
29     public User() {
30
31
32     }
33     public User(String username) {
34         super();
35         this.username = username;
36     }
37
38     public String getAge() {
39         return age;
40     }
41     public void setAge(String age) {
42         this.age = age;
43     }
44     public int getId() {
45         return id;
46     }
47     public void setId(int id) {
48         this.id = id;
49     }
50     public String getUsername() {
51         return username;
52     }
53     public void setUsername(String username) {
54         this.username = username;
55     }
56     public String getSex() {
57         return sex;
58     }
59     public void setSex(String sex) {
60         this.sex = sex;
61     }
62
63     public String getAddress() {
64         return address;
65     }
66     public void setAddress(String address) {
67         this.address = address;
68     }
69     public String getDetail() {
70         return detail;
71     }
72     public void setDetail(String detail) {
73         this.detail = detail;
74     }
75
76     @Override
77     public String toString() {
78         return "User [id=" + id + ", username=" + username + ", age=" + age
79                 + ", sex=" + sex + ", address=" + address + ", detail="
80                 + detail + "]";
81     }
82
83
84
85
86 }

配置mybatis的mapper映射文件:

userMapper.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 <!-- namespace命名空间特殊作用: 如果使用mapper动态代理方法,这里就需要配置mapper接口地址-->
 6
 7 <mapper namespace="com.mybatis.mapper.UserMapper">
 8     <!-- 根据用户id查询一条记录(返回单条记录) -->
 9     <!--
10     select标签表示sql查询,内容会封装到Mapped Statement中。
11     可以将这个select标签称为一个Statement
12     id:Statement的id,用于标识select中定义的 sql,id是在同一个命名空间中不允许重复
13     #{}:表示一个占位符,避免sql注入
14     parameterType:表示输入参数的类型
15     resultType:表示输出 结果集单条记录映射的java对象类型,select查询的字段名和resultType中属性名一致,才能映射成功。
16     #{value}:value表示parameter输入参数的变量,如果输入参数是简单类型,使用#{}占位符,变量名可以使用value或其它的名称
17
18      -->
19     <select id="findUserByName" parameterType="String" resultType="User" useCache="false">
20
21         SELECT * FROM USER WHERE username = #{username}
22
23     </select>
24
25
26     <select id="findUserById" parameterType="int" resultType="User">
27
28         SELECT * FROM USER WHERE id= #{id}
29
30     </select>
31
32
33     <!-- 查询用户列表(返回list集合) -->
34     <!--
35     不管结果集查询一条还是多条,resultType指定结果集单条记录映射的java对象类型
36     ${}:表示sql拼接,相当于sql字符串拼接,无法避免sql注入
37     ${value}:value表示parameter输入参数的变量,如果输入参数是简单类型,使用${}拼接符,变量名必须使用value
38     ${value}直接 将value获取到拼接在sql中,value值不加任何修饰
39      -->
40     <select id="findUserList" parameterType="java.lang.String" resultType="User" >
41       SELECT * FROM USER WHERE username like ‘%${value}%‘
42     </select>
43
44
45     <!-- 添加用户
46     parameterType:如果parameterType指定 是pojo,在#{}中指定 pojo的属性名获取该pojo的属性值
47      -->
48     <insert id="insertUser" parameterType="User"   useGeneratedKeys="true" keyProperty="id">
49
50     <!--
51     useGeneratedKeys设置true表明要mybatis获取由数据库自动生成的主键
52     keyProperty:将主键设置到pojo中哪个属性中
53     order:selectKey中sql执行的时机
54     resultType:selectKey中sql执行的结果类型
55     LAST_INSERT_ID:是insert后获取自增主键值
56      -->
57      <!--
58     <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
59          select LAST_INSERT_ID()
60     </selectKey>
61         -->
62     insert into user(username,sex,address,detail)
63      values(#{username},#{sex},#{address},#{detail})
64     </insert>
65
66     <!-- 根据主键删除用户 -->
67
68     <delete id="deleteUser" parameterType="java.lang.String">
69        delete from user where username =#{username}
70     </delete>
71
72     <!-- 根据主键用户更新
73     更新传入输入参数见容:id和更新的信息
74      -->
75     <update id="updateUser" parameterType="User" >
76        update user set username=#{username},sex=#{sex},address=#{address},detail=#{detail}  where id=#{id}
77     </update>
78
79
80 <cache/>
81 </mapper>

userMapper.java:

 1 package com.mybatis.mapper;
 2
 3 import java.util.List;
 4
 5 import com.mybatis.po.User;
 6
 7
 8
17 public interface UserMapper {
18
19     //根据用户id查询用户信息
20     public User findUserById(int id) throws Exception;
21
22     //根据用户名字查询信息
23     public User findUserByName(String username) throws Exception;
24
25     //查询用户列表
26     public List<User> findUserList(String username)throws Exception;
27
28     public void deleteUser(String username)throws Exception;
29
30     public int insertUser(User user)throws Exception;
31
32     public void updateUser(User user)throws Exception;
33
34 }

Test.java:

  1 package com.mybatis.mapper;
  2
  3 import java.io.InputStream;
  4 import java.util.List;
  5
  6 import org.apache.ibatis.io.Resources;
  7 import org.apache.ibatis.session.SqlSession;
  8 import org.apache.ibatis.session.SqlSessionFactory;
  9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 10 import org.junit.Before;
 11 import org.junit.Test;
 12
 13 import com.mybatis.po.User;
 14
 15 public class UserMapperTest {
 16
 17     // 会话工厂
 18     private SqlSessionFactory sqlSessionFactory;
 19
 20     @Before
 21     public void setUp() throws Exception {
 22         // 加载配置文件
 23         String resource = "SqlMapConfig.xml";
 24         InputStream inputStream = Resources.getResourceAsStream(resource);
 25
 26         // 根据mytais的配置创建SqlSessionFactory
 27
 28         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 29
 30         //sqlSessionFactory.getConfiguration().addMapper(UserMapper.class);
 31     }
 32
 33     @Test
 34     public void testFindUserByName() throws Exception {
 35         SqlSession sqlSession = sqlSessionFactory.openSession();
 36         //通过sqlSession创建代理对象(接口的实现类对象)
 37         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 38         User user= userMapper.findUserByName("张小三");
 39         System.out.println(user);
 40     }
 41
 42     @Test
 43     public void testFindUserList() throws Exception {
 44         SqlSession sqlSession = sqlSessionFactory.openSession();
 45         //通过sqlSession创建代理对象(接口的实现类对象)
 46         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 47         List<User> list = userMapper.findUserList("d");
 48         for(User x:list){
 49             System.out.println(x.getUsername());
 50         }
 51
 52
 53     }
 54
 55     /*
 56      由于我的这个user表被其他表的外键连接,所以这里暂不进行删除操作。
 57     @Test
 58     public void deleteUser() throws Exception {
 59         SqlSession sqlSession = sqlSessionFactory.openSession();
 60         //通过sqlSession创建代理对象(接口的实现类对象)
 61         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 62         userMapper.deleteUser("duyu");
 63         sqlSession.commit();
 64         sqlSession.close();
 65
 66
 67     }
 68     */
 69
 70
 71     @Test
 72     public void insertUser() throws Exception {
 73         SqlSession sqlSession = sqlSessionFactory.openSession();
 74         //通过sqlSession创建代理对象(接口的实现类对象)
 75         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 76         User user=new User("2017-3-12");
 77         user.setAddress("四川");
 78         int z=userMapper.insertUser(user);
 79         sqlSession.commit();
 80         sqlSession.close();
 81         System.out.println(z);
 82
 83     }
 84
 85     @Test
 86     public void updateUser() throws Exception {
 87         SqlSession sqlSession = sqlSessionFactory.openSession();
 88         //通过sqlSession创建代理对象(接口的实现类对象)
 89         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 90         User user=userMapper.findUserByName("duu");
 91         user.setAddress("北京");
 92         user.setUsername("Eminem");
 93         userMapper.updateUser(user);
 94         sqlSession.commit();
 95         sqlSession.close();
 96
 97
 98     }
 99
100 }

执行完操作后表如下:

mybatis对jdbc编程问题的解决:

1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。

2、 Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

3、 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。

4、 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

时间: 2024-10-26 17:45:04

mybatis的学习笔记的相关文章

Mybatis超实用学习笔记

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .2013年11月迁移到Github 一.理解什么是MyBatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索. MyBatis 可以使用简单的XML 或注解用于配置和原始映射,将接口

关于mybatis的学习笔记

配置文件 贴出mybatis的配置文件,这里mybatis还未与spring做整合: 1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"&g

MyBatis框架学习笔记(1)

1. Mybatis向dao层传入能够连接交互数据库并进行操作的对象 sqlSession 作用: - 向sql语句传入参数 - 执行sql语句 - 获取执行sql语句后的结果 - 事务的控制 2.  如何得到SqlSession: - 通过配置文件获取数据库连接相关信息 - 通过配置的相关信息构建SqlSessionFactory - 通过SqlsessionFactory打开 数据库会话(SqlSession) 3.  实体映射文件配置Mapper 数据库中的数据类型跟jdbc中的Type中

3、MyBatis.Net学习笔记之增删改

增删改之前先说一下笔记1里提到的一个无法创建ISqlMapper对象的问题. <resultMaps> <resultMap id="FullResultMap" class="TUSER"> <result property="UID" column="U_ID" dbType="Int"/> <result property="UName"

MyBatis基础学习笔记--摘录

1.MyBatis是什么? MyBatis源自于IBatis,是一个持久层框架,封装了jdbc操作数据库的过程,使得开发者只用关心sql语句,无需关心驱动加载.连接,创建statement,手动设置参数,结果集检索等jdbc底层操作. Mybatis通过xml或注解的方式将要执行的各种statement(statement.preparedStatemnt.CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由myb

mybatis更新学习笔记

import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.session.SqlSession; import cn.itcast.javaee.mybatis.util.MybatisUtil; /** * 持久层 * @author AdminTC */ public class StudentD

Spring+SpringMVC+MyBatis集成学习笔记【一】

一,首先要清楚,SpringMVC其实就是Spring的一个组件       例如我们知道Spring中有类似于,AOP TX等等类似的组件,所以SpringMVC其实就是Spring的一个组件,是Spring框架的一部分,千万不要把SpringMVC当成是另一种框架!       所以在配置上,还是按照配置Spring的套路来,该配置监听,配置监听,该配置配置文件,配置配置文件,一切照旧 二,Spring在Web.xml中的配置       在Web.xml中配置Spring大致可以分为两点

mybatis参数学习笔记

1.  参数中直接加入%%,注意不需要加两个单引号,加了就会出错,因为系统会自动为字符串类型加上两个单引号 param.setUsername("%CD%");      param.setPassword("%11%"); <select id="selectPersons" resultType="person" parameterType="person"> select id,sex,a

2、MyBatis.NET学习笔记之CodeSmith使用

说明:本系列随笔会与CSDN同步发布,当然这里先发,因为这里可以用WLW.但刚才由于误操作,没有重新发上来.只好先在CSDN先发了.重往这里发时图片无法处理,索性直接粘过来吧! 使用框架后一些相关的配置如果手写起来会累死,且没有必要,技术就是用来提升工作效率的(至少我是这么认为的).实体类及配置基本上大同小 异,CTRL+C.CTRL+V 当然也可以实现,但那也不像做技术出身的风格.以前用动软的生成PETSHOP的代码.据说这个CodeSmtih挺强.就拿来用的.感觉定制性挺强,但 使用习惯什么