根据bilibili https://www.bilibili.com/video/av17774929/ 视频学习总结
1. mybatis学习线路
2. 元素JDBC存在的问题
原生JDBC代码
package dal; import java.io.File; import java.io.FileInputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JdbcUtils { private static String driver = null; private static String url = null; private static String username = null; private static String password = null; static{ //try{ /*String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/checkprojectdb"; String username = "root"; String password = "980420";*/ Properties p = new Properties(); try{ //通过相对路径加载文件 String path = (Thread.currentThread().getContextClassLoader().getResource("").getFile()).substring(1); path=java.net.URLDecoder.decode(path, "utf-8"); path=path.replace('/', '\\'); path=path.replace("file:", ""); path=path.replace("classes\\", ""); path+="classes/dal/db.properties"; p.load(new FileInputStream(new File(path))); //用getProperties方法通过关键字获取信息 driver = p.getProperty("driver"); url = p.getProperty("url"); username = p.getProperty("username"); password = p.getProperty("password"); //} Class.forName(driver); }catch (Exception e) { // TODO: handle exception System.out.println(driver +" " + url + " " + username +" " + password ); throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException, ClassNotFoundException{ return DriverManager.getConnection(url, username, password); } public static void release(Connection conn, Statement st, ResultSet rs){ if(rs != null){ try{ rs.close(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } rs = null; } if(st != null){ try{ st.close(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } st = null; } if(conn != null){ try{ conn.close(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } conn = null; } } public static void main(String[] args) { System.out.println(driver + "; " + username + "; " + password + "; " + url); } }JdbcUtils
- 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
- Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
- 用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
- 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便
3. mybatis简介
3.1 什么是 MyBatis ?
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,
将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
3.2 mybatis框架原理
4. 开发DAO的方法(文件配置)
SqlSession使用范围——
1.SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。
在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
2. SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。
3.SqlSession
SqlSession是一个面向用户(程序员)的接口。
SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)
SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
SqlSession最佳应用场合在方法体内,定义成局部变量使用。
4.1 原始dao开发方法(程序员需要写dao接口和dao实现类)
程序员需要写dao接口和dao实现类。
需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession——UserDao.java UserDaoImpl.java
public interface UserDao { public User findById(int id) throws Exception; }
public class UserDaoImpl implements UserDao{ private SqlSessionFactory sqlSessionFactory; public UserDaoImpl(SqlSessionFactory sqlSessionFactory){ this.sqlSessionFactory = sqlSessionFactory; } @Override public User findById(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("test.findUserById", 1); sqlSession.close(); return user; } }
public class UserDaoImplTest { private SqlSessionFactory sqlSessionFactory; // 此方法是在执行testFindUserById之前执行 @Before public void setUp() throws Exception { // 创建sqlSessionFactory // mybatis配置文件 String resource = "SqlMapConfig.xml"; // 得到配置文件流 InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂,传入mybatis的配置文件信息 sqlSessionFactory = new SqlSessionFactoryBuilder() .build(inputStream); } @Test public void testFindById() throws Exception { // 创建UserDao的对象 UserDao userDao = new UserDaoImpl(sqlSessionFactory); // 调用UserDao的方法 User user = userDao.findById(1); System.out.println(user); } }
4.2 mapper代理方法(程序员只需要mapper接口(相当 于dao接口))
程序员需要编写mapper.xml映射文件
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
开发规范:
1、在mapper.xml中namespace等于mapper接口地址
2、mapper.java接口中的方法名和mapper.xml中statement的id一致
3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
步骤:
1、主要写 userMapper.java和 userMapper.xml,教程中是写成同名的并到mapper后缀,实际项目中同名即可(最好带Dao结尾); 2、在SqlMapConfig.xml中加载mapper.xml(开发中会用包扫描方式) 3、应用:获得sqlSessionFactory,获得sqlSession,获得UserMapper对象(此对象是自动生成的)
// 得到配置文件流 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); // 创建会话工厂,传入mybatis的配置文件信息 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findUserById(1);//调用
注意问题
1、在SqlMapConfig.xml中加载mapper.xml
<mappers> <mapper resource="sqlmap/User.xml"/> <mapper resource="mapper/UserMapper.xml"/> </mappers>
public class UserMapperTest { private SqlSessionFactory sqlSessionFactory; // 此方法是在执行testFindUserById之前执行 @Before public void setUp() throws Exception { // 创建sqlSessionFactory // mybatis配置文件 String resource = "SqlMapConfig.xml"; // 得到配置文件流 InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂,传入mybatis的配置文件信息 sqlSessionFactory = new SqlSessionFactoryBuilder() .build(inputStream); } @Test public void testFindUserById() throws Exception { SqlSession SqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = SqlSession.getMapper(UserMapper.class); User user = userMapper.findUserById(1); SqlSession.close(); System.out.println(user); } }
4.3 对比
两者区别:
1、不用写DAO的实现类
2、看不到sqlSession.selectOne("test.findUserById", id);这样的语句。 后续主要练习 一对一,一对多,多对多的查询,pojo和mapper的写法;resultMap,和加载延迟,缓存; 二级缓存参数配置,和分布式缓存ehcache,redis,mamcached;逆向工程的配置生成代码