JavaWeb 后端 <十一> 之 DBUtils 框架 (基本使用 结果集 事务处理 对表读取)
一、数据库操作框架
1、ORM:Object Relation Mapping
Hibernate:非常流行
JPA:Java Persistent API.ORM标准
MyBatis:2010年开始。之前叫做iBatis(重视)
2、JDBC封装框架
DBUtils
Spring JDBC Template
二、Apache的DBUtils框架(会用:练习作业)
1、基本的使用
DBCPutil
public class DBCPUtil {
private static DataSource dataSource;
static{
try {
InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties props = new Properties();
props.load(in);
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
} public static DataSource getDataSource(){
return dataSource;
} public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
dbcpconfig.properties 配置文件 对dbcp进行配置
QueryRunner 的使用 CRUD
/*
create database day18;
use day18;
create table student(
id int primary key,
name varchar(100),
birthday date
);
*/
public class DBUtilCRUD {
private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
@Test
public void testAdd() throws SQLException{
qr.update("insert into student values(?,?,?)", 1,"杨洋",new Date());
}
@Test
public void testUpdate() throws SQLException{
qr.update("update student set birthday=? where id=?", "1993-08-01",1);
}
@Test
public void testDel() throws SQLException{
qr.update("delete from student where id=?", 1);
}
//批处理插入10条
@Test
public void testBatch() throws SQLException{
Object params[][] = new Object[10][];//高维:记录的条数。低维:每条记录需要的参数
for(int i=0;i<params.length;i++){
params[i] = new Object[]{i+1,"杨洋"+(i+1),new Date()};
}
qr.batch("insert into student values(?,?,?)", params);
}
//大文本:了解
/*
create table t1(
id int primary key,
content longtext
);
*/
@Test//大文本类型===Clob
public void testClob()throws Exception{
File file = new File("src/pqy&sx.txt");//文件很大,内存浪费
Reader reader = new FileReader(file);
char ch[] = new char[(int)file.length()];
reader.read(ch);
reader.close();
Clob clob = new SerialClob(ch);
qr.update("insert into t1 values(?,?)", 1,clob);//类型不批配。流不是数据库的类型
}
//大二进制:了解
/*
create table t2(
id int primary key,
content longblob
);
*/
@Test//大二进制类型===Blob
public void testBlob()throws Exception{
InputStream in = new FileInputStream("src/22.jpg");
byte b[] = new byte[in.available()];
in.read(b);
in.close();
Blob blob = new SerialBlob(b);
qr.update("insert into t2 values(?,?)", 1,blob);//类型不批配。流不是数据库的类型
}
}
2、各种结果处理器的使用 ResultSetHandler
public class ResultSetHandlerDemo {
private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
//ArrayHandler:适合结果只有一条的情况。把第一条记录的每列的值封装到一个Object[]数组中
@Test
public void test1() throws Exception{
Object[] objs = qr.query("select * from student", new ArrayHandler());
for(Object obj:objs)
System.out.println(obj);
}
//ArrayListHandler:适合结果有多条的情况。把每列的值封装到Object[]数组中,把Object[]放到List中
@Test
public void test2() throws Exception{
List<Object[]> list = qr.query("select * from student", new ArrayListHandler());
for(Object[] objs:list){
System.out.println("----------------");
for(Object obj:objs){
System.out.println(obj);
}
}
}
//ColumnListHandler:适合取某列的值。把取到值封装到List中
@Test
public void test3() throws Exception{
List<Object> list = qr.query("select * from student", new ColumnListHandler("name"));
for(Object obj:list){
System.out.println(obj);
}
}
//KeyedHandler:查询多条记录。每条记录封装到一个Map中,key:字段名,value:字段值。再把Map作为value放到另外一个Map中,该Map的key为指定的列值作为key。
@Test
public void test4() throws Exception{
Map<Object,Map<String,Object>> bmap = qr.query("select * from student", new KeyedHandler("id"));
for(Map.Entry<Object,Map<String,Object>> bme:bmap.entrySet()){
System.out.println("--------------------");
for(Map.Entry<String, Object> lme:bme.getValue().entrySet()){
System.out.println(lme.getKey()+"="+lme.getValue());
}
}
}
//MapHandler:适合一条结果。封装到一个Map中,key:字段名,value:字段值
@Test
public void test5() throws Exception{
Map<String,Object> map = qr.query("select * from student", new MapHandler());
for(Map.Entry<String, Object> lme:map.entrySet()){
System.out.println(lme.getKey()+"="+lme.getValue());
}
}
//MapListHandler:适合多条结果。把每条封装到一个Map中,key:字段名,value:字段值,在把Map封装到List中
@Test
public void test6() throws Exception{
List<Map<String,Object>> list = qr.query("select * from student", new MapListHandler());
for(Map<String,Object> map:list){
System.out.println("--------------------");
for(Map.Entry<String, Object> lme:map.entrySet()){
System.out.println(lme.getKey()+"="+lme.getValue());
}
}
}
//ScalarHandler:适合取结果只有一行和一列的情况。
@Test
public void test7() throws Exception{
Object obj = qr.query("select count(*) from student", new ScalarHandler(1));
// System.out.println(obj.getClass().getName());
Long l = (Long)obj;
System.out.println(l.intValue());
System.out.println(obj);
}
}
三、实际开发中事务如何管理(非常好)
对事务的控制
1、写4个版本的代码:AOP
1.0
public interface AccountDao {
/**
* 转账
* @param sourceAccountName 转出账户
* @param targetAccontName 转入账户
* @param money 交易金额
*/
void transfer(String sourceAccountName,String targetAccontName,float money);
}
/*
create table account(
id int primary key auto_increment,
name varchar(40),
money float
)character set utf8 collate utf8_general_ci; insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);
*/
public class AccountDaoImpl implements AccountDao { private QueryRunner qr = new QueryRunner(); public void transfer(String sourceAccountName, String targetAccontName,
float money) {
Connection conn = null;
try {
conn = DBCPUtil.getConnection();
conn.setAutoCommit(false);//开启事务
qr.update(conn,"update account set money=money-? where name=?", money,sourceAccountName);
// int i=1/0;
qr.update(conn,"update account set money=money+? where name=?", money,targetAccontName);
} catch (Exception e) {
if(conn!=null){
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();
}finally{
if(conn!=null){
try {
conn.commit();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} } }
public interface BusinessService {
/**
* 转账
* @param sourceAccountName 转出账户
* @param targetAccontName 转入账户
* @param money 交易金额
*/
void transfer(String sourceAccountName,String targetAccontName,float money);
}
public class BusinessServiceImpl implements BusinessService {
private AccountDao dao = new AccountDaoImpl();
public void transfer(String sourceAccountName, String targetAccontName,
float money) {
dao.transfer(sourceAccountName, targetAccontName, money);
} }
public class Client { public static void main(String[] args) {
BusinessService s = new BusinessServiceImpl();
s.transfer("aaa", "bbb", 100);
} }
2.0
//DAO层:不能牵扯到任何业务有关的逻辑。
//DAO:只负责CRUD
public interface AccountDao {
/**
* 根据户名查询账户
* @param accountName
* @return
*/
Account findByName(String accountName);
/**
* 更新账户
* @param account
*/
void updateAcount(Account account);
}
public class AccountDaoImpl implements AccountDao {
private QueryRunner qr = new QueryRunner();
private Connection conn;
public AccountDaoImpl(Connection conn){
this.conn = conn;
}
public Account findByName(String accountName) {
try {
return qr.query(conn,"select * from account where name=?", new BeanHandler<Account>(Account.class),accountName);
} catch (SQLException e) {
throw new RuntimeException(e);
}
} public void updateAcount(Account account) {
try {
qr.update(conn,"update account set money=? where id=?", account.getMoney(),account.getId());
} catch (SQLException e) {
throw new RuntimeException(e);
}
} }
public class Account {
private int id;
private String name;
private float money;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getMoney() {
return money;
}
public void setMoney(float money) {
this.money = money;
} }
public interface BusinessService {
/**
* 转账
* @param sourceAccountName 转出账户
* @param targetAccontName 转入账户
* @param money 交易金额
*/
void transfer(String sourceAccountName,String targetAccontName,float money);
}
//业务层控制事务
public class BusinessServiceImpl implements BusinessService {
public void transfer(String sourceAccountName, String targetAccontName,
float money) {
Connection conn = null;
try {
conn = DBCPUtil.getConnection();
conn.setAutoCommit(false);
AccountDao dao = new AccountDaoImpl(conn);
Account sAccount = dao.findByName(sourceAccountName);
Account tAccount = dao.findByName(targetAccontName);
sAccount.setMoney(sAccount.getMoney() - money);
tAccount.setMoney(tAccount.getMoney() + money);
dao.updateAcount(sAccount);
// int i=1/0;
dao.updateAcount(tAccount);
} catch (Exception e) {
if (conn != null) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.commit();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
} }
public class Client { public static void main(String[] args) {
BusinessService s = new BusinessServiceImpl();
s.transfer("aaa", "bbb", 100);
} }
3.0
//封装了所有与事务有关的方法
public class TransactionManager {
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
public static Connection getConnection(){
Connection conn = tl.get();
if(conn==null){//从当前线程中获取链接
conn = DBCPUtil.getConnection();
tl.set(conn);
}
return conn;
}
public static void startTransaction(){
try {
Connection conn = getConnection();
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void rollback(){
try {
Connection conn = getConnection();
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void commit(){
try {
Connection conn = getConnection();
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void release(){
try {
Connection conn = getConnection();
conn.close();
tl.remove();//从当前线程中解绑。 与服务器实现有关:服务器采用线程池。
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//业务层控制事务
public class BusinessServiceImpl implements BusinessService {
private AccountDao dao = new AccountDaoImpl();
public void transfer(String sourceAccountName, String targetAccontName,
float money) {
try {
TransactionManager.startTransaction();
Account sAccount = dao.findByName(sourceAccountName);
Account tAccount = dao.findByName(targetAccontName);
sAccount.setMoney(sAccount.getMoney() - money);
tAccount.setMoney(tAccount.getMoney() + money);
dao.updateAcount(sAccount);
int i=1/0;
dao.updateAcount(tAccount);
} catch (Exception e) {
TransactionManager.rollback();
e.printStackTrace();
} finally {
TransactionManager.commit();
TransactionManager.release();
}
} }
public class AccountDaoImpl implements AccountDao {
private QueryRunner qr = new QueryRunner(); public Account findByName(String accountName) {
try {
return qr.query(TransactionManager.getConnection(),"select * from account where name=?", new BeanHandler<Account>(Account.class),accountName);
} catch (SQLException e) {
throw new RuntimeException(e);
}
} public void updateAcount(Account account) {
try {
qr.update(TransactionManager.getConnection(),"update account set money=? where id=?", account.getMoney(),account.getId());
} catch (SQLException e) {
throw new RuntimeException(e);
}
} }
4.0 AOP(面向切面编程)
aaarticlea/png;base64,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" alt="" />
//AOP
public class BeanFactory {
public static BusinessService getBusinessService(){
final BusinessService s = new BusinessServiceImpl(); BusinessService proxyS = (BusinessService)Proxy.newProxyInstance(s.getClass().getClassLoader(),
s.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
TransactionManager.startTransaction();
Object rtValue = method.invoke(s, args);
return rtValue;
} catch (Exception e) {
TransactionManager.rollback();
throw new RuntimeException(e);
} finally {
TransactionManager.commit();
TransactionManager.release();
}
}
}); return proxyS;
}
}
2、ThreadLocal(很重要)
//特点:一个线程存的东西,只有该线程才能取出来。线程局部变量。
//模拟
public class ThreadLocal{
//类似Map的结构
private Map<Runnable,Object> map = new HashMap<Runnable,Object>();
public void set(Object obj){
map.put(Thread.currentThread(),obj);
}
public void remove(){
map.remove(Thread.currentThread());
}
public Object get(){
map.get(Thread.currentThread());
}
}
四、利用DBUtils框架进行多表的读取
1、一对多 顾客对订单
mysql表创建:
use day18;
create table customers(
id int primary key,
name varchar(100),
city varchar(100)
);
create table orders(
id int primary key,
num varchar(100),
price float(10,2),
customer_id int,
constraint customer_id_fk foreign key(customer_id) references customers(id)
);
顾客类:
public class Customer {
private int id;
private String name;
private String city; private List<Order> orders = new ArrayList<Order>(); public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", city=" + city + "]";
} }
订单类:
public class Order {
private int id;
private String num;
private float price; private Customer customer; public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
@Override
public String toString() {
return "Order [id=" + id + ", num=" + num + ", price=" + price + "]";
} }
实现
public class CustomerDaoImpl {
private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
public void saveCustomer(Customer c){
try {
qr.update("insert into customers (id,name,city) values(?,?,?)",
c.getId(),c.getName(),c.getCity());
//保存订单的信息:级联保存
List<Order> os = c.getOrders();
if(os.size()>0){
for(Order o:os){
qr.update("insert into orders (id,num,price,customer_id) values(?,?,?,?)",
o.getId(),o.getNum(),o.getPrice(),c.getId());
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
//客户如果找到的话,它的订单要不要查询出来呢? 看需求
// 查询客户时把对应的订单也查询出来(立即加载)
public Customer findCustomerById(int customerId){
try {
Customer c = qr.query("select * from customers where id=?", new BeanHandler<Customer>(Customer.class),customerId);
if(c!=null){
//查订单
List<Order> os = qr.query("select * from orders where customer_id=?", new BeanListHandler<Order>(Order.class),customerId);
c.setOrders(os);
}
return c;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
测试:
public class CustomerDaoImplTest {
private CustomerDaoImpl dao = new CustomerDaoImpl();
@Test
public void testSaveCustomer() {
Customer c = new Customer();
c.setId(1);
c.setName("范青霞");
c.setCity("北京"); Order o1 = new Order();
o1.setId(1);
o1.setNum("001");
o1.setPrice(10000); Order o2 = new Order();
o2.setId(2);
o2.setNum("002");
o2.setPrice(100000); //建立关联关系
c.getOrders().add(o1);
c.getOrders().add(o2); dao.saveCustomer(c);
} @Test
public void testFindCustomerById() {
Customer c = dao.findCustomerById(1);
System.out.println("客户姓名:"+c.getName()+"买了以下商品:");
for(Order o:c.getOrders()){
System.out.println(o);
}
} }
2、多对多 老师对学生
mysql 创建表sql语句
create table teachers(
id int primary key,
name varchar(100),
salary float(8,2)
);
create table students(
id int primary key,
name varchar(100),
grade varchar(10)
);
create table teachers_students(
t_id int,
s_id int,
primary key(t_id,s_id),
constraint t_id_fk foreign key(t_id) references teachers(id),
constraint s_id_fk foreign key(s_id) references students(id)
);
老师类:
public class Teacher {
private int id;
private String name;
private float salary; private List<Student> students = new ArrayList<Student>(); public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public float getSalary() {
return salary;
} public void setSalary(float salary) {
this.salary = salary;
} public List<Student> getStudents() {
return students;
} public void setStudents(List<Student> students) {
this.students = students;
} @Override
public String toString() {
return "Teacher [id=" + id + ", name=" + name + ", salary=" + salary
+ "]";
} }
学生类:
public class Student {
private int id;
private String name;
private String grade; private List<Teacher> teachers = new ArrayList<Teacher>(); public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getGrade() {
return grade;
} public void setGrade(String grade) {
this.grade = grade;
} public List<Teacher> getTeachers() {
return teachers;
} public void setTeachers(List<Teacher> teachers) {
this.teachers = teachers;
} @Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", grade=" + grade
+ "]";
} }
实现:
public class TeacherDaoImpl {
private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
public void saveTeacher(Teacher t){
try{
//保存老师的基本信息
qr.update("insert into teachers values(?,?,?)", t.getId(),t.getName(),t.getSalary());
//查看老师有没有关联的学生信息
List<Student> students = t.getStudents();
//如果有:遍历
for(Student s:students){
//先查询学生信息是否已经存在
Student dbStudent = qr.query("select * from students where id=?", new BeanHandler<Student>(Student.class),s.getId());
//不存在:插入学生信息
if(dbStudent==null){
qr.update("insert into students values (?,?,?)", s.getId(),s.getName(),s.getGrade());
}
//在第三方表中建立关联
qr.update("insert into teachers_students values(?,?)", t.getId(),s.getId());
}
}catch(Exception e){
throw new RuntimeException(e);
}
}
public Teacher findTeacherById(int teacherId){
try{
Teacher t = qr.query("select * from teachers where id=?", new BeanHandler<Teacher>(Teacher.class),teacherId);
if(t!=null){
// String sql = "select * from students where id in (select s_id from teachers_students where t_id=?)";
// String sql = "select * from students s,teachers_students ts where s.id=ts.s_id and ts.t_id=?";
String sql = "select * from students s inner join teachers_students ts on s.id=ts.s_id where ts.t_id=?";
List<Student> students = qr.query(sql, new BeanListHandler<Student>(Student.class),teacherId);
t.setStudents(students);
}
return t;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
测试:
public class TeacherDaoImplTest {
private TeacherDaoImpl dao = new TeacherDaoImpl();
@Test
public void testSaveTeacher() { Teacher t1 = new Teacher();
t1.setId(1);
t1.setName("任瞳");
t1.setSalary(10000); Teacher t2 = new Teacher();
t2.setId(2);
t2.setName("王昭珽");
t2.setSalary(11000); Student s1 = new Student();
s1.setId(1);
s1.setName("张新朋");
s1.setGrade("A"); Student s2 = new Student();
s2.setId(2);
s2.setName("张湾");
s2.setGrade("A"); //建立关系
t1.getStudents().add(s1);
t1.getStudents().add(s2); t2.getStudents().add(s1);
t2.getStudents().add(s2); dao.saveTeacher(t1);
dao.saveTeacher(t2); } @Test
public void testFindTeacherById() {
Teacher t = dao.findTeacherById(2);
System.out.println(t);
for(Student s:t.getStudents())
System.out.println(s);
} }
3、一对一 Person 和 身份证
musql 表创建 sql语句
create table persons(
id int primary key,
name varchar(100)
);
create table id_card(
id int primary key,
num varchar(100),
constraint person_id_fk foreign key(id) references persons(id)
);
Person类:
//粗粒度:表的定义应该粗。少
//细粒度:类的定义尽量的细。多
public class Person {
private int id;
private String name; private IdCard idcard;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public IdCard getIdcard() {
return idcard;
}
public void setIdcard(IdCard idcard) {
this.idcard = idcard;
} }
IdCard类:
public class IdCard {
private int id;
private String num; private Person person;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
} }
实现:
public class PersonDaoImpl {
private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource()); public void savePerson(Person p){
try{
qr.update("insert into persons values(?,?)", p.getId(),p.getName());
IdCard idcard = p.getIdcard();
if(idcard!=null){
qr.update("insert into id_card (id,num) values (?,?)", p.getId(),idcard.getNum());
}
}catch(Exception e){
throw new RuntimeException(e);
}
}
//查询人信息是,要不要查对应的idcard呢? 建议查出来。
public Person findPersonById(int personId){
try{
Person p = qr.query("select * from persons where id=?", new BeanHandler<Person>(Person.class),personId);
if(p!=null){
IdCard idcard = qr.query("select * from id_card where id=?", new BeanHandler<IdCard>(IdCard.class),personId);
p.setIdcard(idcard);
}
return p;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
测试:
public class PersonDaoImplTest {
private PersonDaoImpl dao = new PersonDaoImpl();
@Test
public void testSavePerson() {
Person p = new Person();
p.setId(1);
p.setName("韦文停"); IdCard idcard = new IdCard();
idcard.setNum("4101"); //建立关系
p.setIdcard(idcard); dao.savePerson(p);
} @Test
public void testFindPersonById() {
Person p = dao.findPersonById(1);
System.out.println(p.getName()+"身份证号:"+p.getIdcard().getNum());
} }
JavaWeb 后端 <十一> 之 DBUtils 框架 (基本使用 结果集 事务处理 对表读取)的更多相关文章
- javaweb学习总结(四十一)——Apache的DBUtils框架学习
一.commons-dbutils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化 ...
- Apache—DBUtils框架简介
转载自:http://blog.csdn.net/fengdongkun/article/details/8236216 Apache—DBUtils框架简介.DbUtils类.QueryRunner ...
- JDBC 学习笔记(四)—— 自定义JDBC框架+Apache—DBUtils框架+事务管理+操作多表
本文目录: 1.自定义JDBC框架 ——数据库元数据:DataBaseMetaData 2.自定义JDBC框架 ——数据库元数据:DataBaseMetaData ...
- JNDI和在tomcat中配置DBCP连接池 元数据的使用 DBUtils框架的使用 多表操作
1 JNDI和在tomcat中配置DBCP连接池 JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.namin ...
- DBUtils框架
一.O-R Mapping 简介 一]概念:可以理解为对象和数据库的映射. 二]常用O-R Mapping映射工具 1)Hibernate(全自动框架) 2)l ...
- Java Web(十) JDBC的增删改查,C3P0等连接池,dbutils框架的使用
前面做了一个非常垃圾的小demo,真的无法直面它,菜的抠脚啊,真的菜,好好努力把.菜鸡. --WH 一.JDBC是什么? Java Data Base Connectivity,java数据库连接,在 ...
- JDBC第四篇--【数据库连接池、DbUtils框架、分页】
1.数据库连接池 什么是数据库连接池 简单来说:数据库连接池就是提供连接的. 为什么我们要使用数据库连接池 数据库的连接的建立和关闭是非常消耗资源的 频繁地打开.关闭连接造成系统性能低下 编写连接池 ...
- JDBC【数据库连接池、DbUtils框架、分页】
1.数据库连接池 什么是数据库连接池 简单来说:数据库连接池就是提供连接的... 为什么我们要使用数据库连接池 数据库的连接的建立和关闭是非常消耗资源的 频繁地打开.关闭连接造成系统性能低下 编写连接 ...
- JavaWEB后端支付银联,支付宝,微信对接
注:本文来源于:< JavaWEB后端支付银联,支付宝,微信对接 > JavaWEB后端支付银联,支付宝,微信对接 标签(空格分隔): java 项目概述 最近项目需要后端打通支付,所 ...
随机推荐
- 移动端网页meta设置和响应式
苏宁易购WAP的meta分析 响应式 meta设置 媒体查询时读的width为viewport的宽度.viewport宽度为手机分辨率.比如note2 1280*720.需要重置为设备 640*360 ...
- Mac苹果系统 多系统启动:The rEFInd Boot Manager
苹果系统 多系统启动 下载安装REFIT: 首先安装一下:REFIT, 在这个页面下载: http://refit.sourceforge.net/#download 选择mac disk image ...
- OpenGL教程(2)——第一个窗口
OpenGL环境终于配置好了,现在我们可以开始学习OpenGL了. 首先,创建一个.cpp文件,然后打上几行#include指令: #include <iostream> using st ...
- 第二天0605下午——超链接<a>与图片<img>
今天下午学习了超链接<a>标签和图片<img>标签,以下面代码为例: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...
- day_ha配置文件
流程图: 代码 #!/sur/bin/env python # -*- coding: utf-8 -*- #{"backend": "www.oldboy.org&qu ...
- 写了一个Mac快速设置、打开和关闭Web代理的Shell命令
缘由(痛点) 每次在Mac上设置Web代理,都需要点开"系统偏好设置 -- 网络 -- 高级 -- 代理",然后分别设置Web代理(HTTP)和安全Web代理(HTTPS),设置完 ...
- SVN·最新使用教程总结
SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...
- xfire调用webservice接口的实现方式
package com.test; import java.net.URL; import org.codehaus.xfire.client.Client; import org.codehaus. ...
- 关于CSS样式优先级学习心得
1.未重复时候,只要有都有格式显示 2.重复时,看权值: 权值:标签 1 <类10< ID 100 PS:(*权值 > 继承(表格属性一般无法继承,有些浏览器也不支持表格继承父标签) ...
- Windows 7安装Oracle 10g的方法
Windows7下安装Oracle 10g提示"程序异常终止,发生未知错误"的解决方法 1.修改Oracle 10G\database\stage\prereq\db\refhos ...