其实Javaweb就想直接加在里面但,感觉不全面就算了吧.....
首先为什么使用Mybatis?
在没有mybatis前,java连接数据库和写sql语句是怎么样的?!
public class IStudentDaoImpl implements IStudentDao { private Connection conn=null; private PreparedStatement pst=null; private ResultSet rs=null; /** * 通过ID执行单个查询 * @param i * @return */ @Override public List<Student> selectOne(long i) { List<Student> list = new ArrayList<>(); // 查询表中所有数据 String sql="Select * FROM student where id=?"; try { conn = JDBCUtil.getConnection(); // 预编译语句 pst = conn.prepareStatement(sql); pst.setLong(1,i); // 执行DDL操作 rs = pst.executeQuery(); list = JDBCUtil.loopSet(rs); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { JDBCUtil.close(pst,conn,rs); } return list; }
}
数据库连接
public class JDBCUtil { private static DataSource ds; private static Properties p=new Properties(); static { try( //java6的新特性,try()中自动关闭 InputStream in = Thread.currentThread().getContextClassLoader() .getResourceAsStream("db.properties") ) { p.load(in); /*Class.forName(p.getProperty("driverClassName"));*/ ds= DruidDataSourceFactory.createDataSource(p); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { /* try { return DriverManager.getConnection(p.getProperty("url"), p.getProperty("username"),p.getProperty("password")); } catch (SQLException throwables) { throwables.printStackTrace(); } return null;*/ return ds.getConnection(); }
我们需要在这里面写sql,连接数据库,关闭数据库连接,提交事务,
那么假设我们有很多的表要写,那这个工作量有多大?且sql和java代码混杂在一起,以后维护起来方便吗?!
他可以解决我们什么问题?
帮我们把sql语句抽取出来,让代码便于维护,分离
连接数据库,再也不用写在java代码里一个配置文件搞定连接烦恼
mybatis-xxx.jar
mysql-connector-java-xxx-bin.jar
2.mybatis:mybatis-config.xml配置文档
<?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>
<environments default="dev_mysql"> <environment id="dev_mysql"> <!--Mybatis 内置事务管理器--> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="admin"/> </dataSource> </environment> </environments> <mappers> <!--mapper文件的路径--> <mapper resource="xxx.xml"/> </mappers> </configuration>
mybatis中访问的SQL语句都是在mapper配置文件中的
<?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"> <!-- 配置映射 namespace : 命名空间(通俗说法: 给当前映射文件的唯一标识:起一个唯一的名字) --> <mapper namespace="cn.ss.mybatis.pojo.UserMapper"> <!-- 新增操作 id: 当前功能的唯一标识,和接口方法同名 parameterType : 参数的类型 useGeneratedKeys:是否返回数据库生成的主键 true是/false否 keyProperty : 数据库主键对应java的pojo对象的属性 keyColumn : 数据表的主键列明 --> <insert id="insertUserInfo" parameterType="User" useGeneratedKeys="true" keyProperty="id" keyColumn="id" ></mapper>
其实获取连接对象还是需要用到连接池对象(为什么使用连接池对象的原因是为了减少对数据库资源浪费)
举个栗子:
在没有使用数据库连接池之前,我们每次调用数据库都要开一个数据库连接
而数据库的连接是有限的,当一个项目为了一些操作不断的开启数据库连接
这样最终会导致数据库崩溃.
连接池就是起到,当你使用完数据库连接后,调用关闭并不是放回数据库,而是放入数据库连接池等待下次调用
而mybatis的数据库连接对象时SqlSessionFactory 中获取SqlSession
try (SqlSession session = sqlSessionFactory.openSession()) { BlogMapper mapper = session.getMapper(BlogMapper.class ); Blog blog = mapper.selectBlog(101); }
注意:这里的(BlogMapper.class)指的是接口文件的字节码文件,要匹配到接口修改xml文件的空间命名!!!!!
另外注解和通过SqlSession实例来直接执行SQL的我就不写了(有想了解的百度吧)
ResultMap 的设计思想是,简单的语句不需要明确的结果映射,而复杂一点的语句只需要描述它们的关系就行了。
type 类的完全限定名, 或者一个类型别名 (内置的别名可以参考上面的表格).
association – 一个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联可以指定为一个 resultMap 元素,或者引用一个
<resultMap id="baseResultMap" type="Department"> <id column="id" property="id"/> <result column="name" property="name"/> <!--关联属性是集合类型 使用collection来配置 select 发送而外的sql column 而外sql参数之前sql那些列的值 property 查询结果封装部门对象什么属性 --> <collection select="cn.wolfcode.mapper.EmployeeMapper.queryById" column="id" property="employees"/> </resultMap>
<select id="insertUserInfo" resultType="User" > select * from user where password=#{param1} and username=#{param2} </select>
通过默认命名获取参数
而为了解决这种,不清晰的方式mybatis,提供了注解,让你在传递多个参数前提前给个命名
void selectOne(@Param("username")String username,@Param("password")String password)
优势:以前拼接的时候需要注意的空格、列表最后的逗号等,现在都可以不用手动处理了
if
可选的查找薪水功能
<select id="QueryByList" restult="employee"> SELECT id,name,salary FROM employee where <if test="minSalary !=null"> salary >=#{minSalary} </if> <if test="maxSalary !=null"> and salary <=#{minSalary} </if> </select>
<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
<select id="QueryByList" restult="employee"> SELECT id,name,salary FROM employee <where> <if test="minSalary !=null"> salary >=#{minSalary} </if> <if test="maxSalary !=null"> and salary <=#{minSalary} </if> </where> </select>
<!-- colletion 遍历数组或集合的key,或者属性名 open 遍历开始拼接的字符串 index 遍历索引 item 遍历元素 separator 每遍历一个元素拼接的字符串 close 遍历拼接结束的字符串 --> <delete id="batchDelete"> delete from employee where id IN <foreach collection="ids" open="(" item="id" separator="," close=")"> #{id} </foreach>
相同点:
都可以获取对象(Map对象或者JAVABean对象)信息
不同点:
使用#传递的参数会先转换为,无论传递是什么类型数据都会带一个单引号;$传递的参数,直接把值作为SQL语句的一部分
使用#支持把简单类型参数作为值;$不支持简单类型为值
使用#好比使用PrepareStatement,没有sql注入的问题,比较安全;而$则反之
但这样是不是$就没用了呢?!
其实不然例如ORDER BY 或GROUP BY字句获取参数值使用$,因为这样会直接拼接在SQL上
(#加引号导致找不到列),因此若需要获取参数才使用#
**(使用$可以携带常量)
原文:https://www.cnblogs.com/weiwo/p/13866844.html