mybatis 复习整理(仗剑走天涯) 持久化 持久化是将程序数据在持久状态和瞬时状态间转换的机制。通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据(比如持久化至数据库中,能够长久保存)
持久层 将操作数据库的代码统一抽离出来,形成了介于业务层和数据库中间的独立的层
ORM ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法
全自动的框架,强大、复杂、笨重、学习成本较高,不够灵活,实现了jpa规范。Java Persistence API(Java 持久层 API)
半自动的框架(懂数据库的人 才能操作) 必须要自己写sql,不是依照的jpa规范实现的
mybatis的优点和缺点 sql语句与代码分离,存放于xml配置文件中 优点
:便于维护管理,不用在java代码中找这些语句
缺点
: JDBC方式可以用打断点的方式调试,但是MyBatis调试比较复杂,一般要通过log4j日志输出日志信息帮助调试,然后在配置文件中修改
用逻辑标签控制动态SQL的拼接 优点
:用标签代替编写逻辑代码
缺点
:拼接复杂SQL语句时,没有代码灵活,拼写比较复杂。不要使用变通的手段来应对这种复杂的语句。
查询的结果集与java对象自动映射 优点
:保证名称相同,配置好映射关系即可自动映射或者,不配置映射关系,通过配置列名=字段名也可完成自动映射
缺点
:对开发人员所写的SQL依赖很强。
编写原生SQL 优点
:接近JDBC,比较灵活。
缺点
:对SQL语句依赖程度很高;并且属于半自动,数据库移植比较麻烦,比如MySQL数据库编程Oracle数据库,部分的SQL语句需要调整。
mybatis入门配置 先创建一个表
maven项目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 <?xml version="1.0" encoding="UTF-8"?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > com.dream.xiaobo</groupId > <artifactId > review_mybatis</artifactId > <version > 1.0-SNAPSHOT</version > <modules > <module > mybatis1</module > </modules > <packaging > pom</packaging > <properties > <maven.compiler.source > 11</maven.compiler.source > <maven.compiler.target > 11</maven.compiler.target > <junit.version > 4.13</junit.version > <mybatis.version > 3.5.7</mybatis.version > <mysql-connector-java.version > 8.0.11</mysql-connector-java.version > <lombok.version > 1.18.22</lombok.version > <logback.version > 1.2.11</logback.version > <druid.version > 1.2.8</druid.version > </properties > <dependencyManagement > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > ${junit.version}</version > <scope > test</scope > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > ${mybatis.version}</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > ${mysql-connector-java.version}</version > <scope > runtime</scope > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > ${lombok.version}</version > <scope > provided</scope > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-classic</artifactId > <version > ${logback.version}</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > ${druid.version}</version > </dependency > </dependencies > </dependencyManagement > </project >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 <?xml version="1.0" encoding="UTF-8"?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <parent > <artifactId > review_mybatis</artifactId > <groupId > com.dream.xiaobo</groupId > <version > 1.0-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > mybatis1</artifactId > <properties > <maven.compiler.source > 8</maven.compiler.source > <maven.compiler.target > 8</maven.compiler.target > </properties > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <scope > test</scope > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <scope > runtime</scope > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <scope > provided</scope > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-classic</artifactId > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-compiler-plugin</artifactId > <version > 3.1</version > <configuration > <source > ${maven.compiler.target}</source > <target > ${maven.compiler.target}</target > <encoding > UTF-8</encoding > </configuration > </plugin > </plugins > <resources > <resource > <directory > src/main/java</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > false</filtering > </resource > <resource > <directory > src/main/resources</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > false</filtering > </resource > </resources > </build > </project >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration > <properties > <property name ="driver" value ="com.mysql.cj.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/db_mybatis?useSSL=false& useUnicode=true& characterEncoding=utf8& serverTimezone=GMT%2B8" /> <property name ="username" value ="root" /> <property name ="password" value ="xiaobo" /> </properties > <settings > <setting name ="logImpl" value ="SLF4J" /> <setting name ="logPrefix" value ="mybatis.sql." /> </settings > <typeAliases > <package name ="com.dream.xiaobo.entity" /> </typeAliases > <environments default ="test" > <environment id ="development" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="${driver}" /> <property name ="url" value ="${url}" /> <property name ="username" value ="${username}" /> <property name ="password" value ="${password}" /> </dataSource > </environment > <environment id ="test" > <transactionManager type ="JDBC" /> <dataSource type ="com.dream.xiaobo.datasources.DruidDatasourcesFactory" > <property name ="druid.driverClassName" value ="${driver}" /> <property name ="druid.url" value ="${url}" /> <property name ="druid.username" value ="${username}" /> <property name ="druid.password" value ="${password}" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="mapper/UserMapper.xml" /> <mapper class ="com.dream.xiaobo.dao.AdminMapper" /> </mappers > </configuration >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Data @AllArgsConstructor @NoArgsConstructor public class User { private Integer id; private String username; private Integer age; private Integer version; private Integer isDelete; private String gmtCreate; private String gmtUpdate; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 public interface UserMapper { public List<User> selectAll () ; public User findUserById (Integer id) ; public User findUserByIdAndUsername (@Param("id") Integer id,@Param("username") String username) ; public User findUserByUser (User user) ; public User findUserByMap (Map<String,Object> map) ; public User findUserByUsername (String username) ; public Integer insert (User user) ; public Integer update (User user) ; public Integer delete (User user) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.dream.xiaobo.dao.UserMapper" > <insert id ="insert" > INSERT INTO `t_user`(username,age,version,is_delete,gmt_create,gmt_update) values(#{username},#{age},#{version},#{isDelete},#{gmtCreate},#{gmtUpdate}) </insert > <update id ="update" > UPDATE `t_user` SET username = #{username},age = #{age},gmt_update = #{gmtUpdate} WHERE id = #{id} </update > <delete id ="delete" > DELETE FROM t_user WHERE id = #{id} </delete > <select id ="selectAll" resultType ="user" > SELECT * FROM t_user </select > <select id ="findUserById" resultType ="com.dream.xiaobo.entity.User" > SELECT * FROM t_user WHERE id = #{id} </select > <select id ="findUserByIdAndUsername" resultType ="com.dream.xiaobo.entity.User" > SELECT * FROM t_user WHERE id = #{id} AND username = #{username} </select > <select id ="findUserByUser" resultType ="com.dream.xiaobo.entity.User" > SELECT * FROM t_user WHERE id = #{id} AND username = #{username} </select > <select id ="findUserByMap" resultType ="com.dream.xiaobo.entity.User" > SELECT * FROM t_user WHERE id = #{id} AND username = #{username} </select > <select id ="findUserByUsername" resultType ="com.dream.xiaobo.entity.User" > SELECT * FROM t_user WHERE username LIKE #{username} </select > </mapper >
resultType
:指定返回类型,查询是有结果的,结果啥类型
parameterType
:指定参数类型,查询是有参数的,参数啥类型
id
:指定对应的方法映射关系,就是告诉我你这sql对应的是哪个方法
#{id}
:sql中的变量,要保证大括号的变量必须在User对象里有
#{}
:占位符,其实就是咱们的【PreparedStatement】处理这个变量,mybatis会将它替换成 ?
#和$的区别 #{}
的作用主要是替换预编译语句(PrepareStatement)中的占位符 ?
${}
的作用是直接进行字符串替换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 @Slf4j public class MySqlSessionFactory { private SqlSessionFactory sqlSessionFactory; @Before public void before () { String resource = "mybatis-config.xml" ; InputStream inputStream = null ; try { inputStream = Resources.getResourceAsStream(resource); } catch (IOException e) { e.printStackTrace(); } sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testMybatis () throws IOException { try (SqlSession session = sqlSessionFactory.openSession()) { Object o = session.selectList("user.select" ); log.debug("user 的 信息内容[{}]" ,o); } } @Test public void testMapper () throws IOException { try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); List<User> list = mapper.selectAll(); log.debug("user 的 信息内容[{}]" ,list); } } @Test public void testFindUserById () { try (SqlSession sqlSession = sqlSessionFactory.openSession()){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); User userById = mapper.findUserById(1 ); log.debug("[{}]" ,userById); } } @Test public void testFindUserByIdAndUsername () { try (SqlSession sqlSession = sqlSessionFactory.openSession()){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); User tr = mapper.findUserByIdAndUsername(4 , "tr" ); log.debug("[{}]" ,tr); } } @Test public void testFindUser () { try (SqlSession sqlSession = sqlSessionFactory.openSession()){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setId(1 ); user.setUsername("xiaobo" ); User userByUser = mapper.findUserByUser(user); log.debug("[{}]" ,userByUser); } } @Test public void testFindMap () { try (SqlSession sqlSession = sqlSessionFactory.openSession()){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String,Object> map = new HashMap<String,Object>(2 ); map.put("id" ,1 ); map.put("username" ,"xiaobo" ); User userByMap = mapper.findUserByMap(map); log.debug("[{}]" ,userByMap); } } @Test public void testFindUsername () { try (SqlSession sqlSession = sqlSessionFactory.openSession()){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); User userByUsername = mapper.findUserByUsername("%x%" ); log.debug("[{}]" ,userByUsername); } } @Test public void testInsert () { try (SqlSession sqlSession = sqlSessionFactory.openSession()){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM--dd HH:mm:ss" ); String format = simpleDateFormat.format(date); User user = new User(); user.setUsername("爱要怎么说出口" ); user.setAge(22 ); user.setVersion(0 ); user.setIsDelete(0 ); user.setGmtCreate(format); user.setGmtUpdate(format); try { Integer insert = mapper.insert(user); if (insert >= 1 ){ log.debug("[{}]" ,insert); sqlSession.commit(); }else { log.error("插入失败" ); sqlSession.rollback(); } }catch (Exception e){ log.error("发生异常 插入失败" ,e); sqlSession.rollback(); } } } @Test public void testUpdate () { try (SqlSession sqlSession = sqlSessionFactory.openSession(true )){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM--dd HH:mm:ss" ); String format = simpleDateFormat.format(date); User user = new User(); user.setId(6 ); user.setUsername("爱要怎么说出口" ); user.setAge(24 ); user.setGmtUpdate(format); try { Integer update = mapper.update(user); if (update >= 1 ){ log.debug("[{}]" ,update); }else { log.error("插入失败" ); } }catch (Exception e){ log.error("发生异常 插入失败" ,e); } } } @Test public void testDelete () { try (SqlSession sqlSession = sqlSessionFactory.openSession(true )){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setId(6 ); try { Integer delete = mapper.delete(user); if (delete >= 1 ){ log.debug("[{}]" ,delete); }else { log.error("插入失败" ); } }catch (Exception e){ log.error("发生异常 插入失败" ,e); } } } }
sqlSession.getMapper(UserMapper.class);帮我们生成一个代理对象,该对象实现了这个接口的方法 这里使用了动态代理的方式
增、删、改操作需要提交事务!在默认情况下MySQL的事务是自动提交的,而框架却默认设置成了手动提交,我们开启了事务,又没有去提交事务,结束后自然会回滚啊
基本流程 1、创建一个SqlSessionFactory的 建造者 ,用于创建SqlSessionFactory
2、使用builder构建一个sqlSessionFactory,此处我们基于一个xml配置文件
3、通过sqlSessionFactory获取另一个session,此处使用【工厂设计模式】
4、一个sqlsession就是一个会话,可以使用sqlsession对数据库进行操作
SqlSessionFactory 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式
SqlSession 每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中
1 2 3 try (SqlSession session = sqlSessionFactory.openSession()) { }
mybatis注解配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Data @AllArgsConstructor @NoArgsConstructor public class Admin { private Integer id; private String username; private String password; private Integer version; private Integer isDelete; private String gmtCreate; private String gmtUpdate; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public interface AdminMapper { @Select(value = "SELECT * FROM `t_admin`") public List<Admin> findAll () ; @Select(value = "SELECT * FROM `t_admin` WHERE id = #{id}") public List<Admin> findUserById (@Param("id") Integer id) ; @Insert(value = "INSERT INTO t_admin(username,password,version,is_delete,gmt_create,gmt_update) values(#{username},#{password},#{version},#{isDelete},#{gmtCreate},#{gmtUpdate})") public Integer insert (Admin admin) ; @Update(value = "UPDATE `t_admin` SET username = #{username},password=#{password},version=#{version},is_delete=#{isDelete},gmt_create = #{gmtCreate},gmt_update=#{gmtUpdate} WHERE id = #{id}") public Integer update (Admin admin) ; @Delete(value = "DELETE FROM `t_admin` WHERE id = #{id}") public Integer delete (Admin admin) ; }
1 2 3 4 <mappers> <mapper resource="mapper/UserMapper.xml" /> <mapper class ="com.dream.xiaobo.dao.AdminMapper" /> </mappers>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 @Test public void testInterpretation () { try (SqlSession sqlSession = sqlSessionFactory.openSession(true )){ String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" ).format(new Date()); AdminMapper mapper = sqlSession.getMapper(AdminMapper.class); List<Admin> userById = mapper.findUserById(1 ); List<Admin> all = mapper.findAll(); Admin admin = new Admin(); admin.setId(2 ); admin.setUsername("哑巴" ); admin.setPassword("哑巴" ); admin.setVersion(0 ); admin.setIsDelete(0 ); admin.setGmtCreate(format); admin.setGmtUpdate(format); Integer insert = mapper.insert(admin); Integer update = mapper.update(admin); Integer delete = mapper.delete(admin); log.debug("[{}]" ,userById); log.debug("[{}]" ,all); log.debug("[{}]" ,insert); log.debug("[{}]" ,update); log.debug("[{}]" ,delete); } }
你知道的越多 你不知道的越多 嘿 我是小博 带你一起看我目之所及的世界……